https://gcc.gnu.org/g:bbe87c94186914d439e46565c704e7e5b6d6bf77

commit bbe87c94186914d439e46565c704e7e5b6d6bf77
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Thu Jul 24 21:23:52 2025 +0200

    fortran: Consistently use the same assignment reallocation condition 
[PR121185]
    
    This is a follow-up to:
    r16-2248-gac8e536526393580bc9a4339bab2f8603eff8a47
    fortran: Delay evaluation of array bounds after reallocation
    
    That revision delayed the evaluation of array bounds, with changes in
    two places: in the scalarizer where we save expressions without
    evaluating their values to variables, and in the reallocation code where
    we evaluate to variables the expressions previously saved.  The effect
    should not have been visible in scalarized code, as the saving to a
    variable was only delayed after reallocation.
    
    Unfortunately, it's actually not the case, and there are cases where
    expressions that were saved to variables before the change, are no
    longer after it.  The reason for that is differing conditions guarding
    the omission of the evaluation to variables in the scalarizer on one
    hand, and the emission of reallocation code with the saving to variables
    on the other hand.  There is an additional check that avoids the
    emission of reallocation code if we can prove at compile time that both
    sides of the assignment are conformable.
    
    This change moves up the reallocation code condition definition, so that
    it can be used as well to flag the left hand side array as
    reallocatable, and omit the evaluation of expressions in the exact same
    conditions where the reallocation code would catch those unevaluated
    expressions.
    
    An explicit call to gfc_fix_class_refs is added before the evaluation of
    the reallocation code condition.  It was made implicitly before, by the
    call to gfc_walk_expr.
    
    This is not a correctness issue, but PR #121185, that made the problem
    apparent, exhibited wrong code examples where the lack of an
    intermediary variable was making visible a class container at the
    beginning of an array reference, causing the non-polymorphic array
    reference to be evaluated in a polymorphic way.
    
            PR fortran/121185
    
    gcc/fortran/ChangeLog:
    
            * trans-expr.cc (gfc_trans_assignment_1): Use the same condition
            to set the is_alloc_lhs flag and to decide to generate
            reallocation code.  Add explicit call to gfc_fix_class_refs
            before evaluating the condition.

Diff:
---
 gcc/fortran/trans-expr.cc | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index f2b88c64d5d1..a2c7902255df 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -12892,9 +12892,16 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * 
expr2, bool init_flag,
   gfc_init_se (&lse, NULL);
   gfc_init_se (&rse, NULL);
 
+  gfc_fix_class_refs (expr1);
+
+  realloc_flag = flag_realloc_lhs
+                && gfc_is_reallocatable_lhs (expr1)
+                && expr2->rank
+                && !is_runtime_conformable (expr1, expr2);
+
   /* Walk the lhs.  */
   lss = gfc_walk_expr (expr1);
-  if (gfc_is_reallocatable_lhs (expr1))
+  if (realloc_flag)
     {
       lss->no_bounds_check = 1;
       lss->is_alloc_lhs = 1;
@@ -12945,11 +12952,6 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * 
expr2, bool init_flag,
 
   assoc_assign = is_assoc_assign (expr1, expr2);
 
-  realloc_flag = flag_realloc_lhs
-                && gfc_is_reallocatable_lhs (expr1)
-                && expr2->rank
-                && !is_runtime_conformable (expr1, expr2);
-
   /* Only analyze the expressions for coarray properties, when in coarray-lib
      mode.  Avoid false-positive uninitialized diagnostics with initializing
      the codimension flag unconditionally.  */

Reply via email to