Hello,

Le 25/08/2026 à 14:34, Paul Richard Thomas a écrit :
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index d167036b808..1c859dd9c30 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -2521,12 +2521,16 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, 
bool sub_flag,
/* Otherwise try resolving a copy of a component call. If it succeeds,
         use that for the selector expression.  */
-      else if (tgt_expr && tgt_expr->expr_type == EXPR_COMPCALL)
+      else if (tgt_expr && (tgt_expr->expr_type == EXPR_COMPCALL
+                           || tgt_expr->expr_type == EXPR_ARRAY))
Note this makes the comment just above out of date.
          {
             gfc_expr *cpy = gfc_copy_expr (tgt_expr);
             if (gfc_resolve_expr (cpy))
                {
                  gfc_replace_expr (tgt_expr, cpy);
+                 if (tgt_expr->ts.type == BT_DERIVED)
+                   tgt_expr->ts.u.derived
+                               = gfc_use_derived (tgt_expr->ts.u.derived);
Looks good for now. As you say yourself, all these type guessing heuristics should be removed at some point in favor of a late resolution.
                  sym->ts = tgt_expr->ts;
                }
              else
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 2f11b61a4b8..270c6a34411 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1636,8 +1636,15 @@ gfc_trans_array_ctor_element (stmtblock_t * pblock, tree 
desc,
     }
   else
     {
-      /* TODO: Should the frontend already have done this conversion?  */
-      se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
+
+     /* TODO: Should the frontend already have done this conversion?  */
+      tree t1 = TREE_TYPE (se->expr), t2 = TREE_TYPE (tmp);
+      if (expr->expr_type == EXPR_FUNCTION && expr->ts.type == BT_DERIVED
+         && (TYPE_MAIN_VARIANT (t1) != TYPE_MAIN_VARIANT (t2)))
+       se->expr = build1_loc (input_location, VIEW_CONVERT_EXPR,
+                              t2, se->expr);
There has to be a better way than this. Different TYPE_MAIN_VARIANT means that some of the type-based middle-end optimizations could be misbehaving.

This looks like the usual module duplicate decl problem.
A plausible path could be redirecting type query on the associate name to the function result, use gfc_get_module_backend_decl to have the original result decl from the module and finally copy its type with gfc_copy_decls_if_equal or similar (I fear the types won't compare equal).

+      else
+       se->expr = fold_convert (t2, se->expr);
       gfc_add_modify (&se->pre, tmp, se->expr);
     }
diff --git a/gcc/testsuite/gfortran.dg/associate_85.f90 b/gcc/testsuite/gfortran.dg/associate_85.f90
new file mode 100644
index 00000000000..bf9fec28259
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/associate_85.f90
@@ -0,0 +1,36 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+! Test the fix for PR125012, wich failed as shown below.
+! COntributed by Ivan Pribec  <[email protected]>
+!
+module mwe
+implicit none
+contains
+  function point() result(p)
+     type :: point_
+        real :: x = 42.
+     end type point_
+     type(point_) :: p
+   end function
+end module
+
+program assoc
+  use mwe, only: point
+  implicit none
+  real        :: pi(1)
+  associate (points =>  point() ) ! accepted
+    pi(:) = points%x
+  end associate
+  print *, pi
+  associate (points => (point())) ! accepted
+    pi(:) = points%x
+  end associate
+  print *, pi
+  associate (points => [point()])
+    pi(:) = points%x ! Error: Symbol ‘points’ at (1) has no IMPLICIT type
+  end associate
+  print *, pi
+end program

+! The view convert expression is required to make the association when the
+! derived type is hidden => 3 such expressions.
+! { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR<struct point_>" 3 
"original" } }

There should only be one type point_, and there is no VIEW_CONVERT_EXPR needed in that case. Remove this check?

Reply via email to