diff options
author | Michael Matz <matz@suse.de> | 2011-02-18 19:52:16 +0000 |
---|---|---|
committer | Michael Matz <matz@gcc.gnu.org> | 2011-02-18 19:52:16 +0000 |
commit | b3c1b8a1d6838854acf96be354339a62ff27599e (patch) | |
tree | ed9bae538119f7a14e04f53cad9c5316df51293e /gcc/fortran/trans-expr.c | |
parent | 430aa86819b6a4e6a806220886a77a08e5afc0f8 (diff) | |
download | gcc-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.c | 20 |
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); |