Hello all, The attached patch fixes PR125012. All is explained in the patch :-)
Regards Paul
From 71eeb36729cffff158ec260814543f52ec55d36a Mon Sep 17 00:00:00 2001 From: Paul Thomas <[email protected]> Date: Tue, 25 Aug 2026 13:14:30 +0100 Subject: [PATCH] Fortran: Fix association with array expression of hidden type [PR125012] This is a somewhat unusual bug in that the derived type for the associate name is "hidden" withing the function selector. Since the TYPE_MAIN_VARIANT of the selector is not the same as that of the associate name, a VIEW_CONVERT_EXPR must be used on the rhs of any assignment. This is tested with the tree dump for each ASSOCIATE statement. Apart from this, the patch is straightforward. Passes regression testing on FC44/x86_64. OK for mainline and, a bit later, backporting to 16-branch? Note: Comment 4 in the PR adds two variants of the testcase provided here, which I so not see how to fix without implementing two pass parsing. 2026-08-25 Paul Thomas <[email protected]> gcc/fortran PR fortran/125012 * primary.cc (gfc_match_varspec): Array associate selectors can be resolved in the same fashion as component calls. If the expr is a derived type, call gfc_use derived. * trans-array.cc (gfc_trans_array_ctor_element): If the type variants are not the same, use a view convert expression rather than a fold_convert. gcc/testsuite PR fortran/125012 * gfortran.dg/associate_85.f90: New test. --- gcc/fortran/primary.cc | 6 +++- gcc/fortran/trans-array.cc | 11 +++++-- gcc/testsuite/gfortran.dg/associate_85.f90 | 36 ++++++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/associate_85.f90 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)) { 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); 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); + 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" } } -- 2.55.0
