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?