[Bug fortran/126968] ICE on invalid use of ASSOCIATE

"jvdelisle at gcc dot gnu.org via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126968

Jerry DeLisle <jvdelisle at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2026-08-20

--- Comment #1 from Jerry DeLisle <jvdelisle at gcc dot gnu.org> ---
Possible fix, still testing. This is touching areas Paul is working so I will
hold for a while after I finish testing here.

diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 5a7b0a7acb3..71ac7782beb 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -6935,7 +6935,7 @@ void
 gfc_fixup_inferred_type_refs (gfc_expr *e)
 {
   gfc_ref *ref, *new_ref;
-  gfc_symbol *sym, *derived;
+  gfc_symbol *sym, *derived, *dt;
   gfc_expr *target;
   sym = e->symtree->n.sym;

@@ -7036,17 +7036,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;
+       }
+
+      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;
+      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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.