| Message ID | 999b82a5-1210-4b0d-b83d-94b987ac4626@gmx.de |
|---|---|
| State | New |
| Headers |
Return-Path: <gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A79943858C42 for <patchwork@sourceware.org>; Thu, 11 Sep 2025 18:30:42 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A79943858C42 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, secure) header.d=gmx.de header.i=anlauf@gmx.de header.a=rsa-sha256 header.s=s31663417 header.b=UbeSgVet X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout.gmx.net (mout.gmx.net [212.227.15.15]) by sourceware.org (Postfix) with ESMTPS id 76BE93858D26; Thu, 11 Sep 2025 18:28:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 76BE93858D26 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=gmx.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmx.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 76BE93858D26 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=212.227.15.15 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1757615315; cv=none; b=O2ZEWmpT8FU5nLXzTDEzWdz6wioRmElu4nZdhT9T6FIAEoHzTqDcsxgumiyFrLaxJR4vXvRFhsd13iMcKo1iILqLIJITOnRGfZYvR5HeQCoH5fmIShEOKKxkGFOFnpnWaKSj3JKWUt0xtHK11wNdXv6x0rpCqJ5ivar6as3mGSs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1757615315; c=relaxed/simple; bh=3K7iQgSkfx6F+Hx041uRyPfDnAuVOefvKk8gPcYwggM=; h=DKIM-Signature:Message-ID:Date:MIME-Version:From:Subject; b=noT4RzgG9TRIprZ5RMWmHwhFOvd3uVS1qLduBhkTJPwvrOa/7VSkQmqlpkILEQkSy6McUPngT86O/etMR4Wfm1FJM7kEXBVbiFMfnOcJZysBkwKnW4h+5Q2DlHYSxzNi38iYZwbjDRUawIMuin8FAwpv3LVaZE7zSP6NPsF6BLo= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 76BE93858D26 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmx.de; s=s31663417; t=1757615314; x=1758220114; i=anlauf@gmx.de; bh=wHnLLGDy55w8pM5ZD+aFsPacTn1PEmMV29KJH7RvAWU=; h=X-UI-Sender-Class:Content-Type:Message-ID:Date:MIME-Version:Cc: From:Subject:cc:content-transfer-encoding:content-type:date:from: message-id:mime-version:reply-to:subject:to; b=UbeSgVetx/aMcNvSc0UYgeZRe71K/Lu+nowykYot5qgOsyRtQHQGiNCd3DOmgIgq z3/mOSeVkYBITqhEvKPkJRq4Ry1kJb5FVAj0rjnr/T8zX+dguE4EZYnKmmLWPDk4j PybPb5KkhXz+s/gl2MascUnI1eDO7ikkHgnSIqN+jz4cMO0XRSJLlDHtEFg1EPaOn hdgz9UkyQ4OXibYqQ6f7B+u0k173mtkRAjsUiRjB7AoTguQy+jLkuPVz4eowI9P3Q oWSSXO3QrfUUFGL8jM8e91UK8pKib3aQYrGAfsh0zPgPWWUl+hU2FJe4JsgZRhFWh 4pK6HjzUpTOzyd4DaQ== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from [192.168.178.29] ([93.207.86.103]) by mail.gmx.net (mrgmx004 [212.227.17.190]) with ESMTPSA (Nemesis) id 1M72sP-1v3deg3x1D-00HH2G; Thu, 11 Sep 2025 20:28:34 +0200 Content-Type: multipart/mixed; boundary="------------ZSdQw4MLahec02uE9haeJzyt" Message-ID: <999b82a5-1210-4b0d-b83d-94b987ac4626@gmx.de> Date: Thu, 11 Sep 2025 20:28:33 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Newsgroups: gmane.comp.gcc.fortran,gmane.comp.gcc.patches Content-Language: en-US Cc: fortran <fortran@gcc.gnu.org>, gcc-patches <gcc-patches@gcc.gnu.org> From: Harald Anlauf <anlauf@gmx.de> Subject: [PATCH] Fortran: fix assignment to allocatable scalar polymorphic component [PR121616] X-Provags-ID: V03:K1:JkN6wP4kgSMGnSc4BhBtlr+s+xhcBwcQ/Qn1iW1grmqZUMx3P8p tUzESUiF3eqgjT9ay/LTpqoo4PIlnCo7Fuk1StsYBfuCqMLldf8I/XONpUt+YLB6gBI4oUk ojIEryZ+YSGgjWvqTukHgCqY/oxkaffNel68SEsVZaDYAYjnVwTE2RUBjOw8E/sXu+6SQf+ 5lOHFpEATcFvpgR9hdMSg== UI-OutboundReport: notjunk:1;M01:P0:dGvEvSptabk=;K2qozvmYPML9IE7UMTdaXmSgyQN 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 X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_ASCII_DIVIDERS, MALFORMED_FREEMAIL, MISSING_HEADERS, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org |
| Series |
Fortran: fix assignment to allocatable scalar polymorphic component [PR121616]
|
|
Commit Message
Harald Anlauf
Sept. 11, 2025, 6:28 p.m. UTC
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? If there are no objections, I would like to backport to at least 15-branch. Thanks, Harald
Comments
On 9/11/25 11:28 AM, Harald Anlauf wrote: > 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? > > If there are no objections, I would like to backport to at least > 15-branch. > > Thanks, > Harald > OK and backport, very simple. Jerry
Hi Jerry! Am 11.09.25 um 21:30 schrieb Jerry D: > On 9/11/25 11:28 AM, Harald Anlauf wrote: >> 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? >> >> If there are no objections, I would like to backport to at least >> 15-branch. >> >> Thanks, >> Harald >> > > OK and backport, very simple. Thanks for the review! Pushed as r16-3813-g0899b826f7196f. I wonder how many more cases we have in the frontend where walking a reference chain misses similar simple things... Harald > Jerry >
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.
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; I saw that in passing, but did not hit it in the debugging session. I'd have to think of a more complex testcase.
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?
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
Le 12/09/2025 à 22:51, Harald Anlauf a écrit : > 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. > The latter sentence applies to allocatable, pointer/target, etc, but I don't think it should apply to dimension. Dimension is different because it's the parent reference that determines whether the subreference is a scalar or an array, thus whether it has the dimension attribute or not. > ... > > Assuming that scalar_comp is the ultimate component, its dimension is 0. > Err, well, no. I mean, it depends on what's before it. derived(123)%scalar_comp is a scalar, so it doesn't have the dimension attribute. But derived(:)%scalar_comp is an array, so it has the dimension attribute. > > 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 > That one is definitely an array, I hope we can agree on that. See the second sentence of 9.4.2 saying: A structure component may be a scalar or an array. So the presence in the section about scalars is not an indication that it really is scalar. > 9.5 Arrays > > Note 3 > > SCALAR_PARENT%ARRAY_FIELD(1:N) array section > SCALAR_PARENT%ARRAY_FIELD(1:N)%SCALAR_FIELD array section > Coming back to your patch, rephrasing my previous concerns. If I understand correctly, your patch changes the dimension attribute for the following cases: old value new value 1. array(i)%scalar_comp 1 0 2. array(:)%scalar_comp 1 0 3. scalar%array_comp(i) 0 1 1. is the desired change, but I think 2. and 3. are undesired.
Am 13.09.25 um 22:54 schrieb Mikael Morin: > Le 12/09/2025 à 22:51, Harald Anlauf a écrit : >> 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. >> > The latter sentence applies to allocatable, pointer/target, etc, but I > don't think it should apply to dimension. > Dimension is different because it's the parent reference that determines > whether the subreference is a scalar or an array, thus whether it has > the dimension attribute or not. > >> ... >> >> Assuming that scalar_comp is the ultimate component, its dimension is 0. >> > Err, well, no. I mean, it depends on what's before it. > derived(123)%scalar_comp is a scalar, so it doesn't have the dimension > attribute. > But derived(:)%scalar_comp is an array, so it has the dimension attribute. > >> >> 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 >> > That one is definitely an array, I hope we can agree on that. > See the second sentence of 9.4.2 saying: > A structure component may be a scalar or an array. > > So the presence in the section about scalars is not an indication that > it really is scalar. > >> 9.5 Arrays >> >> Note 3 >> >> SCALAR_PARENT%ARRAY_FIELD(1:N) array section >> SCALAR_PARENT%ARRAY_FIELD(1:N)%SCALAR_FIELD array section >> > > Coming back to your patch, rephrasing my previous concerns. > If I understand correctly, your patch changes the dimension attribute > for the following cases: > old value new value > 1. array(i)%scalar_comp 1 0 > 2. array(:)%scalar_comp 1 0 > 3. scalar%array_comp(i) 0 1 > > 1. is the desired change, but I think 2. and 3. are undesired. Well, the patch changes gfc_variable_attr, but see also the comment I cited. This is needed that the scalarized assignment sees the ultimate component, which is an allocatable scalar for the testcase. I did not claim that gfc_expr_attr always returns the right attributes.
Le 14/09/2025 à 21:17, Harald Anlauf a écrit : > Am 13.09.25 um 22:54 schrieb Mikael Morin: >> Le 12/09/2025 à 22:51, Harald Anlauf a écrit : >>> 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. >>> >> The latter sentence applies to allocatable, pointer/target, etc, but I >> don't think it should apply to dimension. >> Dimension is different because it's the parent reference that >> determines whether the subreference is a scalar or an array, thus >> whether it has the dimension attribute or not. >> >>> ... >>> >>> Assuming that scalar_comp is the ultimate component, its dimension is 0. >>> >> Err, well, no. I mean, it depends on what's before it. >> derived(123)%scalar_comp is a scalar, so it doesn't have the dimension >> attribute. >> But derived(:)%scalar_comp is an array, so it has the dimension >> attribute. >> >>> >>> 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 >>> >> That one is definitely an array, I hope we can agree on that. >> See the second sentence of 9.4.2 saying: >> A structure component may be a scalar or an array. >> >> So the presence in the section about scalars is not an indication that >> it really is scalar. >> >>> 9.5 Arrays >>> >>> Note 3 >>> >>> SCALAR_PARENT%ARRAY_FIELD(1:N) array section >>> SCALAR_PARENT%ARRAY_FIELD(1:N)%SCALAR_FIELD array section >>> >> >> Coming back to your patch, rephrasing my previous concerns. >> If I understand correctly, your patch changes the dimension attribute >> for the following cases: >> old value new value >> 1. array(i)%scalar_comp 1 0 >> 2. array(:)%scalar_comp 1 0 >> 3. scalar%array_comp(i) 0 1 >> >> 1. is the desired change, but I think 2. and 3. are undesired. > > Well, the patch changes gfc_variable_attr, but see also the comment > I cited. This is needed that the scalarized assignment sees the > ultimate component, which is an allocatable scalar for the testcase. > > I did not claim that gfc_expr_attr always returns the right attributes. > I bet it does for some definition of "right". Anyway, I'm propably wasting my time arguing about this. Let's wait and see if something breaks.
On 9/15/25 1:56 AM, Mikael Morin wrote: > Le 14/09/2025 à 21:17, Harald Anlauf a écrit : >> Am 13.09.25 um 22:54 schrieb Mikael Morin: >>> Le 12/09/2025 à 22:51, Harald Anlauf a écrit : >>>> 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. >>>> >>> The latter sentence applies to allocatable, pointer/target, etc, but I don't >>> think it should apply to dimension. >>> Dimension is different because it's the parent reference that determines >>> whether the subreference is a scalar or an array, thus whether it has the >>> dimension attribute or not. >>> >>>> ... >>>> >>>> Assuming that scalar_comp is the ultimate component, its dimension is 0. >>>> >>> Err, well, no. I mean, it depends on what's before it. >>> derived(123)%scalar_comp is a scalar, so it doesn't have the dimension >>> attribute. >>> But derived(:)%scalar_comp is an array, so it has the dimension attribute. >>> >>>> >>>> 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 >>>> >>> That one is definitely an array, I hope we can agree on that. >>> See the second sentence of 9.4.2 saying: >>> A structure component may be a scalar or an array. >>> >>> So the presence in the section about scalars is not an indication that it >>> really is scalar. >>> >>>> 9.5 Arrays >>>> >>>> Note 3 >>>> >>>> SCALAR_PARENT%ARRAY_FIELD(1:N) array section >>>> SCALAR_PARENT%ARRAY_FIELD(1:N)%SCALAR_FIELD array section >>>> >>> >>> Coming back to your patch, rephrasing my previous concerns. >>> If I understand correctly, your patch changes the dimension attribute for the >>> following cases: >>> old value new value >>> 1. array(i)%scalar_comp 1 0 >>> 2. array(:)%scalar_comp 1 0 >>> 3. scalar%array_comp(i) 0 1 >>> >>> 1. is the desired change, but I think 2. and 3. are undesired. >> >> Well, the patch changes gfc_variable_attr, but see also the comment >> I cited. This is needed that the scalarized assignment sees the >> ultimate component, which is an allocatable scalar for the testcase. >> >> I did not claim that gfc_expr_attr always returns the right attributes. >> > I bet it does for some definition of "right". > Anyway, I'm propably wasting my time arguing about this. > Let's wait and see if something breaks. It is never a waste of time to have open dialogue. We all learn from this exchange. Breaking things is also a way to learn and promote further investigation. Cheers to all, Jerry
Am 15.09.25 um 19:21 schrieb Jerry D: > On 9/15/25 1:56 AM, Mikael Morin wrote: >> Le 14/09/2025 à 21:17, Harald Anlauf a écrit : >>> Am 13.09.25 um 22:54 schrieb Mikael Morin: >>>> Le 12/09/2025 à 22:51, Harald Anlauf a écrit : >>> Well, the patch changes gfc_variable_attr, but see also the comment >>> I cited. This is needed that the scalarized assignment sees the >>> ultimate component, which is an allocatable scalar for the testcase. >>> >>> I did not claim that gfc_expr_attr always returns the right attributes. >>> >> I bet it does for some definition of "right". >> Anyway, I'm propably wasting my time arguing about this. >> Let's wait and see if something breaks. > > It is never a waste of time to have open dialogue. We all learn from > this exchange. Breaking things is also a way to learn and promote > further investigation. Quite true. Ideally, if we kick the tree, all bad apples (bugs) will fall down eventually. Regarding attributes, dimensions, and all that stuff, there is an apparent history visible when looking at the code. And when it comes to component, substring, or specially inquiry references (type, kind, real and imaginary part, all of which were added over time), the handling seems scattered over lots of places. I've been wondering if there is some strategy to "differentially" debug the frontend: using a simple testcase, and replacing just a single token by another one, and see when and how the path splits and maybe rejoins later. Cases at hand: pr108581. Replacing fixed-length character by deferred length. Or pr121939: character(kind=4) vs. kind=1. Cheers! > Cheers to all, > > Jerry >
Le 15/09/2025 à 19:21, Jerry D a écrit : > On 9/15/25 1:56 AM, Mikael Morin wrote: >> Le 14/09/2025 à 21:17, Harald Anlauf a écrit : >>> Am 13.09.25 um 22:54 schrieb Mikael Morin: >>>> Le 12/09/2025 à 22:51, Harald Anlauf a écrit : >>>>> 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. >>>>> >>>> The latter sentence applies to allocatable, pointer/target, etc, but >>>> I don't think it should apply to dimension. >>>> Dimension is different because it's the parent reference that >>>> determines whether the subreference is a scalar or an array, thus >>>> whether it has the dimension attribute or not. >>>> >>>>> ... >>>>> >>>>> Assuming that scalar_comp is the ultimate component, its dimension >>>>> is 0. >>>>> >>>> Err, well, no. I mean, it depends on what's before it. >>>> derived(123)%scalar_comp is a scalar, so it doesn't have the >>>> dimension attribute. >>>> But derived(:)%scalar_comp is an array, so it has the dimension >>>> attribute. >>>> >>>>> >>>>> 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 >>>>> >>>> That one is definitely an array, I hope we can agree on that. >>>> See the second sentence of 9.4.2 saying: >>>> A structure component may be a scalar or an array. >>>> >>>> So the presence in the section about scalars is not an indication >>>> that it really is scalar. >>>> >>>>> 9.5 Arrays >>>>> >>>>> Note 3 >>>>> >>>>> SCALAR_PARENT%ARRAY_FIELD(1:N) array section >>>>> SCALAR_PARENT%ARRAY_FIELD(1:N)%SCALAR_FIELD array section >>>>> >>>> >>>> Coming back to your patch, rephrasing my previous concerns. >>>> If I understand correctly, your patch changes the dimension >>>> attribute for the following cases: >>>> old value new value >>>> 1. array(i)%scalar_comp 1 0 >>>> 2. array(:)%scalar_comp 1 0 >>>> 3. scalar%array_comp(i) 0 1 >>>> >>>> 1. is the desired change, but I think 2. and 3. are undesired. >>> >>> Well, the patch changes gfc_variable_attr, but see also the comment >>> I cited. This is needed that the scalarized assignment sees the >>> ultimate component, which is an allocatable scalar for the testcase. >>> >>> I did not claim that gfc_expr_attr always returns the right attributes. >>> >> I bet it does for some definition of "right". >> Anyway, I'm propably wasting my time arguing about this. >> Let's wait and see if something breaks. > > It is never a waste of time to have open dialogue. Yeah, well, communication can be difficult. My premise when I started commenting was that the function should return a value as defined by the standard (for the standard attributes). Harald doesn't seem to agree with that, and without that premise the function is free to return any result, so my point becomes moot. > We all learn from > this exchange. Breaking things is also a way to learn and promote > further investigation. >
Le 15/09/2025 à 21:33, Harald Anlauf a écrit : > Am 15.09.25 um 19:21 schrieb Jerry D: >> On 9/15/25 1:56 AM, Mikael Morin wrote: >>> Le 14/09/2025 à 21:17, Harald Anlauf a écrit : >>>> Am 13.09.25 um 22:54 schrieb Mikael Morin: >>>>> Le 12/09/2025 à 22:51, Harald Anlauf a écrit : >>>> Well, the patch changes gfc_variable_attr, but see also the comment >>>> I cited. This is needed that the scalarized assignment sees the >>>> ultimate component, which is an allocatable scalar for the testcase. >>>> >>>> I did not claim that gfc_expr_attr always returns the right attributes. >>>> >>> I bet it does for some definition of "right". >>> Anyway, I'm propably wasting my time arguing about this. >>> Let's wait and see if something breaks. >> >> It is never a waste of time to have open dialogue. We all learn from >> this exchange. Breaking things is also a way to learn and promote >> further investigation. > > Quite true. > > Ideally, if we kick the tree, all bad apples (bugs) will fall down > eventually. > > Regarding attributes, dimensions, and all that stuff, there is an > apparent history visible when looking at the code. And when it > comes to component, substring, or specially inquiry references > (type, kind, real and imaginary part, all of which were added > over time), the handling seems scattered over lots of places. > > I've been wondering if there is some strategy to "differentially" > debug the frontend: using a simple testcase, and replacing just > a single token by another one, and see when and how the path > splits and maybe rejoins later. > Maybe you can use code coverage data, but I'm not aware of any ready-made diff tool for it. gcov can produce json data with the --json-format argument, that can be a good starting point.
Am 15.09.25 um 22:32 schrieb Mikael Morin: > Le 15/09/2025 à 21:33, Harald Anlauf a écrit : >> I've been wondering if there is some strategy to "differentially" >> debug the frontend: using a simple testcase, and replacing just >> a single token by another one, and see when and how the path >> splits and maybe rejoins later. >> > Maybe you can use code coverage data, but I'm not aware of any ready- > made diff tool for it. gcov can produce json data with the --json- > format argument, that can be a good starting point. I have no idea how to use that. What I meant: the modified token may show up e.g. in a variable decl, and when it is passed to some function in trans*.cc, that tiny difference evolves etc. I just get overwhelmed by all the forest I usually end up with, and hardly see the tiny little twig that counts.
From 0899b826f7196f609fc8991456eb728802061318 Mon Sep 17 00:00:00 2001 From: Harald Anlauf <anlauf@gmx.de> Date: Thu, 11 Sep 2025 20:17:31 +0200 Subject: [PATCH] Fortran: fix assignment to allocatable scalar polymorphic component [PR121616] PR fortran/121616 gcc/fortran/ChangeLog: * primary.cc (gfc_variable_attr): Properly set dimension attribute from a component ref. gcc/testsuite/ChangeLog: * gfortran.dg/alloc_comp_assign_17.f90: New test. --- gcc/fortran/primary.cc | 2 + .../gfortran.dg/alloc_comp_assign_17.f90 | 96 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/alloc_comp_assign_17.f90 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; diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_assign_17.f90 b/gcc/testsuite/gfortran.dg/alloc_comp_assign_17.f90 new file mode 100644 index 00000000000..7a659f2e0c0 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/alloc_comp_assign_17.f90 @@ -0,0 +1,96 @@ +! { dg-do run } +! PR fortran/121616 +! +! Test fix for intrinsic assignment to allocatable scalar polymorphic component + +program p + call pr121616 () + call test_ts () +end + +! Derived from original PR (contributed by Jean Vézina) +subroutine pr121616 () + implicit none + integer :: i + type general + class(*), allocatable :: x + end type general + type(general) :: a(4), b(4) + ! Intrinsic assignment to a variable of unlimited polymorphic type + a(1)%x = 1 + a(2)%x = 3.14 + a(3)%x = .true. + a(4)%x = 'abc' + ! The workaround was to use a structure constructor + b(1) = general(1) + b(2) = general(3.14) + b(3) = general(.true.) + b(4) = general('abc') + do i = 1, 4 + if (.not. allocated (a(i)%x)) stop 10+i + if (.not. allocated (b(i)%x)) stop 20+i + call prt (a(i)%x, b(i)%x) + end do + do i = 1, 4 + deallocate (a(i)%x, b(i)%x) + end do +contains + subroutine prt (x, y) + class(*), intent(in) :: x, y + select type (v=>x) + type is (integer) + print *,v + type is (real) + print *,v + type is (logical) + print *,v + type is (character(*)) + print *,v + class default + error stop 99 + end select + if (.not. same_type_as (x, y)) stop 30+i + end subroutine prt +end + +! Contributed by a friend (private communication) +subroutine test_ts () + implicit none + + type :: t_inner + integer :: i + end type + + type :: t_outer + class(t_inner), allocatable :: inner + end type + + class(t_inner), allocatable :: inner + type(t_outer), allocatable :: outer(:) + integer :: i + + allocate(t_inner :: inner) + inner% i = 0 + + !------------------------------------------------ + ! Size of outer must be > 1 for the bug to appear + !------------------------------------------------ + allocate(outer(2)) + + !------------------------------ + ! Loop is necessary for the bug + !------------------------------ + do i = 1, size(outer) + write(*,*) i + !---------------------------------------------------- + ! Expect intrinsic assignment to polymorphic variable + !---------------------------------------------------- + outer(i)% inner = inner + deallocate (outer(i)% inner) + end do + + write(*,*) 'Loop DONE' + deallocate(outer) + deallocate(inner) + write(*,*) 'Dellocation DONE' +end -- 2.51.0