Le 20/10/2026 à 00:47, Jerry DeLisle a écrit :
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index a37a5024ecc..401431252d1 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -7108,17 +7108,47 @@ gfc_fixup_inferred_type_refs (gfc_expr *e)
        }
     }
- /* Proceed as far as the first component reference and ensure that the
-     correct derived type is being used.  */
+  /* The type used to build the component references at parse time was only
+     a guess, so they can point into a different derived type that happens
+     to have a component of the same name.  Bind each one by name to the
+     corrected type.  */
+  dt = derived;
   for (ref = e->ref; ref; ref = ref->next)
-    if (ref->type == REF_COMPONENT)
-      {
-       if (ref->u.c.component->name[0] != '_')
-         ref->u.c.sym = derived;
-       else
+    {
+      gfc_component *c;
+
+      if (ref->type != REF_COMPONENT)
+       continue;
+

+      /* The '_data', '_vptr' and '_len' fields belong to the class
+        container, and 'derived' already is the type that follows '_data'.  */
+      if (ref->u.c.component->name[0] == '_')
+       {
          ref->u.c.sym = sym->ts.u.derived;
+         continue;
+       }
I think this will do the wrong thing for the second _data reference in the chain (if there is more than one). I mean for a reference like foo%class_comp1(4)%class_comp2(:)%bar.

+
+      if (!dt)
        break;
-      }
+
+      c = gfc_find_component (dt, ref->u.c.component->name, true, true, NULL);
+      if (!c)
+       {
+         gfc_error ("%qs at %L is not a member of the %qs structure",
+                    ref->u.c.component->name, &e->where, dt->name);
+         return;
+       }
+
+      ref->u.c.sym = dt;
+      ref->u.c.component = c;
+
+      if (c->ts.type == BT_DERIVED)
+       dt = c->ts.u.derived;

+      else if (c->ts.type == BT_CLASS && CLASS_DATA (c))
+       dt = CLASS_DATA (c)->ts.u.derived;
I think there are two cases here.
If the next reference is one of the '_*' components, its ref->u.c.sym is this component's c->ts.u.derived (i.e. the class container type). If the next reference is any other component, the '_data' component in between is implicit, and the ref->u.c.sym will be this component's CLASS_DATA (c)->ts.u.derived (i.e. the declared type).

I don't think that any of these cases is excluded in the context of ASSOCIATE. resolve.cc's resolve_assoc_var contains:

  if (target->ts.type == BT_CLASS)
    gfc_fix_class_refs (target);

which is conditional on the ultimate type. So if the ultimate type is polymorphic, all the polymorphic intermediary references have an explicit '_data' component ref; and if the ultimate type isn't polymorphic none of the polymorphic intermediary references have the '_data' component ref.

+      else
+       dt = NULL;
+    }
/* Verify that the type inference mechanism has not introduced a spurious
      array reference.  This can happen with an associate name, whose selector

Reply via email to