diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 16e8f037cfc..a68c8d33acc 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -6804,6 +6804,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, /* Pass a class array. */ parmse.use_offset = 1; gfc_conv_expr_descriptor (&parmse, e); + bool defer_repackage = false; /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is allocated on entry, it must be deallocated. */ @@ -6844,7 +6845,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, else tmp = gfc_finish_block (&block); - gfc_add_expr_to_block (&se->pre, tmp); + gfc_add_expr_to_block (&dealloc_blk, tmp); + defer_repackage = true; } /* The conversion does not repackage the reference to a class @@ -6858,6 +6860,10 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, && e->symtree->n.sym->attr.optional, CLASS_DATA (fsym)->attr.class_pointer || CLASS_DATA (fsym)->attr.allocatable); + + /* Defer repackaging after deallocation. */ + if (defer_repackage) + gfc_add_block_to_block (&dealloc_blk, &parmse.pre); } else { @@ -7131,17 +7137,12 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, /* If any actual argument of the procedure is allocatable and passed to an allocatable dummy with INTENT(OUT), we conservatively - evaluate all actual argument expressions before deallocations are + evaluate actual argument expressions before deallocations are performed and the procedure is executed. This ensures we conform - to F2023:15.5.3, 15.5.4. Create temporaries except for constants, - variables, and functions returning pointers that can appear in a - variable definition context. */ + to F2023:15.5.3, 15.5.4. May create temporaries when needed. */ if (e && fsym && force_eval_args - && e->expr_type != EXPR_VARIABLE - && !gfc_is_constant_expr (e) - && (e->expr_type != EXPR_FUNCTION - || !(gfc_expr_attr (e).pointer - || gfc_expr_attr (e).proc_pointer))) + && fsym->attr.intent != INTENT_OUT + && !gfc_is_constant_expr (e)) parmse.expr = gfc_evaluate_now (parmse.expr, &parmse.pre); if (fsym && need_interface_mapping && e)