[RFC,middle-end/PR102359] Not add initialization for READONLY variables with -ftrivial-auto-var-init
Message ID | C84D1E41-EC7C-4140-9247-4B5B60E5CDB3@oracle.com |
---|---|
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 0C10E385802D for <patchwork@sourceware.org>; Wed, 29 Sep 2021 21:30:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0C10E385802D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1632951036; bh=/gKb+HLp0ILM9JERG3J1C0NPGniD+805YS6F2HnIwdA=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=fYFGJJp2KDWfz7hIDLLEdgTZmGOYlh1pfxf0uYmiBK88Y7AIHmn60O6o+PFIb8YoC kLg5xk8+YOr6CvL225j3HCLjvoRnakBAlvR/kf7zK7RqviwwPuAOd8Y2BKOQDGmUO5 M1VZbMH3iXCMK56lflt6MjALKSk25lf6FsOb/318= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by sourceware.org (Postfix) with ESMTPS id B7C6C3858C60 for <gcc-patches@gcc.gnu.org>; Wed, 29 Sep 2021 21:30:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B7C6C3858C60 Received: from pps.filterd (m0246631.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 18TL3lL2017463; Wed, 29 Sep 2021 21:30:04 GMT Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3bcg3hrt2s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 29 Sep 2021 21:30:04 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 18TLTjxK007723; Wed, 29 Sep 2021 21:30:03 GMT Received: from nam10-mw2-obe.outbound.protection.outlook.com (mail-mw2nam10lp2100.outbound.protection.outlook.com [104.47.55.100]) by aserp3020.oracle.com with ESMTP id 3bceu63npc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 29 Sep 2021 21:30:03 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=QDzTGurseN+3pEeaH000KqNTfl0YAxy2JSf7grdZLX+/TkGM+lMMNghjH1hf7Bs99BHlxZUYkV7NML5+3yErTas9vcKPGwb+yIF8nX7i0NdmpwxNAv2M/PyzomknXkUFH+qj79wKcCBT80SOSgpDJiqnKa2XVBHqb5yOUTlFbPJE7w95zQ2wKuo3FidTeVz9+CPBabbVaRRX8616LTqPekX0ofR4QwArvCaW2QVv9C0hJLtIMW0LLdG2jq9GSiUaTLMqUawg6yAL7pVH4gHSdtrvd8m7NPQrevKqby7HZeMFM2e31ju4R7jStCs7zOX63dp17WN5VO46lpEqtLHapg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=/gKb+HLp0ILM9JERG3J1C0NPGniD+805YS6F2HnIwdA=; b=IFnHM3/sjHuY5aXcjfvjlv6610wKqThyeBwCK7E7hVO3NbeBpBiBOVffXTotDjJmPTmhF6BGL5bP1ozsLWT6at0+Kyl9XZrxhGpTDcW3G/UtMEWVGS3UyQHxiyBQBjDpryrnNiEaCI4lr9pp6eMtJWgEmce73z8dTagCtxWm316GSytqp/QyjaqbUTOv7r8yLlK0NREajJqJhmrJ6di63zH34NxpX9ScOx2JzZ76gmupp4qtBhlhwE3Y3zRAwEYos3o4dlZ6j5vUQTTIREjf/gsxg0/p3RshTYOjvBGijWEI2vso7A8vuT8isSEOgv/WdIYi636116CmfZ112nwm2w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none Received: from CH2PR10MB4344.namprd10.prod.outlook.com (2603:10b6:610:af::19) by CH2PR10MB3813.namprd10.prod.outlook.com (2603:10b6:610:5::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4566.14; Wed, 29 Sep 2021 21:30:00 +0000 Received: from CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::25f8:eaf:a3b9:fe86]) by CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::25f8:eaf:a3b9:fe86%3]) with mapi id 15.20.4566.015; Wed, 29 Sep 2021 21:30:00 +0000 To: richard Biener <rguenther@suse.de>, "jason@redhat.com" <jason@redhat.com> Subject: [RFC][Patch][middle-end/PR102359]Not add initialization for READONLY variables with -ftrivial-auto-var-init Thread-Topic: [RFC][Patch][middle-end/PR102359]Not add initialization for READONLY variables with -ftrivial-auto-var-init Thread-Index: AQHXtXko1di7hLoz90+84IQ/lVvdpw== Date: Wed, 29 Sep 2021 21:30:00 +0000 Message-ID: <C84D1E41-EC7C-4140-9247-4B5B60E5CDB3@oracle.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-mailer: Apple Mail (2.3608.120.23.2.7) x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 8b8cb247-a331-462a-41e0-08d983904ae9 x-ms-traffictypediagnostic: CH2PR10MB3813: x-microsoft-antispam-prvs: <CH2PR10MB38130396783E8B856AE2683780A99@CH2PR10MB3813.namprd10.prod.outlook.com> x-ms-oob-tlc-oobclassifiers: OLM:9508; x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: mfAB7ZYSkj+xbpBffyJL4/DoQ0jAYt/J50YWh6OwRrbHwyc8+SNojaYG7G7stBVw9l+mjfU3lTsWWB870gHDvCV3FBOKLU9+OOJ+jenNCKqhkBeH+9sLN6geB/bQVeJiySfO+2C5cVSsUh76av2liY3fOCLEoyHTFrZcMa68vCGmdVD+6zH7m5dsNGxmhuJROr059ajXryQl3PXVdH6CEuGfswrJyUpMdJvAvbohx5yrFyR2QmxhyWQGHwVKGV/5IGY/Konc2/QzqIonWNa4uVKvEnnXe5occNI6/nBE0W3EzVmNW7FVPIkCLKxk7xtidtIOtNnvRibbhO2ULgYmfjnzTesh1IOtEoEbmBPmRTvsSDsd/00u5TWShdipFPRiaCU8ZYk1XgUxyZxonqGqHMWfqipsOv6zAkEggrRIvhZX9fI8y8BcF8k+ZAoDKGLQU9cC1NNd2k+CcL7pWnORi9zfLpoO/wEXyMsuEQdM8/ctC7S/m13lKgZd6x+XNzStSSqA+LFfbJVEs96f7UcyJRsahsqiAGM/j2uyDFgAZjcOPsTHQPuKxt0wuoq3LH6op+tL2tHRsyBB0bWvYT6Nthl8V8j+wWV6S8nqDbe3StHLro271DwRmuPb7UqphuKSG07yDuH9nM2jPTXNuzWZISOX6PLf7AtL4+3S2MW5csc2qBhEsOPWleH6er4Ci/SOmjVZIWuL7pdMTz7lV7FWo4HdiDr6i+Yeu1+8XfjpSknIGv2F2S5mABIhSGJiiM8TNs8PiQc069d6+YO207g1xmHkcSnVpBRTs0kEROdw36loJ30QIRg6NRhDhptpKEv/ x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:CH2PR10MB4344.namprd10.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(6506007)(36756003)(38070700005)(71200400001)(2906002)(2616005)(4326008)(8676002)(508600001)(6512007)(110136005)(316002)(966005)(53546011)(186003)(66476007)(38100700002)(66946007)(76116006)(91956017)(83380400001)(44832011)(66446008)(64756008)(66556008)(5660300002)(86362001)(8936002)(122000001)(33656002)(6486002)(45980500001); DIR:OUT; SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?utf-8?q?MITey0E8EsDPh4qHHHcNTkWKA6CI?= =?utf-8?q?VtZ08EQ2kaz7cftaQf6GAzBTvEadwTaCZGs+kPZwuDKJB8eOKvRX34K0aXVyR/+zq?= =?utf-8?q?NxDlT+nsFkcICtIXiFXIKoJDPm149mSWHIf1gY3HQw+2J0XsimD9XBrZnQLuONWwM?= =?utf-8?q?EqskKvulQvMWkmez9+c32+pfnSYbYO/fiO4qtx9BOKKsdxQg/Z2lU6GpJiVPZwKhb?= =?utf-8?q?20GIjssjlQBwFRh4t3sYhwrIGEqMUxMRhJ20cYRW+gubRi+2jLn/xIsqEkOSN3ig+?= =?utf-8?q?xd+IUvM4gWJdhW3bRHwRGkeA+r8qExWeh9y2DhNzI21N6uISWMvruDp1WBhkhrpt0?= =?utf-8?q?iI2pyMQ3AqOOxDidVVGDrydph72/7QdKT2rK8sHN5qaaPGZCGkirhBa3Xs0hwCg1Q?= =?utf-8?q?HtT6bOoJO6WB6csf9FUkKDbv7Y6TanEIAU/M0IZtOICzFPlTPrJcrV0rBbIhqy6WJ?= =?utf-8?q?gPoqVRvgC7Uc+MEbU64k1C4jBF4KM4Ib6Bm4OtgoW4SO6LqBDk8TK6UToqTzxKxhR?= =?utf-8?q?nrsBQzId0BVtI0SO0QwnoCEFgKBVnp+sHE1Xrq3szMelGadJMo+XD8SXENWRqCKHZ?= =?utf-8?q?W1/ZAjnXml9fsWzLz7OILfCk2Nos+IhScbopcPTm93JL3akwMQUUK57YN/MBcv20+?= =?utf-8?q?ygBbf9vjvLccE8GfdR58PVi/Jtq1HG+t1cOE33p4bqFwVjajvdlxdI4P3YmyGCNX8?= =?utf-8?q?L638xfc2ACDGg4Ta2kUP3o+BAouYHw0HvzGnTJOlc1TE9m7vRDLdjik2Er3Tt8RNW?= =?utf-8?q?VAJwxio+KSVsUHWRIz8sRDxcDeRsFbKN3krEucclX5jlSKkx5XgvrCQmProWvKvb5?= =?utf-8?q?E8GusRNKu3icWQMlwSA9eHQfWzuFaMXiIWLtD2UkmDRZTrTyul+aitsaesnB7+X3j?= =?utf-8?q?4WwlFJkc61GUm2DKO84iLloq6jCuYJNhVJvLgUhFjTOcIbTYkNOEe4/FaQlZNgvpK?= =?utf-8?q?LNMQpZTKwDnNKe5Opc98V+Wv+MYR0Vq+4abgtKeMxfoqIQjktSsZJjWo0CMP6fHDP?= =?utf-8?q?Ac+KXxRdo9oTxNK3FBXkrzeFx/13kvfHKanOIWot0+mOoi6p7khvqdPYoHzb3lLrT?= =?utf-8?q?Ej1nX6eGkqsPG94lgymzOKZzv+NlI243pibOjjp1fiXkvrUyV3VPRJbf7uO0hWd2O?= =?utf-8?q?niGofSL/AVJdfGlNoUw1VtL5KAkt5XpWMQpFK3YuoPJgqVcjDVn+k9ZaMhUay1cr7?= =?utf-8?q?3MQlF4T44DfGNcqUq9+KALp4XVotpTYexk3ArzJ7FbwLWHFzlDxrRiaeLbftvBEX/?= =?utf-8?q?yxVxJe4PQyW1OIS+QIY8nQmkKN0yeupJ8PMOsQ2y6rgGprHroUUYP7ByXEo=3D?= x-ms-exchange-transport-forked: True Content-Type: text/plain; charset="utf-8" Content-ID: <45547595AF84A04ABF72790BF7EBD1E8@namprd10.prod.outlook.com> Content-Transfer-Encoding: base64 MIME-Version: 1.0 X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CH2PR10MB4344.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8b8cb247-a331-462a-41e0-08d983904ae9 X-MS-Exchange-CrossTenant-originalarrivaltime: 29 Sep 2021 21:30:00.3890 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: ckwQDK0CySWqWGvV5fusA7tFtAnE7NS6Sya2itOfUGPPdInh8rNZEqf5aaQIovtmhlX769BZUqPYpQuJw0KqoQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH2PR10MB3813 X-Proofpoint-Virus-Version: vendor=nai engine=6300 definitions=10122 signatures=668683 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 suspectscore=0 spamscore=0 adultscore=0 bulkscore=0 mlxscore=0 malwarescore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2109230001 definitions=main-2109290126 X-Proofpoint-GUID: tEApycSHOVBE9C5thganbVtsyPVCsATB X-Proofpoint-ORIG-GUID: tEApycSHOVBE9C5thganbVtsyPVCsATB X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 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> From: Qing Zhao via Gcc-patches <gcc-patches@gcc.gnu.org> Reply-To: Qing Zhao <qing.zhao@oracle.com> Cc: gcc-patches Nick Alcock via <gcc-patches@gcc.gnu.org> Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> |
Series |
[RFC,middle-end/PR102359] Not add initialization for READONLY variables with -ftrivial-auto-var-init
|
|
Commit Message
Qing Zhao
Sept. 29, 2021, 9:30 p.m. UTC
Hi,
PR102359 (ICE gimplification failed since r12-3433-ga25e0b5e6ac8a77a)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359
Is due to -ftrivial-auto-var-init adding initialization for READONLY variable “this” in the following routine: (t.cpp.005t.original)
=======
;; Function A::foo()::<lambda()> (null)
;; enabled by -tree-original
{
const struct A * const this [value-expr: &__closure->__this];
const struct A * const this [value-expr: &__closure->__this];
return <retval> = (double) ((const struct A *) this)->a;
}
=======
However, in the above routine, “this” is NOT marked as READONLY, but its value-expr "&__closure->__this” is marked as READONLY.
There are two major issues:
1. In the routine “is_var_need_auto_init”, we should exclude “decl” that is marked as READONLY;
2. In the C++ FE, “this” should be marked as READONLY.
The idea solution will be:
1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl);
2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true;
Not sure whether it’s hard for C++ FE to fix the 2nd issue or not?
In the case it’s not a quick fix in C++FE, I proposed the following fix in middle end:
Let me know your comments or suggestions on this.
Thanks a lot for the help.
Qing
==============================
From 0a5982cd61bc4610655d3df00ae8d2fbcb3c8e9b Mon Sep 17 00:00:00 2001
From: Qing Zhao <qing.zhao@oracle.com>
Date: Wed, 29 Sep 2021 20:49:59 +0000
Subject: [PATCH] Fix PR102359
---
gcc/gimplify.c | 15 +++++++++++++++
gcc/testsuite/g++.dg/pr102359.C | 13 +++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/pr102359.C
Comments
On 9/29/21 17:30, Qing Zhao wrote: > Hi, > > PR102359 (ICE gimplification failed since r12-3433-ga25e0b5e6ac8a77a) > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359 > > Is due to -ftrivial-auto-var-init adding initialization for READONLY variable “this” in the following routine: (t.cpp.005t.original) > > ======= > > ;; Function A::foo()::<lambda()> (null) > ;; enabled by -tree-original > > { > const struct A * const this [value-expr: &__closure->__this]; > const struct A * const this [value-expr: &__closure->__this]; > return <retval> = (double) ((const struct A *) this)->a; > } > ======= > > However, in the above routine, “this” is NOT marked as READONLY, but its value-expr "&__closure->__this” is marked as READONLY. > > There are two major issues: > > 1. In the routine “is_var_need_auto_init”, we should exclude “decl” that is marked as READONLY; > 2. In the C++ FE, “this” should be marked as READONLY. > > The idea solution will be: > > 1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl); > 2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true; > > Not sure whether it’s hard for C++ FE to fix the 2nd issue or not? > > In the case it’s not a quick fix in C++FE, I proposed the following fix in middle end: > > Let me know your comments or suggestions on this. > > Thanks a lot for the help. I'd think is_var_need_auto_init should be false for any variable with DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of naming objects that are initialized elsewhere. > Qing > > ============================== > From 0a5982cd61bc4610655d3df00ae8d2fbcb3c8e9b Mon Sep 17 00:00:00 2001 > From: Qing Zhao <qing.zhao@oracle.com> > Date: Wed, 29 Sep 2021 20:49:59 +0000 > Subject: [PATCH] Fix PR102359 > > --- > gcc/gimplify.c | 15 +++++++++++++++ > gcc/testsuite/g++.dg/pr102359.C | 13 +++++++++++++ > 2 files changed, 28 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/pr102359.C > > diff --git a/gcc/gimplify.c b/gcc/gimplify.c > index 1067113b1639..a2587869b35d 100644 > --- a/gcc/gimplify.c > +++ b/gcc/gimplify.c > @@ -1819,12 +1819,27 @@ gimple_add_padding_init_for_auto_var (tree decl, bool is_vla, > gimplify_seq_add_stmt (seq_p, call); > } > > +/* Return true if the DECL is READONLY. > + This is to workaround a C++ FE bug that only mark the value_expr of "this" > + as readonly but does not mark "this" as readonly. > + C++ FE should fix this issue before replacing this routine with > + TREE_READONLY (decl). */ > + > +static bool > +is_decl_readonly (tree decl) > +{ > + return (TREE_READONLY (decl) > + || (DECL_HAS_VALUE_EXPR_P (decl) > + && TREE_READONLY (DECL_VALUE_EXPR (decl)))); > +} > + > /* Return true if the DECL need to be automaticly initialized by the > compiler. */ > static bool > is_var_need_auto_init (tree decl) > { > if (auto_var_p (decl) > + && !is_decl_readonly (decl) > && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED) > && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))) > && !is_empty_type (TREE_TYPE (decl))) > diff --git a/gcc/testsuite/g++.dg/pr102359.C b/gcc/testsuite/g++.dg/pr102359.C > new file mode 100644 > index 000000000000..da643cde7bed > --- /dev/null > +++ b/gcc/testsuite/g++.dg/pr102359.C > @@ -0,0 +1,13 @@ > +/* PR middle-end/102359 ICE gimplification failed since > + r12-3433-ga25e0b5e6ac8a77a. */ > +/* { dg-do compile } */ > +/* { dg-options "-ftrivial-auto-var-init=zero" } */ > +/* { dg-require-effective-target c++17 } */ > + > +struct A { > + double a = 111; > + auto foo() { > + return [*this] { return a; }; > + } > +}; > +int X = A{}.foo()(); >
On Thu, 30 Sep 2021, Jason Merrill wrote: > On 9/29/21 17:30, Qing Zhao wrote: > > Hi, > > > > PR102359 (ICE gimplification failed since r12-3433-ga25e0b5e6ac8a77a) > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359 > > > > Is due to -ftrivial-auto-var-init adding initialization for READONLY > > variable “this” in the following routine: (t.cpp.005t.original) > > > > ======= > > > > ;; Function A::foo()::<lambda()> (null) > > ;; enabled by -tree-original > > > > { > > const struct A * const this [value-expr: &__closure->__this]; > > const struct A * const this [value-expr: &__closure->__this]; > > return <retval> = (double) ((const struct A *) this)->a; > > } > > ======= > > > > However, in the above routine, “this” is NOT marked as READONLY, but its > > value-expr "&__closure->__this” is marked as READONLY. > > > > There are two major issues: > > > > 1. In the routine “is_var_need_auto_init”, we should exclude “decl” that is > > marked as READONLY; > > 2. In the C++ FE, “this” should be marked as READONLY. > > > > The idea solution will be: > > > > 1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl); > > 2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true; > > > > Not sure whether it’s hard for C++ FE to fix the 2nd issue or not? > > > > In the case it’s not a quick fix in C++FE, I proposed the following fix in > > middle end: > > > > Let me know your comments or suggestions on this. > > > > Thanks a lot for the help. > > I'd think is_var_need_auto_init should be false for any variable with > DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of naming > objects that are initialized elsewhere. IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to auto-init VLAs, otherwise I tend to agree - would we handle those when we see a DECL_EXPR then? > > > Qing > > > > ============================== > > From 0a5982cd61bc4610655d3df00ae8d2fbcb3c8e9b Mon Sep 17 00:00:00 2001 > > From: Qing Zhao <qing.zhao@oracle.com> > > Date: Wed, 29 Sep 2021 20:49:59 +0000 > > Subject: [PATCH] Fix PR102359 > > > > --- > > gcc/gimplify.c | 15 +++++++++++++++ > > gcc/testsuite/g++.dg/pr102359.C | 13 +++++++++++++ > > 2 files changed, 28 insertions(+) > > create mode 100644 gcc/testsuite/g++.dg/pr102359.C > > > > diff --git a/gcc/gimplify.c b/gcc/gimplify.c > > index 1067113b1639..a2587869b35d 100644 > > --- a/gcc/gimplify.c > > +++ b/gcc/gimplify.c > > @@ -1819,12 +1819,27 @@ gimple_add_padding_init_for_auto_var (tree decl, > > bool is_vla, > > gimplify_seq_add_stmt (seq_p, call); > > } > > > > +/* Return true if the DECL is READONLY. > > + This is to workaround a C++ FE bug that only mark the value_expr of > > "this" > > + as readonly but does not mark "this" as readonly. > > + C++ FE should fix this issue before replacing this routine with > > + TREE_READONLY (decl). */ > > + > > +static bool > > +is_decl_readonly (tree decl) > > +{ > > + return (TREE_READONLY (decl) > > + || (DECL_HAS_VALUE_EXPR_P (decl) > > + && TREE_READONLY (DECL_VALUE_EXPR (decl)))); > > +} > > + > > /* Return true if the DECL need to be automaticly initialized by the > > compiler. */ > > static bool > > is_var_need_auto_init (tree decl) > > { > > if (auto_var_p (decl) > > + && !is_decl_readonly (decl) > > && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED) > > && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))) > > && !is_empty_type (TREE_TYPE (decl))) > > diff --git a/gcc/testsuite/g++.dg/pr102359.C > > b/gcc/testsuite/g++.dg/pr102359.C > > new file mode 100644 > > index 000000000000..da643cde7bed > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/pr102359.C > > @@ -0,0 +1,13 @@ > > +/* PR middle-end/102359 ICE gimplification failed since > > + r12-3433-ga25e0b5e6ac8a77a. */ > > +/* { dg-do compile } */ > > +/* { dg-options "-ftrivial-auto-var-init=zero" } */ > > +/* { dg-require-effective-target c++17 } */ > > + > > +struct A { > > + double a = 111; > > + auto foo() { > > + return [*this] { return a; }; > > + } > > +}; > > +int X = A{}.foo()(); > > > >
> On Sep 30, 2021, at 1:54 AM, Richard Biener <rguenther@suse.de> wrote: > > On Thu, 30 Sep 2021, Jason Merrill wrote: > >> On 9/29/21 17:30, Qing Zhao wrote: >>> Hi, >>> >>> PR102359 (ICE gimplification failed since r12-3433-ga25e0b5e6ac8a77a) >>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359 >>> >>> Is due to -ftrivial-auto-var-init adding initialization for READONLY >>> variable “this” in the following routine: (t.cpp.005t.original) >>> >>> ======= >>> >>> ;; Function A::foo()::<lambda()> (null) >>> ;; enabled by -tree-original >>> >>> { >>> const struct A * const this [value-expr: &__closure->__this]; >>> const struct A * const this [value-expr: &__closure->__this]; >>> return <retval> = (double) ((const struct A *) this)->a; >>> } >>> ======= >>> >>> However, in the above routine, “this” is NOT marked as READONLY, but its >>> value-expr "&__closure->__this” is marked as READONLY. >>> >>> There are two major issues: >>> >>> 1. In the routine “is_var_need_auto_init”, we should exclude “decl” that is >>> marked as READONLY; >>> 2. In the C++ FE, “this” should be marked as READONLY. >>> >>> The idea solution will be: >>> >>> 1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl); >>> 2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true; >>> >>> Not sure whether it’s hard for C++ FE to fix the 2nd issue or not? >>> >>> In the case it’s not a quick fix in C++FE, I proposed the following fix in >>> middle end: >>> >>> Let me know your comments or suggestions on this. >>> >>> Thanks a lot for the help. >> >> I'd think is_var_need_auto_init should be false for any variable with >> DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of naming >> objects that are initialized elsewhere. > > IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to > auto-init VLAs, Yes, that’s correct. i.e, when adding call to .DEFFERED_INIT to auto variables, DECL for a VLA already has a DECL_VALUE_EXPR. > otherwise I tend to agree - would we handle those > when we see a DECL_EXPR then? You mean, for VLA DECL? YES, we added a call to .DEFFERED_INIT for VLA DECL right now. Qing > >> >>> Qing >>> >>> ============================== >>> From 0a5982cd61bc4610655d3df00ae8d2fbcb3c8e9b Mon Sep 17 00:00:00 2001 >>> From: Qing Zhao <qing.zhao@oracle.com> >>> Date: Wed, 29 Sep 2021 20:49:59 +0000 >>> Subject: [PATCH] Fix PR102359 >>> >>> --- >>> gcc/gimplify.c | 15 +++++++++++++++ >>> gcc/testsuite/g++.dg/pr102359.C | 13 +++++++++++++ >>> 2 files changed, 28 insertions(+) >>> create mode 100644 gcc/testsuite/g++.dg/pr102359.C >>> >>> diff --git a/gcc/gimplify.c b/gcc/gimplify.c >>> index 1067113b1639..a2587869b35d 100644 >>> --- a/gcc/gimplify.c >>> +++ b/gcc/gimplify.c >>> @@ -1819,12 +1819,27 @@ gimple_add_padding_init_for_auto_var (tree decl, >>> bool is_vla, >>> gimplify_seq_add_stmt (seq_p, call); >>> } >>> >>> +/* Return true if the DECL is READONLY. >>> + This is to workaround a C++ FE bug that only mark the value_expr of >>> "this" >>> + as readonly but does not mark "this" as readonly. >>> + C++ FE should fix this issue before replacing this routine with >>> + TREE_READONLY (decl). */ >>> + >>> +static bool >>> +is_decl_readonly (tree decl) >>> +{ >>> + return (TREE_READONLY (decl) >>> + || (DECL_HAS_VALUE_EXPR_P (decl) >>> + && TREE_READONLY (DECL_VALUE_EXPR (decl)))); >>> +} >>> + >>> /* Return true if the DECL need to be automaticly initialized by the >>> compiler. */ >>> static bool >>> is_var_need_auto_init (tree decl) >>> { >>> if (auto_var_p (decl) >>> + && !is_decl_readonly (decl) >>> && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED) >>> && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))) >>> && !is_empty_type (TREE_TYPE (decl))) >>> diff --git a/gcc/testsuite/g++.dg/pr102359.C >>> b/gcc/testsuite/g++.dg/pr102359.C >>> new file mode 100644 >>> index 000000000000..da643cde7bed >>> --- /dev/null >>> +++ b/gcc/testsuite/g++.dg/pr102359.C >>> @@ -0,0 +1,13 @@ >>> +/* PR middle-end/102359 ICE gimplification failed since >>> + r12-3433-ga25e0b5e6ac8a77a. */ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-ftrivial-auto-var-init=zero" } */ >>> +/* { dg-require-effective-target c++17 } */ >>> + >>> +struct A { >>> + double a = 111; >>> + auto foo() { >>> + return [*this] { return a; }; >>> + } >>> +}; >>> +int X = A{}.foo()(); >>> >> >> > > -- > Richard Biener <rguenther@suse.de> > SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, > Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)
> On Sep 30, 2021, at 1:54 AM, Richard Biener <rguenther@suse.de> wrote: > > On Thu, 30 Sep 2021, Jason Merrill wrote: > >> On 9/29/21 17:30, Qing Zhao wrote: >>> Hi, >>> >>> PR102359 (ICE gimplification failed since r12-3433-ga25e0b5e6ac8a77a) >>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359 >>> >>> Is due to -ftrivial-auto-var-init adding initialization for READONLY >>> variable “this” in the following routine: (t.cpp.005t.original) >>> >>> ======= >>> >>> ;; Function A::foo()::<lambda()> (null) >>> ;; enabled by -tree-original >>> >>> { >>> const struct A * const this [value-expr: &__closure->__this]; >>> const struct A * const this [value-expr: &__closure->__this]; >>> return <retval> = (double) ((const struct A *) this)->a; >>> } >>> ======= >>> >>> However, in the above routine, “this” is NOT marked as READONLY, but its >>> value-expr "&__closure->__this” is marked as READONLY. >>> >>> There are two major issues: >>> >>> 1. In the routine “is_var_need_auto_init”, we should exclude “decl” that is >>> marked as READONLY; >>> 2. In the C++ FE, “this” should be marked as READONLY. >>> >>> The idea solution will be: >>> >>> 1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl); >>> 2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true; >>> >>> Not sure whether it’s hard for C++ FE to fix the 2nd issue or not? >>> >>> In the case it’s not a quick fix in C++FE, I proposed the following fix in >>> middle end: >>> >>> Let me know your comments or suggestions on this. >>> >>> Thanks a lot for the help. >> >> I'd think is_var_need_auto_init should be false for any variable with >> DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of naming >> objects that are initialized elsewhere. > > IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to > auto-init VLAs, otherwise I tend to agree - would we handle those > when we see a DECL_EXPR then? The current implementation is: gimplify_decl_expr: For each DECL_EXPR “decl” If (VAR_P (decl) && !DECL_EXTERNAL (decl)) { if (is_vla (decl)) gimplify_vla_decl (decl, …); /* existing handling: create a VALUE_EXPR for this vla decl*/ … if (has_explicit_init (decl)) { …; /* existing handling. */ } else if (is_var_need_auto_init (decl)) /*. New code. */ { gimple_add_init_for_auto_var (….); /* new code. */ ... } } Since the “DECL_VALUE_EXPR (decl)” is NOT a DECL_EXPR, it will not be scanned and added initialization. if we do not add initialization for a decl that has DECL_VALUE_EXPR, then the “DECL_VALUE_EXPR (decl)” will not be added an initialization either. We will miss adding initializations for these decls. So, I think that the current implementation is correct. And if C++ FE will not mark “this” as READONLY, only mark DECL_VALUE_EXPR(this) as READONLY, the proposed fix is correct too. Let me know your opinion on this. Thanks. Qing > >> >>> Qing >>> >>> ============================== >>> From 0a5982cd61bc4610655d3df00ae8d2fbcb3c8e9b Mon Sep 17 00:00:00 2001 >>> From: Qing Zhao <qing.zhao@oracle.com> >>> Date: Wed, 29 Sep 2021 20:49:59 +0000 >>> Subject: [PATCH] Fix PR102359 >>> >>> --- >>> gcc/gimplify.c | 15 +++++++++++++++ >>> gcc/testsuite/g++.dg/pr102359.C | 13 +++++++++++++ >>> 2 files changed, 28 insertions(+) >>> create mode 100644 gcc/testsuite/g++.dg/pr102359.C >>> >>> diff --git a/gcc/gimplify.c b/gcc/gimplify.c >>> index 1067113b1639..a2587869b35d 100644 >>> --- a/gcc/gimplify.c >>> +++ b/gcc/gimplify.c >>> @@ -1819,12 +1819,27 @@ gimple_add_padding_init_for_auto_var (tree decl, >>> bool is_vla, >>> gimplify_seq_add_stmt (seq_p, call); >>> } >>> >>> +/* Return true if the DECL is READONLY. >>> + This is to workaround a C++ FE bug that only mark the value_expr of >>> "this" >>> + as readonly but does not mark "this" as readonly. >>> + C++ FE should fix this issue before replacing this routine with >>> + TREE_READONLY (decl). */ >>> + >>> +static bool >>> +is_decl_readonly (tree decl) >>> +{ >>> + return (TREE_READONLY (decl) >>> + || (DECL_HAS_VALUE_EXPR_P (decl) >>> + && TREE_READONLY (DECL_VALUE_EXPR (decl)))); >>> +} >>> + >>> /* Return true if the DECL need to be automaticly initialized by the >>> compiler. */ >>> static bool >>> is_var_need_auto_init (tree decl) >>> { >>> if (auto_var_p (decl) >>> + && !is_decl_readonly (decl) >>> && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED) >>> && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))) >>> && !is_empty_type (TREE_TYPE (decl))) >>> diff --git a/gcc/testsuite/g++.dg/pr102359.C >>> b/gcc/testsuite/g++.dg/pr102359.C >>> new file mode 100644 >>> index 000000000000..da643cde7bed >>> --- /dev/null >>> +++ b/gcc/testsuite/g++.dg/pr102359.C >>> @@ -0,0 +1,13 @@ >>> +/* PR middle-end/102359 ICE gimplification failed since >>> + r12-3433-ga25e0b5e6ac8a77a. */ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-ftrivial-auto-var-init=zero" } */ >>> +/* { dg-require-effective-target c++17 } */ >>> + >>> +struct A { >>> + double a = 111; >>> + auto foo() { >>> + return [*this] { return a; }; >>> + } >>> +}; >>> +int X = A{}.foo()(); >>> >> >> > > -- > Richard Biener <rguenther@suse.de> > SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, > Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)
On Sep 30, 2021, at 1:54 AM, Richard Biener <rguenther@suse.de> wrote:
On Thu, 30 Sep 2021, Jason Merrill wrote:
On 9/29/21 17:30, Qing Zhao wrote:
Hi,
PR102359 (ICE gimplification failed since r12-3433-ga25e0b5e6ac8a77a)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359
Is due to -ftrivial-auto-var-init adding initialization for READONLY
variable “this” in the following routine: (t.cpp.005t.original)
=======
;; Function A::foo()::<lambda()> (null)
;; enabled by -tree-original
{
const struct A * const this [value-expr: &__closure->__this];
const struct A * const this [value-expr: &__closure->__this];
return <retval> = (double) ((const struct A *) this)->a;
}
=======
However, in the above routine, “this” is NOT marked as READONLY, but its
value-expr "&__closure->__this” is marked as READONLY.
There are two major issues:
1. In the routine “is_var_need_auto_init”, we should exclude “decl” that is
marked as READONLY;
2. In the C++ FE, “this” should be marked as READONLY.
The idea solution will be:
1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl);
2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true;
Not sure whether it’s hard for C++ FE to fix the 2nd issue or not?
In the case it’s not a quick fix in C++FE, I proposed the following fix in
middle end:
Let me know your comments or suggestions on this.
Thanks a lot for the help.
I'd think is_var_need_auto_init should be false for any variable with
DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of naming
objects that are initialized elsewhere.
IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to
auto-init VLAs, otherwise I tend to agree - would we handle those
when we see a DECL_EXPR then?
The current implementation is:
gimplify_decl_expr:
For each DECL_EXPR “decl”
If (VAR_P (decl) && !DECL_EXTERNAL (decl))
{
if (is_vla (decl))
gimplify_vla_decl (decl, …); /* existing handling: create a VALUE_EXPR for this vla decl*/
…
if (has_explicit_init (decl))
{
…; /* existing handling. */
}
else if (is_var_need_auto_init (decl)) /*. New code. */
{
gimple_add_init_for_auto_var (….); /* new code. */
...
}
}
Since the “DECL_VALUE_EXPR (decl)” is NOT a DECL_EXPR, it will not be scanned and added initialization.
if we do not add initialization for a decl that has DECL_VALUE_EXPR, then the “DECL_VALUE_EXPR (decl)” will not be added an initialization either. We will miss adding initializations for these decls.
So, I think that the current implementation is correct.
And if C++ FE will not mark “this” as READONLY, only mark DECL_VALUE_EXPR(this) as READONLY, the proposed fix is correct too.
Let me know your opinion on this.
Thanks.
Qing
Qing
==============================
From 0a5982cd61bc4610655d3df00ae8d2fbcb3c8e9b Mon Sep 17 00:00:00 2001
From: Qing Zhao <qing.zhao@oracle.com>
Date: Wed, 29 Sep 2021 20:49:59 +0000
Subject: [PATCH] Fix PR102359
---
gcc/gimplify.c | 15 +++++++++++++++
gcc/testsuite/g++.dg/pr102359.C | 13 +++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/pr102359.C
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 1067113b1639..a2587869b35d 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1819,12 +1819,27 @@ gimple_add_padding_init_for_auto_var (tree decl,
bool is_vla,
gimplify_seq_add_stmt (seq_p, call);
}
+/* Return true if the DECL is READONLY.
+ This is to workaround a C++ FE bug that only mark the value_expr of
"this"
+ as readonly but does not mark "this" as readonly.
+ C++ FE should fix this issue before replacing this routine with
+ TREE_READONLY (decl). */
+
+static bool
+is_decl_readonly (tree decl)
+{
+ return (TREE_READONLY (decl)
+ || (DECL_HAS_VALUE_EXPR_P (decl)
+ && TREE_READONLY (DECL_VALUE_EXPR (decl))));
+}
+
/* Return true if the DECL need to be automaticly initialized by the
compiler. */
static bool
is_var_need_auto_init (tree decl)
{
if (auto_var_p (decl)
+ && !is_decl_readonly (decl)
&& (flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
&& (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl)))
&& !is_empty_type (TREE_TYPE (decl)))
diff --git a/gcc/testsuite/g++.dg/pr102359.C
b/gcc/testsuite/g++.dg/pr102359.C
new file mode 100644
index 000000000000..da643cde7bed
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr102359.C
@@ -0,0 +1,13 @@
+/* PR middle-end/102359 ICE gimplification failed since
+ r12-3433-ga25e0b5e6ac8a77a. */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+/* { dg-require-effective-target c++17 } */
+
+struct A {
+ double a = 111;
+ auto foo() {
+ return [*this] { return a; };
+ }
+};
+int X = A{}.foo()();
--
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)
On 9/30/21 11:42, Qing Zhao wrote: > > >> On Sep 30, 2021, at 1:54 AM, Richard Biener <rguenther@suse.de> wrote: >> >> On Thu, 30 Sep 2021, Jason Merrill wrote: >> >>> On 9/29/21 17:30, Qing Zhao wrote: >>>> Hi, >>>> >>>> PR102359 (ICE gimplification failed since r12-3433-ga25e0b5e6ac8a77a) >>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359 >>>> >>>> Is due to -ftrivial-auto-var-init adding initialization for READONLY >>>> variable “this” in the following routine: (t.cpp.005t.original) >>>> >>>> ======= >>>> >>>> ;; Function A::foo()::<lambda()> (null) >>>> ;; enabled by -tree-original >>>> >>>> { >>>> const struct A * const this [value-expr: &__closure->__this]; >>>> const struct A * const this [value-expr: &__closure->__this]; >>>> return <retval> = (double) ((const struct A *) this)->a; >>>> } >>>> ======= >>>> >>>> However, in the above routine, “this” is NOT marked as READONLY, but its >>>> value-expr "&__closure->__this” is marked as READONLY. >>>> >>>> There are two major issues: >>>> >>>> 1. In the routine “is_var_need_auto_init”, we should exclude “decl” that is >>>> marked as READONLY; >>>> 2. In the C++ FE, “this” should be marked as READONLY. >>>> >>>> The idea solution will be: >>>> >>>> 1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl); >>>> 2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true; >>>> >>>> Not sure whether it’s hard for C++ FE to fix the 2nd issue or not? >>>> >>>> In the case it’s not a quick fix in C++FE, I proposed the following fix in >>>> middle end: >>>> >>>> Let me know your comments or suggestions on this. >>>> >>>> Thanks a lot for the help. >>> >>> I'd think is_var_need_auto_init should be false for any variable with >>> DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of naming >>> objects that are initialized elsewhere. >> >> IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to >> auto-init VLAs, otherwise I tend to agree - would we handle those >> when we see a DECL_EXPR then? > > The current implementation is: > > > gimplify_decl_expr: > > > For each DECL_EXPR “decl” > > If (VAR_P (decl) && !DECL_EXTERNAL (decl)) > { > if (is_vla (decl)) > gimplify_vla_decl (decl, …); /* existing handling: create a VALUE_EXPR for this vla decl*/ > > … > if (has_explicit_init (decl)) > { > …; /* existing handling. */ > } > else if (is_var_need_auto_init (decl)) /*. New code. */ > { > gimple_add_init_for_auto_var (….); /* new code. */ > ... > } > } > > > Since the “DECL_VALUE_EXPR (decl)” is NOT a DECL_EXPR, it will not be scanned and added initialization. > > if we do not add initialization for a decl that has DECL_VALUE_EXPR, then the “DECL_VALUE_EXPR (decl)” will not be added an initialization either. We will miss adding initializations for these decls. > > So, I think that the current implementation is correct. > > And if C++ FE will not mark “this” as READONLY, only mark DECL_VALUE_EXPR(this) as READONLY, the proposed fix is correct too. > > Let me know your opinion on this. The problem with this test is not whether the 'this' proxy is marked READONLY, the problem is that you're trying to initialize lambda capture proxies at all; the lambda capture objects were already initialized when forming the closure object. So this test currently aborts with -ftrivial-auto-var-init=zero because you "initialize" the i capture field to 0 after it was previously initialized to 42: int main() { int i = 42; auto l = [=]() mutable { return i; }; if (l() != i) __builtin_abort (); } I believe the same issue applies to the proxy variables in coroutines that work much like lambdas. You can't just assume that a VAR_DECL with DECL_VALUE_EXPR is uninitialized. Since there's already VLA handling in gimplify_decl_expr, you could remember whether you added DECL_VALUE_EXPR in that function, and only then do the initialization. Jason
> On Sep 30, 2021, at 2:31 PM, Jason Merrill <jason@redhat.com> wrote: > > On 9/30/21 11:42, Qing Zhao wrote: >>> On Sep 30, 2021, at 1:54 AM, Richard Biener <rguenther@suse.de> wrote: >>> >>> On Thu, 30 Sep 2021, Jason Merrill wrote: >>> >>>> On 9/29/21 17:30, Qing Zhao wrote: >>>>> Hi, >>>>> >>>>> PR102359 (ICE gimplification failed since r12-3433-ga25e0b5e6ac8a77a) >>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359 >>>>> >>>>> Is due to -ftrivial-auto-var-init adding initialization for READONLY >>>>> variable “this” in the following routine: (t.cpp.005t.original) >>>>> >>>>> ======= >>>>> >>>>> ;; Function A::foo()::<lambda()> (null) >>>>> ;; enabled by -tree-original >>>>> >>>>> { >>>>> const struct A * const this [value-expr: &__closure->__this]; >>>>> const struct A * const this [value-expr: &__closure->__this]; >>>>> return <retval> = (double) ((const struct A *) this)->a; >>>>> } >>>>> ======= >>>>> >>>>> However, in the above routine, “this” is NOT marked as READONLY, but its >>>>> value-expr "&__closure->__this” is marked as READONLY. >>>>> >>>>> There are two major issues: >>>>> >>>>> 1. In the routine “is_var_need_auto_init”, we should exclude “decl” that is >>>>> marked as READONLY; >>>>> 2. In the C++ FE, “this” should be marked as READONLY. >>>>> >>>>> The idea solution will be: >>>>> >>>>> 1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl); >>>>> 2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true; >>>>> >>>>> Not sure whether it’s hard for C++ FE to fix the 2nd issue or not? >>>>> >>>>> In the case it’s not a quick fix in C++FE, I proposed the following fix in >>>>> middle end: >>>>> >>>>> Let me know your comments or suggestions on this. >>>>> >>>>> Thanks a lot for the help. >>>> >>>> I'd think is_var_need_auto_init should be false for any variable with >>>> DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of naming >>>> objects that are initialized elsewhere. >>> >>> IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to >>> auto-init VLAs, otherwise I tend to agree - would we handle those >>> when we see a DECL_EXPR then? >> The current implementation is: >> gimplify_decl_expr: >> For each DECL_EXPR “decl” >> If (VAR_P (decl) && !DECL_EXTERNAL (decl)) >> { >> if (is_vla (decl)) >> gimplify_vla_decl (decl, …); /* existing handling: create a VALUE_EXPR for this vla decl*/ >> … >> if (has_explicit_init (decl)) >> { >> …; /* existing handling. */ >> } >> else if (is_var_need_auto_init (decl)) /*. New code. */ >> { >> gimple_add_init_for_auto_var (….); /* new code. */ >> ... >> } >> } >> Since the “DECL_VALUE_EXPR (decl)” is NOT a DECL_EXPR, it will not be scanned and added initialization. >> if we do not add initialization for a decl that has DECL_VALUE_EXPR, then the “DECL_VALUE_EXPR (decl)” will not be added an initialization either. We will miss adding initializations for these decls. >> So, I think that the current implementation is correct. >> And if C++ FE will not mark “this” as READONLY, only mark DECL_VALUE_EXPR(this) as READONLY, the proposed fix is correct too. >> Let me know your opinion on this. > > The problem with this test is not whether the 'this' proxy is marked READONLY, the problem is that you're trying to initialize lambda capture proxies at all; the lambda capture objects were already initialized when forming the closure object. So this test currently aborts with -ftrivial-auto-var-init=zero because you "initialize" the i capture field to 0 after it was previously initialized to 42: > > int main() > { > int i = 42; > auto l = [=]() mutable { return i; }; > if (l() != i) > __builtin_abort (); > } > > I believe the same issue applies to the proxy variables in coroutines that work much like lambdas. So, how should the middle end determine that a variable is “proxy variable”? Have all “proxy variables” been initialized by C++ FE already? > > You can't just assume that a VAR_DECL with DECL_VALUE_EXPR is uninitialized. So, all the VAR_DECLs with DECL_VALUE_EXPR (except the ones created by “gimplify_decl_expr”) are initialized by FE already? > > Since there's already VLA handling in gimplify_decl_expr, you could remember whether you added DECL_VALUE_EXPR in that function, and only then do the initialization. Yes, if we can guarantee that all the VAR_DECLs with DECL_VALUE_EXPR created from FEs have been initialized already by FE, we can fix this issue as this way. thanks. Qing > > Jason >
On 10/1/21 10:54, Qing Zhao wrote: > > >> On Sep 30, 2021, at 2:31 PM, Jason Merrill <jason@redhat.com> wrote: >> >> On 9/30/21 11:42, Qing Zhao wrote: >>>> On Sep 30, 2021, at 1:54 AM, Richard Biener <rguenther@suse.de> wrote: >>>> >>>> On Thu, 30 Sep 2021, Jason Merrill wrote: >>>> >>>>> On 9/29/21 17:30, Qing Zhao wrote: >>>>>> Hi, >>>>>> >>>>>> PR102359 (ICE gimplification failed since r12-3433-ga25e0b5e6ac8a77a) >>>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359 >>>>>> >>>>>> Is due to -ftrivial-auto-var-init adding initialization for READONLY >>>>>> variable “this” in the following routine: (t.cpp.005t.original) >>>>>> >>>>>> ======= >>>>>> >>>>>> ;; Function A::foo()::<lambda()> (null) >>>>>> ;; enabled by -tree-original >>>>>> >>>>>> { >>>>>> const struct A * const this [value-expr: &__closure->__this]; >>>>>> const struct A * const this [value-expr: &__closure->__this]; >>>>>> return <retval> = (double) ((const struct A *) this)->a; >>>>>> } >>>>>> ======= >>>>>> >>>>>> However, in the above routine, “this” is NOT marked as READONLY, but its >>>>>> value-expr "&__closure->__this” is marked as READONLY. >>>>>> >>>>>> There are two major issues: >>>>>> >>>>>> 1. In the routine “is_var_need_auto_init”, we should exclude “decl” that is >>>>>> marked as READONLY; >>>>>> 2. In the C++ FE, “this” should be marked as READONLY. >>>>>> >>>>>> The idea solution will be: >>>>>> >>>>>> 1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl); >>>>>> 2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true; >>>>>> >>>>>> Not sure whether it’s hard for C++ FE to fix the 2nd issue or not? >>>>>> >>>>>> In the case it’s not a quick fix in C++FE, I proposed the following fix in >>>>>> middle end: >>>>>> >>>>>> Let me know your comments or suggestions on this. >>>>>> >>>>>> Thanks a lot for the help. >>>>> >>>>> I'd think is_var_need_auto_init should be false for any variable with >>>>> DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of naming >>>>> objects that are initialized elsewhere. >>>> >>>> IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to >>>> auto-init VLAs, otherwise I tend to agree - would we handle those >>>> when we see a DECL_EXPR then? >>> The current implementation is: >>> gimplify_decl_expr: >>> For each DECL_EXPR “decl” >>> If (VAR_P (decl) && !DECL_EXTERNAL (decl)) >>> { >>> if (is_vla (decl)) >>> gimplify_vla_decl (decl, …); /* existing handling: create a VALUE_EXPR for this vla decl*/ >>> … >>> if (has_explicit_init (decl)) >>> { >>> …; /* existing handling. */ >>> } >>> else if (is_var_need_auto_init (decl)) /*. New code. */ >>> { >>> gimple_add_init_for_auto_var (….); /* new code. */ >>> ... >>> } >>> } >>> Since the “DECL_VALUE_EXPR (decl)” is NOT a DECL_EXPR, it will not be scanned and added initialization. >>> if we do not add initialization for a decl that has DECL_VALUE_EXPR, then the “DECL_VALUE_EXPR (decl)” will not be added an initialization either. We will miss adding initializations for these decls. >>> So, I think that the current implementation is correct. >>> And if C++ FE will not mark “this” as READONLY, only mark DECL_VALUE_EXPR(this) as READONLY, the proposed fix is correct too. >>> Let me know your opinion on this. >> >> The problem with this test is not whether the 'this' proxy is marked READONLY, the problem is that you're trying to initialize lambda capture proxies at all; the lambda capture objects were already initialized when forming the closure object. So this test currently aborts with -ftrivial-auto-var-init=zero because you "initialize" the i capture field to 0 after it was previously initialized to 42: >> >> int main() >> { >> int i = 42; >> auto l = [=]() mutable { return i; }; >> if (l() != i) >> __builtin_abort (); >> } >> >> I believe the same issue applies to the proxy variables in coroutines that work much like lambdas. > So, how should the middle end determine that a variable is “proxy variable”? In the front end, is_capture_proxy will identify a lambda capture proxy variable. But that won't be true for the similar proxies used by coroutines. > Have all “proxy variables” been initialized by C++ FE already? Yes. >> You can't just assume that a VAR_DECL with DECL_VALUE_EXPR is uninitialized. > > So, all the VAR_DECLs with DECL_VALUE_EXPR (except the ones created by “gimplify_decl_expr”) are initialized by FE already? In general I'd expect them to refer to previously created objects which may or may not have been initialized, but if they haven't been, the place to deal with that is at their previous creation. >> Since there's already VLA handling in gimplify_decl_expr, you could remember whether you added DECL_VALUE_EXPR in that function, and only then do the initialization. > > Yes, if we can guarantee that all the VAR_DECLs with DECL_VALUE_EXPR created from FEs have been initialized already by FE, we can fix this issue as this way. Or more generally, check whether the argument to gimplify_decl_expr has DECL_VALUE_EXPR when we enter the function, and don't do the initialization in that case. Jason
> On Oct 1, 2021, at 10:33 AM, Jason Merrill <jason@redhat.com> wrote: > > On 10/1/21 10:54, Qing Zhao wrote: >>> On Sep 30, 2021, at 2:31 PM, Jason Merrill <jason@redhat.com> wrote: >>> >>> On 9/30/21 11:42, Qing Zhao wrote: >>>>> On Sep 30, 2021, at 1:54 AM, Richard Biener <rguenther@suse.de> wrote: >>>>> >>>>> On Thu, 30 Sep 2021, Jason Merrill wrote: >>>>> >>>>>> On 9/29/21 17:30, Qing Zhao wrote: >>>>>>> Hi, >>>>>>> >>>>>>> PR102359 (ICE gimplification failed since r12-3433-ga25e0b5e6ac8a77a) >>>>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359 >>>>>>> >>>>>>> Is due to -ftrivial-auto-var-init adding initialization for READONLY >>>>>>> variable “this” in the following routine: (t.cpp.005t.original) >>>>>>> >>>>>>> ======= >>>>>>> >>>>>>> ;; Function A::foo()::<lambda()> (null) >>>>>>> ;; enabled by -tree-original >>>>>>> >>>>>>> { >>>>>>> const struct A * const this [value-expr: &__closure->__this]; >>>>>>> const struct A * const this [value-expr: &__closure->__this]; >>>>>>> return <retval> = (double) ((const struct A *) this)->a; >>>>>>> } >>>>>>> ======= >>>>>>> >>>>>>> However, in the above routine, “this” is NOT marked as READONLY, but its >>>>>>> value-expr "&__closure->__this” is marked as READONLY. >>>>>>> >>>>>>> There are two major issues: >>>>>>> >>>>>>> 1. In the routine “is_var_need_auto_init”, we should exclude “decl” that is >>>>>>> marked as READONLY; >>>>>>> 2. In the C++ FE, “this” should be marked as READONLY. >>>>>>> >>>>>>> The idea solution will be: >>>>>>> >>>>>>> 1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl); >>>>>>> 2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true; >>>>>>> >>>>>>> Not sure whether it’s hard for C++ FE to fix the 2nd issue or not? >>>>>>> >>>>>>> In the case it’s not a quick fix in C++FE, I proposed the following fix in >>>>>>> middle end: >>>>>>> >>>>>>> Let me know your comments or suggestions on this. >>>>>>> >>>>>>> Thanks a lot for the help. >>>>>> >>>>>> I'd think is_var_need_auto_init should be false for any variable with >>>>>> DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of naming >>>>>> objects that are initialized elsewhere. >>>>> >>>>> IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to >>>>> auto-init VLAs, otherwise I tend to agree - would we handle those >>>>> when we see a DECL_EXPR then? >>>> The current implementation is: >>>> gimplify_decl_expr: >>>> For each DECL_EXPR “decl” >>>> If (VAR_P (decl) && !DECL_EXTERNAL (decl)) >>>> { >>>> if (is_vla (decl)) >>>> gimplify_vla_decl (decl, …); /* existing handling: create a VALUE_EXPR for this vla decl*/ >>>> … >>>> if (has_explicit_init (decl)) >>>> { >>>> …; /* existing handling. */ >>>> } >>>> else if (is_var_need_auto_init (decl)) /*. New code. */ >>>> { >>>> gimple_add_init_for_auto_var (….); /* new code. */ >>>> ... >>>> } >>>> } >>>> Since the “DECL_VALUE_EXPR (decl)” is NOT a DECL_EXPR, it will not be scanned and added initialization. >>>> if we do not add initialization for a decl that has DECL_VALUE_EXPR, then the “DECL_VALUE_EXPR (decl)” will not be added an initialization either. We will miss adding initializations for these decls. >>>> So, I think that the current implementation is correct. >>>> And if C++ FE will not mark “this” as READONLY, only mark DECL_VALUE_EXPR(this) as READONLY, the proposed fix is correct too. >>>> Let me know your opinion on this. >>> >>> The problem with this test is not whether the 'this' proxy is marked READONLY, the problem is that you're trying to initialize lambda capture proxies at all; the lambda capture objects were already initialized when forming the closure object. So this test currently aborts with -ftrivial-auto-var-init=zero because you "initialize" the i capture field to 0 after it was previously initialized to 42: >>> >>> int main() >>> { >>> int i = 42; >>> auto l = [=]() mutable { return i; }; >>> if (l() != i) >>> __builtin_abort (); >>> } >>> >>> I believe the same issue applies to the proxy variables in coroutines that work much like lambdas. > >> So, how should the middle end determine that a variable is “proxy variable”? > > In the front end, is_capture_proxy will identify a lambda capture proxy variable. But that won't be true for the similar proxies used by coroutines. Does this mean that in middle end, especially in gimplification phase, there is Not a simple way to determine whether a variable is a proxy variable? > >> Have all “proxy variables” been initialized by C++ FE already? > > Yes. > >>> You can't just assume that a VAR_DECL with DECL_VALUE_EXPR is uninitialized. >> So, all the VAR_DECLs with DECL_VALUE_EXPR (except the ones created by “gimplify_decl_expr”) are initialized by FE already? > > In general I'd expect them to refer to previously created objects which may or may not have been initialized, but if they haven't been, the place to deal with that is at their previous creation. Still a little confuse..., do you mean, even for VAL_DECLS with DECL_VALUE_EXPR that were created by FE, we cannot guarantee they have been initialized? What did you mean by “the place to deal with that is at there previous creation”? > >>> Since there's already VLA handling in gimplify_decl_expr, you could remember whether you added DECL_VALUE_EXPR in that function, and only then do the initialization. >> Yes, if we can guarantee that all the VAR_DECLs with DECL_VALUE_EXPR created from FEs have been initialized already by FE, we can fix this issue as this way. > > Or more generally, check whether the argument to gimplify_decl_expr has DECL_VALUE_EXPR when we enter the function, and don't do the initialization in that case. Yes, we can do that. However, the major thing I need to make sure is: can we guarantee that for All the VAL_DECLS with DECL_VALUE_EXPR created by FE are initialized already? thanks. Qing > > Jason
On Fri, 1 Oct 2021, Qing Zhao wrote: > > > > On Oct 1, 2021, at 10:33 AM, Jason Merrill <jason@redhat.com> wrote: > > > > On 10/1/21 10:54, Qing Zhao wrote: > >>> On Sep 30, 2021, at 2:31 PM, Jason Merrill <jason@redhat.com> wrote: > >>> > >>> On 9/30/21 11:42, Qing Zhao wrote: > >>>>> On Sep 30, 2021, at 1:54 AM, Richard Biener <rguenther@suse.de> wrote: > >>>>> > >>>>> On Thu, 30 Sep 2021, Jason Merrill wrote: > >>>>> > >>>>>> On 9/29/21 17:30, Qing Zhao wrote: > >>>>>>> Hi, > >>>>>>> > >>>>>>> PR102359 (ICE gimplification failed since r12-3433-ga25e0b5e6ac8a77a) > >>>>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359 > >>>>>>> > >>>>>>> Is due to -ftrivial-auto-var-init adding initialization for READONLY > >>>>>>> variable “this” in the following routine: (t.cpp.005t.original) > >>>>>>> > >>>>>>> ======= > >>>>>>> > >>>>>>> ;; Function A::foo()::<lambda()> (null) > >>>>>>> ;; enabled by -tree-original > >>>>>>> > >>>>>>> { > >>>>>>> const struct A * const this [value-expr: &__closure->__this]; > >>>>>>> const struct A * const this [value-expr: &__closure->__this]; > >>>>>>> return <retval> = (double) ((const struct A *) this)->a; > >>>>>>> } > >>>>>>> ======= > >>>>>>> > >>>>>>> However, in the above routine, “this” is NOT marked as READONLY, but its > >>>>>>> value-expr "&__closure->__this” is marked as READONLY. > >>>>>>> > >>>>>>> There are two major issues: > >>>>>>> > >>>>>>> 1. In the routine “is_var_need_auto_init”, we should exclude “decl” that is > >>>>>>> marked as READONLY; > >>>>>>> 2. In the C++ FE, “this” should be marked as READONLY. > >>>>>>> > >>>>>>> The idea solution will be: > >>>>>>> > >>>>>>> 1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl); > >>>>>>> 2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true; > >>>>>>> > >>>>>>> Not sure whether it’s hard for C++ FE to fix the 2nd issue or not? > >>>>>>> > >>>>>>> In the case it’s not a quick fix in C++FE, I proposed the following fix in > >>>>>>> middle end: > >>>>>>> > >>>>>>> Let me know your comments or suggestions on this. > >>>>>>> > >>>>>>> Thanks a lot for the help. > >>>>>> > >>>>>> I'd think is_var_need_auto_init should be false for any variable with > >>>>>> DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of naming > >>>>>> objects that are initialized elsewhere. > >>>>> > >>>>> IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to > >>>>> auto-init VLAs, otherwise I tend to agree - would we handle those > >>>>> when we see a DECL_EXPR then? > >>>> The current implementation is: > >>>> gimplify_decl_expr: > >>>> For each DECL_EXPR “decl” > >>>> If (VAR_P (decl) && !DECL_EXTERNAL (decl)) > >>>> { > >>>> if (is_vla (decl)) > >>>> gimplify_vla_decl (decl, …); /* existing handling: create a VALUE_EXPR for this vla decl*/ > >>>> … > >>>> if (has_explicit_init (decl)) > >>>> { > >>>> …; /* existing handling. */ > >>>> } > >>>> else if (is_var_need_auto_init (decl)) /*. New code. */ > >>>> { > >>>> gimple_add_init_for_auto_var (….); /* new code. */ > >>>> ... > >>>> } > >>>> } > >>>> Since the “DECL_VALUE_EXPR (decl)” is NOT a DECL_EXPR, it will not be scanned and added initialization. > >>>> if we do not add initialization for a decl that has DECL_VALUE_EXPR, then the “DECL_VALUE_EXPR (decl)” will not be added an initialization either. We will miss adding initializations for these decls. > >>>> So, I think that the current implementation is correct. > >>>> And if C++ FE will not mark “this” as READONLY, only mark DECL_VALUE_EXPR(this) as READONLY, the proposed fix is correct too. > >>>> Let me know your opinion on this. > >>> > >>> The problem with this test is not whether the 'this' proxy is marked READONLY, the problem is that you're trying to initialize lambda capture proxies at all; the lambda capture objects were already initialized when forming the closure object. So this test currently aborts with -ftrivial-auto-var-init=zero because you "initialize" the i capture field to 0 after it was previously initialized to 42: > >>> > >>> int main() > >>> { > >>> int i = 42; > >>> auto l = [=]() mutable { return i; }; > >>> if (l() != i) > >>> __builtin_abort (); > >>> } > >>> > >>> I believe the same issue applies to the proxy variables in coroutines that work much like lambdas. > > > >> So, how should the middle end determine that a variable is “proxy variable”? > > > > In the front end, is_capture_proxy will identify a lambda capture proxy variable. But that won't be true for the similar proxies used by coroutines. > > Does this mean that in middle end, especially in gimplification phase, there is Not a simple way to determine whether a variable is a proxy variable? > > > >> Have all “proxy variables” been initialized by C++ FE already? > > > > Yes. > > > >>> You can't just assume that a VAR_DECL with DECL_VALUE_EXPR is uninitialized. > >> So, all the VAR_DECLs with DECL_VALUE_EXPR (except the ones created by “gimplify_decl_expr”) are initialized by FE already? > > > > In general I'd expect them to refer to previously created objects which may or may not have been initialized, but if they haven't been, the place to deal with that is at their previous creation. > > Still a little confuse..., do you mean, even for VAL_DECLS with DECL_VALUE_EXPR that were created by FE, we cannot guarantee they have been initialized? > > What did you mean by “the place to deal with that is at there previous creation”? > > > > > >>> Since there's already VLA handling in gimplify_decl_expr, you could remember whether you added DECL_VALUE_EXPR in that function, and only then do the initialization. > >> Yes, if we can guarantee that all the VAR_DECLs with DECL_VALUE_EXPR created from FEs have been initialized already by FE, we can fix this issue as this way. > > > > Or more generally, check whether the argument to gimplify_decl_expr has DECL_VALUE_EXPR when we enter the function, and don't do the initialization in that case. > > Yes, we can do that. > > However, the major thing I need to make sure is: > > can we guarantee that for All the VAL_DECLS with DECL_VALUE_EXPR created > by FE are initialized already? I think so. Richard.
> On Oct 4, 2021, at 1:44 AM, Richard Biener <rguenther@suse.de> wrote: > > On Fri, 1 Oct 2021, Qing Zhao wrote: > >> >> >>> On Oct 1, 2021, at 10:33 AM, Jason Merrill <jason@redhat.com> wrote: >>> >>> On 10/1/21 10:54, Qing Zhao wrote: >>>>> On Sep 30, 2021, at 2:31 PM, Jason Merrill <jason@redhat.com> wrote: >>>>> >>>>> On 9/30/21 11:42, Qing Zhao wrote: >>>>>>> On Sep 30, 2021, at 1:54 AM, Richard Biener <rguenther@suse.de> wrote: >>>>>>> >>>>>>> On Thu, 30 Sep 2021, Jason Merrill wrote: >>>>>>> >>>>>>>> On 9/29/21 17:30, Qing Zhao wrote: >>>>>>>>> Hi, >>>>>>>>> >>>>>>>>> PR102359 (ICE gimplification failed since r12-3433-ga25e0b5e6ac8a77a) >>>>>>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359 >>>>>>>>> >>>>>>>>> Is due to -ftrivial-auto-var-init adding initialization for READONLY >>>>>>>>> variable “this” in the following routine: (t.cpp.005t.original) >>>>>>>>> >>>>>>>>> ======= >>>>>>>>> >>>>>>>>> ;; Function A::foo()::<lambda()> (null) >>>>>>>>> ;; enabled by -tree-original >>>>>>>>> >>>>>>>>> { >>>>>>>>> const struct A * const this [value-expr: &__closure->__this]; >>>>>>>>> const struct A * const this [value-expr: &__closure->__this]; >>>>>>>>> return <retval> = (double) ((const struct A *) this)->a; >>>>>>>>> } >>>>>>>>> ======= >>>>>>>>> >>>>>>>>> However, in the above routine, “this” is NOT marked as READONLY, but its >>>>>>>>> value-expr "&__closure->__this” is marked as READONLY. >>>>>>>>> >>>>>>>>> There are two major issues: >>>>>>>>> >>>>>>>>> 1. In the routine “is_var_need_auto_init”, we should exclude “decl” that is >>>>>>>>> marked as READONLY; >>>>>>>>> 2. In the C++ FE, “this” should be marked as READONLY. >>>>>>>>> >>>>>>>>> The idea solution will be: >>>>>>>>> >>>>>>>>> 1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl); >>>>>>>>> 2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true; >>>>>>>>> >>>>>>>>> Not sure whether it’s hard for C++ FE to fix the 2nd issue or not? >>>>>>>>> >>>>>>>>> In the case it’s not a quick fix in C++FE, I proposed the following fix in >>>>>>>>> middle end: >>>>>>>>> >>>>>>>>> Let me know your comments or suggestions on this. >>>>>>>>> >>>>>>>>> Thanks a lot for the help. >>>>>>>> >>>>>>>> I'd think is_var_need_auto_init should be false for any variable with >>>>>>>> DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of naming >>>>>>>> objects that are initialized elsewhere. >>>>>>> >>>>>>> IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to >>>>>>> auto-init VLAs, otherwise I tend to agree - would we handle those >>>>>>> when we see a DECL_EXPR then? >>>>>> The current implementation is: >>>>>> gimplify_decl_expr: >>>>>> For each DECL_EXPR “decl” >>>>>> If (VAR_P (decl) && !DECL_EXTERNAL (decl)) >>>>>> { >>>>>> if (is_vla (decl)) >>>>>> gimplify_vla_decl (decl, …); /* existing handling: create a VALUE_EXPR for this vla decl*/ >>>>>> … >>>>>> if (has_explicit_init (decl)) >>>>>> { >>>>>> …; /* existing handling. */ >>>>>> } >>>>>> else if (is_var_need_auto_init (decl)) /*. New code. */ >>>>>> { >>>>>> gimple_add_init_for_auto_var (….); /* new code. */ >>>>>> ... >>>>>> } >>>>>> } >>>>>> Since the “DECL_VALUE_EXPR (decl)” is NOT a DECL_EXPR, it will not be scanned and added initialization. >>>>>> if we do not add initialization for a decl that has DECL_VALUE_EXPR, then the “DECL_VALUE_EXPR (decl)” will not be added an initialization either. We will miss adding initializations for these decls. >>>>>> So, I think that the current implementation is correct. >>>>>> And if C++ FE will not mark “this” as READONLY, only mark DECL_VALUE_EXPR(this) as READONLY, the proposed fix is correct too. >>>>>> Let me know your opinion on this. >>>>> >>>>> The problem with this test is not whether the 'this' proxy is marked READONLY, the problem is that you're trying to initialize lambda capture proxies at all; the lambda capture objects were already initialized when forming the closure object. So this test currently aborts with -ftrivial-auto-var-init=zero because you "initialize" the i capture field to 0 after it was previously initialized to 42: >>>>> >>>>> int main() >>>>> { >>>>> int i = 42; >>>>> auto l = [=]() mutable { return i; }; >>>>> if (l() != i) >>>>> __builtin_abort (); >>>>> } >>>>> >>>>> I believe the same issue applies to the proxy variables in coroutines that work much like lambdas. >>> >>>> So, how should the middle end determine that a variable is “proxy variable”? >>> >>> In the front end, is_capture_proxy will identify a lambda capture proxy variable. But that won't be true for the similar proxies used by coroutines. >> >> Does this mean that in middle end, especially in gimplification phase, there is Not a simple way to determine whether a variable is a proxy variable? >>> >>>> Have all “proxy variables” been initialized by C++ FE already? >>> >>> Yes. >>> >>>>> You can't just assume that a VAR_DECL with DECL_VALUE_EXPR is uninitialized. >>>> So, all the VAR_DECLs with DECL_VALUE_EXPR (except the ones created by “gimplify_decl_expr”) are initialized by FE already? >>> >>> In general I'd expect them to refer to previously created objects which may or may not have been initialized, but if they haven't been, the place to deal with that is at their previous creation. >> >> Still a little confuse..., do you mean, even for VAL_DECLS with DECL_VALUE_EXPR that were created by FE, we cannot guarantee they have been initialized? >> >> What did you mean by “the place to deal with that is at there previous creation”? >> >> >>> >>>>> Since there's already VLA handling in gimplify_decl_expr, you could remember whether you added DECL_VALUE_EXPR in that function, and only then do the initialization. >>>> Yes, if we can guarantee that all the VAR_DECLs with DECL_VALUE_EXPR created from FEs have been initialized already by FE, we can fix this issue as this way. >>> >>> Or more generally, check whether the argument to gimplify_decl_expr has DECL_VALUE_EXPR when we enter the function, and don't do the initialization in that case. >> >> Yes, we can do that. >> >> However, the major thing I need to make sure is: >> >> can we guarantee that for All the VAL_DECLS with DECL_VALUE_EXPR created >> by FE are initialized already? > > I think so. Okay. Will fix this bug based on this. Thanks. Qing > > Richard.
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 1067113b1639..a2587869b35d 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1819,12 +1819,27 @@ gimple_add_padding_init_for_auto_var (tree decl, bool is_vla, gimplify_seq_add_stmt (seq_p, call); } +/* Return true if the DECL is READONLY. + This is to workaround a C++ FE bug that only mark the value_expr of "this" + as readonly but does not mark "this" as readonly. + C++ FE should fix this issue before replacing this routine with + TREE_READONLY (decl). */ + +static bool +is_decl_readonly (tree decl) +{ + return (TREE_READONLY (decl) + || (DECL_HAS_VALUE_EXPR_P (decl) + && TREE_READONLY (DECL_VALUE_EXPR (decl)))); +} + /* Return true if the DECL need to be automaticly initialized by the compiler. */ static bool is_var_need_auto_init (tree decl) { if (auto_var_p (decl) + && !is_decl_readonly (decl) && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED) && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))) && !is_empty_type (TREE_TYPE (decl))) diff --git a/gcc/testsuite/g++.dg/pr102359.C b/gcc/testsuite/g++.dg/pr102359.C new file mode 100644 index 000000000000..da643cde7bed --- /dev/null +++ b/gcc/testsuite/g++.dg/pr102359.C @@ -0,0 +1,13 @@ +/* PR middle-end/102359 ICE gimplification failed since + r12-3433-ga25e0b5e6ac8a77a. */ +/* { dg-do compile } */ +/* { dg-options "-ftrivial-auto-var-init=zero" } */ +/* { dg-require-effective-target c++17 } */ + +struct A { + double a = 111; + auto foo() { + return [*this] { return a; }; + } +}; +int X = A{}.foo()();