diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-03-11 16:12:22 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-03-11 16:12:22 -0800 |
commit | bc636c218f2b28da06cd1404d5b35d1f8cc43fd1 (patch) | |
tree | 764937d8460563db6132d7c75e19b95ef3ea6ea8 /gcc/fortran/trans-expr.c | |
parent | 89d7be42db00cd0953e7d4584877cf50a56ed046 (diff) | |
parent | 7ad5a72c8bc6aa71a0d195ddfa207db01265fe0b (diff) | |
download | gcc-bc636c218f2b28da06cd1404d5b35d1f8cc43fd1.zip gcc-bc636c218f2b28da06cd1404d5b35d1f8cc43fd1.tar.gz gcc-bc636c218f2b28da06cd1404d5b35d1f8cc43fd1.tar.bz2 |
Merge from trunk revision 7ad5a72c8bc6aa71a0d195ddfa207db01265fe0b.
Diffstat (limited to 'gcc/fortran/trans-expr.c')
-rw-r--r-- | gcc/fortran/trans-expr.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 103cb31..85c16d7 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -613,11 +613,15 @@ class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc, class object of the 'declared' type. If vptr is not NULL, this is used for the temporary class object. optional_alloc_ptr is false when the dummy is neither allocatable - nor a pointer; that's only relevant for the optional handling. */ + nor a pointer; that's only relevant for the optional handling. + The optional argument 'derived_array' is used to preserve the parmse + expression for deallocation of allocatable components. Assumed rank + formal arguments made this necessary. */ void gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts, tree vptr, bool optional, - bool optional_alloc_ptr) + bool optional_alloc_ptr, + tree *derived_array) { gfc_symbol *vtab; tree cond_optional = NULL_TREE; @@ -747,6 +751,13 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, { gcc_assert (class_ts.u.derived->components->as->type == AS_ASSUMED_RANK); + if (derived_array + && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse->expr))) + { + *derived_array = gfc_create_var (TREE_TYPE (parmse->expr), + "array"); + gfc_add_modify (&block, *derived_array , parmse->expr); + } class_array_data_assign (&block, ctree, parmse->expr, false); } else @@ -765,6 +776,9 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, gfc_init_block (&block); gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node); + if (derived_array && *derived_array != NULL_TREE) + gfc_conv_descriptor_data_set (&block, *derived_array, + null_pointer_node); tmp = build3_v (COND_EXPR, cond_optional, tmp, gfc_finish_block (&block)); @@ -5665,6 +5679,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, { bool finalized = false; bool non_unity_length_string = false; + tree derived_array = NULL_TREE; e = arg->expr; fsym = formal ? formal->sym : NULL; @@ -5770,7 +5785,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, && e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.optional, CLASS_DATA (fsym)->attr.class_pointer - || CLASS_DATA (fsym)->attr.allocatable); + || CLASS_DATA (fsym)->attr.allocatable, + &derived_array); } else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS && gfc_expr_attr (e).flavor != FL_PROCEDURE) @@ -6077,6 +6093,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, && !fsym->attr.allocatable && !fsym->attr.pointer && !e->symtree->n.sym->attr.dimension && !e->symtree->n.sym->attr.pointer + && !e->symtree->n.sym->attr.allocatable /* See PR 41453. */ && !e->symtree->n.sym->attr.dummy /* FIXME - PR 87395 and PR 41453 */ @@ -6594,6 +6611,12 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, && parm_rank == 0 && parmse.loop; + /* Scalars passed to an assumed rank argument are converted to + a descriptor. Obtain the data field before deallocating any + allocatable components. */ + if (parm_rank == 0 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp))) + tmp = gfc_conv_descriptor_data_get (tmp); + if (scalar_res_outside_loop) { /* Go through the ss chain to find the argument and use @@ -6609,9 +6632,15 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, } } - if ((e->ts.type == BT_CLASS - && GFC_CLASS_TYPE_P (TREE_TYPE (tmp))) - || e->ts.type == BT_DERIVED) + STRIP_NOPS (tmp); + + if (derived_array != NULL_TREE) + tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, + derived_array, + parm_rank); + else if ((e->ts.type == BT_CLASS + && GFC_CLASS_TYPE_P (TREE_TYPE (tmp))) + || e->ts.type == BT_DERIVED) tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank); else if (e->ts.type == BT_CLASS) |