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