https://gcc.gnu.org/g:3f31b17adb3fe9b4b00198dfb3330e4b40dd7091
commit 3f31b17adb3fe9b4b00198dfb3330e4b40dd7091 Author: Mikael Morin <[email protected]> Date: Thu Sep 17 14:43:02 2026 +0200 fortran: Use span array indexing for class pointers [PR127448] Fortran-tested on aarch64-unknown-linux-gnu. OK for mainline? -- >8 -- Mark the _data field of pointer class containers with the GFC_DECL_PTR_ARRAY_P flag, so that they use span indexing. Before this change, it was assumed that the size taken from the class container was the correct span value. It is not the case if the pointer target is a subobject of a bigger object, and yet is polymorphic. The change tries to keep the current behaviour if possible, that is use the size from the class container if the array is known to be contiguous. I doubt the information is properly propagated everywhere, but it should be conservatively correct. The is_pointer_array hunk removes a condition that is redundant: the type of the operand 1 of a component ref is the type of the field, which is also the type of the component ref itself, which has already been checked before. I suspect the condition to be a typo and should check operand 0 of the component ref. If that was the case, this patch would remove it anyway. PR fortran/127448 gcc/fortran/ChangeLog: * trans-array.cc (is_pointer_array): Remove redundant condition. (is_span_addressed_array): For polymorphic arrays, return false if the array is known to be contiguous. * trans-types.cc (gfc_get_derived_type): Also set the GFC_DECL_PTR_ARRAY_P flag for _data fields of class containers corresponding to polymorphic array pointers. Diff: --- gcc/fortran/trans-array.cc | 28 +++++++++++++++++++++++++--- gcc/fortran/trans-types.cc | 5 +++-- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 2d60ea3ff5a3..4abf9da49150 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -484,8 +484,7 @@ is_pointer_array (tree expr) /* The field declaration is marked as a pointer array. */ if (TREE_CODE (expr) == COMPONENT_REF - && GFC_DECL_PTR_ARRAY_P (TREE_OPERAND (expr, 1)) - && !GFC_CLASS_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1)))) + && GFC_DECL_PTR_ARRAY_P (TREE_OPERAND (expr, 1))) return true; return false; @@ -501,7 +500,30 @@ static bool is_span_addressed_array (tree expr) { if (is_pointer_array (expr)) - return true; + { + /* For classes, index arrays using the size from the virtual pointer if + the array is contiguous. Otherwise use the span. */ + if (TREE_CODE (expr) == COMPONENT_REF + && GFC_CLASS_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0))) + && TYPE_LANG_SPECIFIC (TREE_TYPE (expr))) + { + switch (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (expr))) + { + case GFC_ARRAY_ASSUMED_SHAPE_CONT: + case GFC_ARRAY_ASSUMED_RANK_CONT: + case GFC_ARRAY_ASSUMED_RANK_ALLOCATABLE: + case GFC_ARRAY_ASSUMED_RANK_POINTER_CONT: + case GFC_ARRAY_ALLOCATABLE: + case GFC_ARRAY_POINTER_CONT: + return false; + + default: + break; + } + } + + return true; + } if (VAR_P (expr) && GFC_DECL_PTR_ARRAY_P (expr) diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc index ef80cd8feabb..3675f0932535 100644 --- a/gcc/fortran/trans-types.cc +++ b/gcc/fortran/trans-types.cc @@ -3167,8 +3167,9 @@ gfc_get_derived_type (gfc_symbol * derived, int codimen) if (class_coarray_flag || !c->backend_decl || c->attr.caf_token) c->backend_decl = field; - if (c->attr.pointer && (c->attr.dimension || c->attr.codimension) - && !(c->ts.type == BT_DERIVED && strcmp (c->name, "_data") == 0)) + if ((c->attr.dimension || c->attr.codimension) + && ((derived->attr.is_class && c->attr.class_pointer) + || (!derived->attr.is_class && c->attr.pointer))) GFC_DECL_PTR_ARRAY_P (c->backend_decl) = 1; }
