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


Reply via email to