summaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/trans-decl.c')
-rw-r--r--gcc/fortran/trans-decl.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index fafde89f37b..4c0b1da5af1 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -2146,7 +2146,7 @@ create_function_arglist (gfc_symbol * sym)
hence, the optional status cannot be transfered via a NULL pointer.
Thus, we will use a hidden argument in that case. */
else if (f->sym->attr.optional && f->sym->attr.value
- && !f->sym->attr.dimension && !f->sym->ts.type != BT_CLASS
+ && !f->sym->attr.dimension && f->sym->ts.type != BT_CLASS
&& f->sym->ts.type != BT_DERIVED)
{
tree tmp;
@@ -3649,7 +3649,37 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
NULL_TREE);
}
- if (sym->attr.dimension || sym->attr.codimension)
+ if (sym->ts.type == BT_CLASS
+ && (sym->attr.save || gfc_option.flag_max_stack_var_size == 0)
+ && CLASS_DATA (sym)->attr.allocatable)
+ {
+ tree vptr;
+
+ if (UNLIMITED_POLY (sym))
+ vptr = null_pointer_node;
+ else
+ {
+ gfc_symbol *vsym;
+ vsym = gfc_find_derived_vtab (sym->ts.u.derived);
+ vptr = gfc_get_symbol_decl (vsym);
+ vptr = gfc_build_addr_expr (NULL, vptr);
+ }
+
+ if (CLASS_DATA (sym)->attr.dimension
+ || (CLASS_DATA (sym)->attr.codimension
+ && gfc_option.coarray != GFC_FCOARRAY_LIB))
+ {
+ tmp = gfc_class_data_get (sym->backend_decl);
+ tmp = gfc_build_null_descriptor (TREE_TYPE (tmp));
+ }
+ else
+ tmp = null_pointer_node;
+
+ DECL_INITIAL (sym->backend_decl)
+ = gfc_class_set_static_fields (sym->backend_decl, vptr, tmp);
+ TREE_CONSTANT (DECL_INITIAL (sym->backend_decl)) = 1;
+ }
+ else if (sym->attr.dimension || sym->attr.codimension)
{
/* Assumed-size Cray pointees need to be treated as AS_EXPLICIT. */
array_type tmp = sym->as->type;