Le 25/10/2026 à 13:58, Jerry DeLisle a écrit :
This attached patch is one of the followups for the v2 patch and applies
after the v2.
I looked into the possibility of fixing this earlier in the parser. It
currently filters candidates only by the first component name, then
drops the list. If it kept the list and filtered it by the whole chain
as it parses (q%cm%c2 needs a type whose cm has a c2), it would guess
right far more often. This would not fix all cases though. I wonder if
some sort two pass approach would help.
My opinion is we are doing too much at parse time, and when we don't
know for sure as in this case, we should rather do less than do more,
and wait to have more knowledge. I'm not sure what you mean by two
passes. Isn't the current status a two passes approach (guess at parse
time, fix at resolution time)?
Regression tested on x86_64.
Ok for mainline?
I have one small memory management suggestion below, but OK in any case.
Thanks for the patch.
Regards,
Jerry
---
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index bbe5f845f66..74564670321 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -6998,6 +6998,63 @@ resolve_procedure:
}
+/* The reference at *LINK follows a reference to component C in the
+ inferred type expression E. Make it agree with the array spec of C. */
+
+static void
+fixup_inferred_component_array_ref (gfc_expr *e, gfc_component *c,
+ gfc_ref **link)
+{
+ gfc_ref *ref = *link, *new_ref;
+ gfc_array_spec *as;
+
+ if (c->ts.type == BT_CLASS)
+ as = CLASS_DATA (c) ? CLASS_DATA (c)->as : NULL;
+ else
+ as = c->as;
+
+ if (ref && ref->type == REF_ARRAY)
+ {
+ if (as)
+ ref->u.ar.as = as;
+ else if (ref->u.ar.type == AR_FULL)
+ {
+ /* Drop the full array ref of a component guessed to be an array. */
+ *link = ref->next;
+ free (ref);
+ }
+ else if (c->ts.type == BT_CHARACTER && ref->u.ar.dimen == 1
+ && ref->u.ar.dimen_type[0] == DIMEN_RANGE
+ && !ref->u.ar.stride[0])
+ {
+ /* A substring misidentified as an array section. */
+ new_ref = gfc_get_ref ();
+ new_ref->type = REF_SUBSTRING;
+ new_ref->u.ss.start = ref->u.ar.start[0];
+ new_ref->u.ss.end = ref->u.ar.end[0];
+ new_ref->u.ss.length = c->ts.u.cl;
+ new_ref->next = ref->next;
+ *link = new_ref;
+ free (ref);
Can't you maybe reuse `ref' instead of allocating a new object?
+ }
+ else
+ /* Leave the array ref of a scalar to find_array_spec to diagnose. */
+ ref->u.ar.as = NULL;
+ }
+ else if (as)
+ {
+ /* Supply the full array ref of a component guessed to be scalar. */
+ new_ref = gfc_get_ref ();
+ new_ref->type = REF_ARRAY;
+ new_ref->u.ar.type = AR_FULL;
+ new_ref->u.ar.as = as;
+ new_ref->u.ar.where = e->where;
+ new_ref->next = ref;
+ *link = new_ref;
+ }
+}
+
+
/* 'sym' was initially guessed to be derived type but has been corrected
in resolve_assoc_var to be a class entity or the derived type correcting.
If a class entity it will certainly need the _data reference or the