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 <ja...@gcc.gnu.org> PR fortran/57562 * expr.c (find_component_ref): Deal with extended types. 2015-01-02 Janus Weil <ja...@gcc.gnu.org> 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 <helvio.vairin...@gmail.com> 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