Am 12.09.25 um 11:12 schrieb Mikael Morin:
Le 11/09/2025 à 22:46, Harald Anlauf a écrit :
Am 11.09.25 um 22:27 schrieb Mikael Morin:
Le 11/09/2025 à 20:28, Harald Anlauf a écrit :
Dear all,
here's a - once found - seemingly simple and obvious fix for a memory
corruption happening when intrinsic assignment is used to set a scalar
allocatable polymorphic component of a derived type when the latter
is instanciated as an array of rank > 0. Just get the dimension
attribute right when using gfc_variable_attr ...
The testcase is an extended version of the reporter's with unlimited
polymorphism, including another simpler one contributed by a friend.
Without the fix, both tests crash with memory corruption of various
kinds.
Regtested on x86_64-pc-linux-gnu. OK for mainline?
Hello Harald,
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 6df95558bb1..2cb930d83b8 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -3057,12 +3057,14 @@ gfc_variable_attr (gfc_expr *expr,
gfc_typespec *ts)
if (comp->ts.type == BT_CLASS)
{
+ dimension = CLASS_DATA (comp)->attr.dimension;
codimension = CLASS_DATA (comp)->attr.codimension;
pointer = CLASS_DATA (comp)->attr.class_pointer;
allocatable = CLASS_DATA (comp)->attr.allocatable;
}
else
{
+ dimension = comp->attr.dimension;
codimension = comp->attr.codimension;
if (expr->ts.type == BT_CLASS && strcmp (comp->name,
"_data") == 0)
pointer = comp->attr.class_pointer;
I think the dimension flag should additionally be cleared if there is
an array element reference after the component. Otherwise one could
get the dimension attribute for a scalar expression (say
derived%array_comp(123)).
I don't really have a testcase that would exhibit a failure, I'm just
being overly cautious.
Thanks for the patch in any case.
You mean further up?
switch (ref->type)
{
case REF_ARRAY:
switch (ref->u.ar.type)
{
...
case AR_ELEMENT:
/* Handle coarrays. */
if (ref->u.ar.dimen > 0)
allocatable = pointer = optional = false;
break;
Yes, that's the place.
The more I look at your patch, the less I understand it.
So, given an array expression such as array(:)%scalar_comp,
gfc_variable_attr on it would return a result without the dimension
attribute?
Well, the comment before gfc_variable_attr says:
/* Given an expression that is a variable, figure out what the
ultimate variable's type and attribute is, traversing the reference
structures if necessary.
This subroutine is trickier than it looks. We start at the base
symbol and store the attribute. Component references load a
completely new attribute.
...
Assuming that scalar_comp is the ultimate component, its dimension is 0.
The standard appears somewhat ambiguous on the expression you give:
9.4 Scalars
Note 2
ARRAY_PARENT(1:N)%SCALAR_FIELD component of array section parent
9.5 Arrays
Note 3
SCALAR_PARENT%ARRAY_FIELD(1:N) array section
SCALAR_PARENT%ARRAY_FIELD(1:N)%SCALAR_FIELD array section