aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-expr.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2011-02-18 19:52:16 +0000
committerMichael Matz <matz@gcc.gnu.org>2011-02-18 19:52:16 +0000
commitb3c1b8a1d6838854acf96be354339a62ff27599e (patch)
treeed9bae538119f7a14e04f53cad9c5316df51293e /gcc/fortran/trans-expr.c
parent430aa86819b6a4e6a806220886a77a08e5afc0f8 (diff)
downloadgcc-b3c1b8a1d6838854acf96be354339a62ff27599e.zip
gcc-b3c1b8a1d6838854acf96be354339a62ff27599e.tar.gz
gcc-b3c1b8a1d6838854acf96be354339a62ff27599e.tar.bz2
re PR fortran/45586 (ICE non-trivial conversion at assignment)
PR fortran/45586 * gfortran.h (struct gfc_component): Add norestrict_decl member. * trans.h (struct lang_type): Add nonrestricted_type member. * trans-expr.c (gfc_conv_component_ref): Search fields with correct parent type. * trans-types.c (mirror_fields, gfc_nonrestricted_type): New. (gfc_sym_type): Use it. testsuite/ PR fortran/45586 * gfortran.dg/lto/pr45586_0.f90: New test. * gfortran.dg/typebound_proc_20.f90: Ditto. * gfortran.dg/typebound_proc_21.f90: Ditto. From-SVN: r170284
Diffstat (limited to 'gcc/fortran/trans-expr.c')
-rw-r--r--gcc/fortran/trans-expr.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index b7d7ed9..3cf8df5 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -504,6 +504,26 @@ gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
field = c->backend_decl;
gcc_assert (TREE_CODE (field) == FIELD_DECL);
decl = se->expr;
+
+ /* Components can correspond to fields of different containing
+ types, as components are created without context, whereas
+ a concrete use of a component has the type of decl as context.
+ So, if the type doesn't match, we search the corresponding
+ FIELD_DECL in the parent type. To not waste too much time
+ we cache this result in norestrict_decl. */
+
+ if (DECL_FIELD_CONTEXT (field) != TREE_TYPE (decl))
+ {
+ tree f2 = c->norestrict_decl;
+ if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
+ for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
+ if (TREE_CODE (f2) == FIELD_DECL
+ && DECL_NAME (f2) == DECL_NAME (field))
+ break;
+ gcc_assert (f2);
+ c->norestrict_decl = f2;
+ field = f2;
+ }
tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
decl, field, NULL_TREE);