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

Reply via email to