Hi all,
the attached patch fixes a problem with PARAMETER variables of
extended derived type: When resolving component references to the such
variables, we have to find the right component of the corresponding
structure constructor expression, which is done by the function
'find_component_ref'.
This function could not handle extended derived types, and so that is
what the patch does. For extended derived types, the first component
always represents the parent type. We have to iterate through the
whole inheritance chain, in order to check in which parent type the
desired component is located and fetch the corresponding constructor
component.
Regtested on x86_64-unknown-linux-gnu. Ok for trunk?
Cheers,
Janus
2015-01-02 Janus Weil <[email protected]>
PR fortran/57562
* expr.c (find_component_ref): Deal with extended types.
2015-01-02 Janus Weil <[email protected]>
PR fortran/57562
* gfortran.dg/extends_16.f90: New.
Index: gcc/fortran/expr.c
===================================================================
--- gcc/fortran/expr.c (Revision 219141)
+++ gcc/fortran/expr.c (Arbeitskopie)
@@ -1270,12 +1270,23 @@ depart:
static gfc_constructor *
find_component_ref (gfc_constructor_base base, gfc_ref *ref)
{
- gfc_component *comp;
- gfc_component *pick;
+ gfc_component *pick = ref->u.c.component;
gfc_constructor *c = gfc_constructor_first (base);
- comp = ref->u.c.sym->components;
- pick = ref->u.c.component;
+ gfc_symbol *dt = ref->u.c.sym;
+ int ext = dt->attr.extension;
+
+ /* For extended types, check if the desired component is in one of the
+ * parent types. */
+ while (ext>0 && gfc_find_component (dt->components->ts.u.derived, pick->name,
+ true, true))
+ {
+ dt = dt->components->ts.u.derived;
+ c = gfc_constructor_first (c->expr->value.constructor);
+ ext--;
+ }
+
+ gfc_component *comp = dt->components;
while (comp != pick)
{
comp = comp->next;
! { dg-do run }
!
! PR 57562: [OOP] ICE due to extended derived type with PARAMETER attribute
!
! Contributed by <[email protected]>
type :: Parent
integer :: member1 = 0
end type
type, extends(Parent) :: Child
integer :: member2 = 0
end type
type(Child), parameter :: object = Child(23, 42)
if (object%member1 /= 23) call abort
if (object%member2 /= 42) call abort
end