From patchwork Tue Jul 19 14:09:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qing Zhao X-Patchwork-Id: 56166 Return-Path: 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 DD1603852763 for ; Tue, 19 Jul 2022 14:10:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DD1603852763 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1658239825; bh=DppieeaFMWNxBMT83iqYi2sRbVA+WzlVS+LltG1xQWw=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=OxgkFBJKOiPRQrKrbj+4c/r0MaU4wqHsoEd4+MZiuIX/SK3ieqyK5yIHQxlj//F/b g/jwNfs1XnQ2mU1q8Ym86Sb1/7EcvbXRuzZHEfYvSv5YC/Kd11eF6+VjQKNHTkvnst kPIw1n2sIRAwK4PWqADNo0q2jPR/UHwHpoQJWB7I= 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 919493858281 for ; Tue, 19 Jul 2022 14:09:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 919493858281 Received: from pps.filterd (m0246631.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 26JDAvWY015096; Tue, 19 Jul 2022 14:09:51 GMT Received: from iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta02.appoci.oracle.com [147.154.18.20]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3hbm42ef8q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 19 Jul 2022 14:09:50 +0000 Received: from pps.filterd (iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.5/8.17.1.5) with ESMTP id 26JBaC5Q002842; Tue, 19 Jul 2022 14:09:50 GMT Received: from nam11-co1-obe.outbound.protection.outlook.com (mail-co1nam11lp2172.outbound.protection.outlook.com [104.47.56.172]) by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3hc1mb5u42-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 19 Jul 2022 14:09:49 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=XAEBCdxJLBylNvx2bmHhH3d8jntGa46Tvi3pVfnE+7SLr7LCy0RoaCR1Lk2J4ZB8bQ4Ic6DwRXT2YwdiAjxWnMktwDjS6PL/gf9mRpHeUq3pU6cicapTYE/Tr0kBZ6L9YBnvPnM15CnEWEFOyvCAEt/QPA2DcxK8wgkivCraIdCOSawUbHtaTLs+2S1ULsWs3/82JFt4rJDokSAc3mgPPIHBS0in6PZn9Ps/gDOQYxHnf/0iolaGXy6HiQBfWLxBfzzID4XwV9ZB9GmJ3qonp9r9TuDs3J3EBZpIEDxZDc1RchE7ZOMjWRqUSEFxO3q6SNAI4IRs16KGYegPPGfM6Q== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=DppieeaFMWNxBMT83iqYi2sRbVA+WzlVS+LltG1xQWw=; b=d8pP0/rEd/YG0/oS/hrMWVULsiZk/rmTW9WJfQPzMpxlUeLS+T/9vdILbxKO8ehjSTKMLRhiA17nEBlj2DGWuVQbt140FlOgT3doxiqbPCoCfK4lQ2QWiYA1jxru9A8sbuKzvEACgJGY8th0IZeFEVMcxgY3ujIXZkQwXu22Stf47m3AlcIyCZUZYMWAc5ifHNqHecBlsF7do60mk8rm0kUjsUZNStihisPlIkpIMdNTvKoTdGemrGgm24YatS+24L+PlkIjplYQQgLsT1T1RnHR7tyYsgBlqE+H4Xv7aSYfDMQILwS1SWEVYsj3hMQYBFTKQCH9Z6h7e5nFIm8imA== 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 DM6PR10MB2761.namprd10.prod.outlook.com (2603:10b6:5:b9::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5438.20; Tue, 19 Jul 2022 14:09:46 +0000 Received: from CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::2d14:50e4:3bb:4e30]) by CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::2d14:50e4:3bb:4e30%9]) with mapi id 15.20.5438.023; Tue, 19 Jul 2022 14:09:46 +0000 To: gcc-patches Paul A Clarke via Subject: [GCC13][Patch][V2][1/2]Add a new option -fstrict-flex-array[=n] and attribute strict_flex_array(n) and use it in PR101836 Thread-Topic: [GCC13][Patch][V2][1/2]Add a new option -fstrict-flex-array[=n] and attribute strict_flex_array(n) and use it in PR101836 Thread-Index: AQHYm3kzzNgnovwL1Uy+e8iGZkPVFg== Date: Tue, 19 Jul 2022 14:09:46 +0000 Message-ID: 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: a5827689-96ea-44c5-2828-08da6990560d x-ms-traffictypediagnostic: DM6PR10MB2761:EE_ x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: QWHghoqBpm+twGu2TdElcy2CE50gW8KePSLImUG8bRjQGzYc2L+/ZK/vQrqoDdKwHBSoNDmUN6V0IW74EDv8dxmmbyKA/Na4rJSbyirTi/uqTJp/BzMNjLjyas/L2UQ87buq8bkrMKtPYr/1MIpHCzATr7iN4VmMYVdI7f/2e6yR9p6ReecCD6dDsiUif7ZtClxpOK0J/VibpedsDZ8wg4z3Hw6c4Ezc1wB1qJgci+ba1+0GQGbsGDll0O1R+2YzlQNLq4PKxnin93oB8wWS6vBtaZy7GdboeI3DyY3kM9RjxQaCNZ1NHxsWvu3xAkPZQdFkVlWHo+MxcB3U3GrLXzRCsM8MJSxdg8WlpNcr1c0O3zh0UAdOHBQL1fKfknY4PLqO9baLn7euDLQn78fY8IchIIuQXmwe9Izh5rT2MpUrUI+ucneAEoL2GFas+CGhSfLFV94cUjaHapkDhMLzEktFWSe2BmfPtJz0fw6xyPzlF6r9rYUbJo/0X4QGYwPtbaapgYyJpM+YzHfq/MrdJB6S4zw+7E6YQRFzwgV1nlSq17oBJ9OtmYbp3SHH+omMHpcoWu6wxjCi38gauxped3Dn3s1o8lvdKVcGFJv3Xz03gnrc4fKBOnr7n+2KQ5+ObjquzzkhxYoNYv+DXt81k1bBP5Ukfu82aJXp18HsuNuLibfScWP+Jz1OuTbKyUwTUngEdE//BANCsME0bE5JmXL+Ry8mAVy8UklpKJEHDlgVkse2e0xNyD4A18qWB1orxFHfwgks1KIbbBGEjWLwZX4GKGYyorA2w260Gc+7frKhJYrHqXfbqdPrhI7KHsUepxvghGKJrN5B4DRqULywChLBfDvD1uqn00FNSPM/200= 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:(13230016)(136003)(396003)(366004)(346002)(376002)(39860400002)(71200400001)(478600001)(83380400001)(2616005)(44832011)(41300700001)(186003)(6486002)(86362001)(5660300002)(6512007)(2906002)(30864003)(122000001)(38100700002)(76116006)(66446008)(66946007)(64756008)(8676002)(4326008)(66556008)(84970400001)(8936002)(38070700005)(33656002)(91956017)(316002)(53546011)(6506007)(54906003)(6916009)(36756003)(66476007)(45980500001)(559001)(579004); DIR:OUT; SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: wHxl9NK4gTLz10lYbiKaYvCVWZxx6RFpOi0ihU+N/A6pv3OzqVULkXglGq8lCfD0qGRYFGxLipd6eWGsbPWNPb7z+jd0ZddTeU9Q+hltiwaY7plBxcgPmEhxvA3ICAV8BGdnZcxGUZURRGr6t087e+D+qqlEP01Wu/lWjxrpze0MUnWy5zIfF8JcSfTNLv0LPBJabqIC/Vht43kRSyGhEiWOAzJU8Wib5exUvYdm7ym/2Kj9vkILxiT6KDPlWOROIyqI4VtfDgBTKhErot2aby2eYh/5/WI62p1y7IsL75LZMjrOKg9peqh5DSFOq5SADzxOo/RdR346JZMfLzVTDc6KfhQAmqO9i/30TEWQxuW7HTpRPY8SUOSHaO4wNspyw/xVcUmOZq5akDITSw+Q0oxpBRG05xPS34DsaOGUHcHLqvfeHn/x8tB2PBX+2gB0B4fcIjQZO+eJsO9Za9kV0bsOx8YBAMUP78rTLKQWS12ng/8zVZ7KmEtRZ+zLmyHdddcllbDhHtMt6aFiyhQT24TIohA9GBBNjK1ny7vYSn5hFcL/UvBS6ACiRH0zQnQolxpG5fvQMQrRNUHU7Q9BJr+bjmcgYepkdqz0MzhYAWFuXTChOM9UPDPhLYXIuaomNZXJF1e+lDsGxonqTFj0j5GkDQTNAOmVugnY6fFuYO7hv6laUJSxCjktXHnaPGyE9SPctKeONAV8w9XmFbh3dkUb5Ef/2rL5Jh/jY0KnOAN/+Axk2Adz2emG9hlBcszwfekgF9cRnxA3rts7IGRsVBkapy+phD69KFn5+T3SeeSsOv1FecL6S54DZPxknpNGAMp0kRRYSASTF6wJhAIkj1Vmk0MosD4F4hjZ9I5gROb/j1zl6X4fb8MpSNRGfgoCT1dvL6568yddLC7YfBcQZ6RAKo8CQiwiUe70S4qFXDDD5Dr6lb7R2xfELo6UQSx7tlmXEjYfisAsrIFzC0EvdOj2X0Bhq0K20FEtYaCLkIOgplEeKVS/KKRq+IGy5fM0vaw+yP1Y3/MSL88I368oDOyfV2xbQ23EjX2apW64c6xvH6rNjIJmFjzQMoSfzPHSdOhCujCsaf6oLis2vPqjZK6B5EMgaMQJMMQY8Y3cRj/2gXjC0MTVpOyjjjy8+rPbuGdFcT2cZDw5EQJ0fELcTTF04c4DD6lg8d/w4j0HjzLL/VkXipYn8RyO8Z5hkROBZFYMMFrDFnFK5ab3YYh9VieUoIiEtVp9zZ8v21cRUNjohZSitKzN/ryphBtvpzPbSpl4Dz6Z7L85neX5hDcIwukyquD1FjFB8iBQEfbaRTJAcIOHSD2LWE/f5JyG/fd/ga0eN/p17uaHwMCMlXD2AXMc5lJN/5k0zgdcAtzPjupMbmXeJiF+sXb+9fSZ+YWlNag2P0bt4yHNb/i51E7l9aAuW45wLWucd+jit+HNlsPFzkaXGHF6EF8tcOr2p9tMZRKAMdirsID4p8G+5ZoPZntguJv/R7ybUODIdnriSR//H7Dqnw8sTlmAZ5xqq1CbPkBUyiU9W0OiapJN+KU3BmHAHf1Gxg+sQXTlezY3/j9cD6ZpFuEB/iCimoqO7obfgWgTFj0X+LVw2ImpXAPe+UWRHxifud9gxBAMqOXy3AM= Content-ID: <114AB9B4A2EBEF40A7E21E94C42BA51E@namprd10.prod.outlook.com> 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: a5827689-96ea-44c5-2828-08da6990560d X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Jul 2022 14:09:46.6100 (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: IiMG7gPt2LCAGSfRiuu4C8bLckrQLWloPY8PqJIyNcncCxu09hwfXhTnokXgMUTeKKQ4bROUfUPzMYAeLJWj6w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR10MB2761 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-07-19_02,2022-07-19_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 bulkscore=0 phishscore=0 suspectscore=0 mlxlogscore=999 adultscore=0 spamscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2206140000 definitions=main-2207190060 X-Proofpoint-ORIG-GUID: 0ec9Ve-R65CQp2R_YifvRXz3wzCC-9uU X-Proofpoint-GUID: 0ec9Ve-R65CQp2R_YifvRXz3wzCC-9uU X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_NUMSUBJECT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Qing Zhao via Gcc-patches From: Qing Zhao Reply-To: Qing Zhao Cc: jakub Jelinek , richard Biener , martin Sebor , "joseph@codesourcery.com" , kees Cook Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From 3854004802b8e2f132ebf218fc35a632f5e80c6a Mon Sep 17 00:00:00 2001 From: Qing Zhao Date: Mon, 18 Jul 2022 17:04:12 +0000 Subject: [PATCH 1/2] Add a new option -fstrict-flex-array[=n] and new attribute strict_flex_array Add the following new option -fstrict-flex-array[=n] and a corresponding attribute strict_flex_array to GCC: '-fstrict-flex-array' Treat the trailing array of a structure as a flexible array member in a stricter way. The positive form is equivalent to '-fstrict-flex-array=3', which is the strictest. A trailing array is treated as a flexible array member only when it is declared as a flexible array member per C99 standard onwards. The negative form is equivalent to '-fstrict-flex-array=0', which is the least strict. All trailing arrays of structures are treated as flexible array members. '-fstrict-flex-array=LEVEL' Treat the trailing array of a structure as a flexible array member in a stricter way. The value of LEVEL controls the level of strictness. The possible values of LEVEL are the same as for the 'strict_flex_array' attribute (*note Variable Attributes::). You can control this behavior for a specific trailing array field of a structure by using the variable attribute 'strict_flex_array' attribute (*note Variable Attributes::). 'strict_flex_array (LEVEL)' The 'strict_flex_array' attribute should be attached to the trailing array field of a structure. It specifies the level of strictness of treating the trailing array field of a structure as a flexible array member. LEVEL must be an integer betwen 0 to 3. LEVEL=0 is the least strict level, all trailing arrays of structures are treated as flexible array members. LEVEL=3 is the strictest level, only when the trailing array is declared as a flexible array member per C99 standard onwards ([]), it is treated as a flexible array member. There are two more levels in between 0 and 3, which are provided to support older codes that use GCC zero-length array extension ([0]) or one-size array as flexible array member ([1]): When LEVEL is 1, the trailing array is treated as a flexible array member when it is declared as either [], [0], or [1]; When LEVEL is 2, the trailing array is treated as a flexible array member when it is declared as either [], or [0]. This attribute can be used with or without '-fstrict-flex-array'. When both the attribute and the option present at the same time, the level of the strictness for the specific trailing array field is determined by the attribute. gcc/c-family/ChangeLog: * c-attribs.cc (handle_strict_flex_array_attribute): New function. (c_common_attribute_table): New item for strict_flex_array. * c.opt (fstrict-flex-array): New option. (fstrict-flex-array=): New option. gcc/c/ChangeLog: * c-decl.cc (add_flexible_array_elts_to_size): Call new utility routine flexible_array_member_p. (is_flexible_array_member_p): New function. (finish_struct): Set the new DECL_NOT_FLEXARRAY flag. gcc/ChangeLog: * doc/extend.texi: Document strict_flex_array attribute. * doc/invoke.texi: Document -fstrict-flex-array[=n] option. * tree-core.h (struct tree_decl_common): New bit field decl_not_flexarray. * tree.cc (component_ref_size): Reorg by using new utility functions. (flexible_array_member_p): New function. (zero_length_array_p): Likewise. (one_element_array_p): Likewise. (flexible_array_type_p): Likewise. * tree.h (DECL_NOT_FLEXARRAY): New flag. (zero_length_array_p): New function prototype. (one_element_array_p): Likewise. (flexible_array_member_p): Likewise. gcc/testsuite/ChangeLog: * gcc.dg/strict-flex-array-1.c: New test. --- gcc/c-family/c-attribs.cc | 47 ++++++++ gcc/c-family/c.opt | 7 ++ gcc/c/c-decl.cc | 91 +++++++++++++-- gcc/doc/extend.texi | 25 ++++ gcc/doc/invoke.texi | 27 ++++- gcc/testsuite/gcc.dg/strict-flex-array-1.c | 31 +++++ gcc/tree-core.h | 5 +- gcc/tree.cc | 130 ++++++++++++++------- gcc/tree.h | 16 ++- 9 files changed, 322 insertions(+), 57 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/strict-flex-array-1.c diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index c8d96723f4c..10d16532f0d 100644 --- a/gcc/c-family/c-attribs.cc +++ b/gcc/c-family/c-attribs.cc @@ -101,6 +101,8 @@ static tree handle_special_var_sec_attribute (tree *, tree, tree, int, bool *); static tree handle_aligned_attribute (tree *, tree, tree, int, bool *); static tree handle_warn_if_not_aligned_attribute (tree *, tree, tree, int, bool *); +static tree handle_strict_flex_array_attribute (tree *, tree, tree, + int, bool *); static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ; static tree handle_noplt_attribute (tree *, tree, tree, int, bool *) ; static tree handle_alias_ifunc_attribute (bool, tree *, tree, tree, bool *); @@ -367,6 +369,8 @@ const struct attribute_spec c_common_attribute_table[] = attr_aligned_exclusions }, { "warn_if_not_aligned", 0, 1, false, false, false, false, handle_warn_if_not_aligned_attribute, NULL }, + { "strict_flex_array", 1, 1, false, false, false, false, + handle_strict_flex_array_attribute, NULL }, { "weak", 0, 0, true, false, false, false, handle_weak_attribute, NULL }, { "noplt", 0, 0, true, false, false, false, @@ -2498,6 +2502,49 @@ handle_warn_if_not_aligned_attribute (tree *node, tree name, no_add_attrs, true); } +/* Handle a "strict_flex_array" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_strict_flex_array_attribute (tree *node, tree name, + tree args, int ARG_UNUSED (flags), + bool *no_add_attrs) +{ + tree decl = *node; + tree argval = TREE_VALUE (args); + + /* This attribute only applies to field decls of a structure. */ + if (TREE_CODE (decl) != FIELD_DECL) + { + error_at (DECL_SOURCE_LOCATION (decl), + "%qE attribute may not be specified for %q+D", name, decl); + *no_add_attrs = true; + } + /* This attribute only applies to field with array type. */ + else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE) + { + error_at (DECL_SOURCE_LOCATION (decl), + "%qE attribute may not be specified for a non array field", + name); + *no_add_attrs = true; + } + else if (TREE_CODE (argval) != INTEGER_CST) + { + error_at (DECL_SOURCE_LOCATION (decl), + "%qE attribute argument not an integer", name); + *no_add_attrs = true; + } + else if (!tree_fits_uhwi_p (argval) || tree_to_uhwi (argval) > 3) + { + error_at (DECL_SOURCE_LOCATION (decl), + "%qE attribute argument %qE is not an integer constant" + " between 0 and 3", name, argval); + *no_add_attrs = true; + } + + return NULL_TREE; +} + /* Handle a "weak" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 44e1a60ce24..864cd8df1d3 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -2060,6 +2060,13 @@ fsized-deallocation C++ ObjC++ Var(flag_sized_deallocation) Init(-1) Enable C++14 sized deallocation support. +fstrict-flex-array +C C++ Common Alias(fstrict-flex-array=,3,0) + +fstrict-flex-array= +C C++ Common Joined RejectNegative UInteger Var(flag_strict_flex_array) Init(0) IntegerRange(0,3) +-fstrict-flex-array= Treat the trailing array of a structure as a flexible array in a stricter way. The default is treating all trailing arrays of structures as flexible arrays. + fsquangle C++ ObjC++ WarnRemoved diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index ae8990c138f..14defae9584 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -5013,10 +5013,7 @@ add_flexible_array_elts_to_size (tree decl, tree init) elt = CONSTRUCTOR_ELTS (init)->last ().value; type = TREE_TYPE (elt); - if (TREE_CODE (type) == ARRAY_TYPE - && TYPE_SIZE (type) == NULL_TREE - && TYPE_DOMAIN (type) != NULL_TREE - && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE) + if (flexible_array_member_p (type)) { complete_array_type (&type, elt, false); DECL_SIZE (decl) @@ -8720,6 +8717,80 @@ finish_incomplete_vars (tree incomplete_vars, bool toplevel) } } +/* Determine whether the FIELD_DECL X is a flexible array member according to + the following info: + A. whether the FIELD_DECL X is the last field of the DECL_CONTEXT; + B. whether the FIELD_DECL is an array that is declared as "[]", "[0]", + or "[1]"; + C. flag_strict_flex_array; + D. the attribute strict_flex_array that is attached to the field + if presenting. + Return TRUE when it's a flexible array member, FALSE otherwise. */ + +static bool +is_flexible_array_member_p (bool is_last_field, + tree x) +{ + /* if not the last field, return false. */ + if (!is_last_field) + return false; + + /* if not an array field, return false. */ + if (TREE_CODE (TREE_TYPE (x)) != ARRAY_TYPE) + return false; + + bool is_zero_length_array = zero_length_array_p (TREE_TYPE (x)); + bool is_one_element_array = one_element_array_p (TREE_TYPE (x)); + bool is_flexible_array = flexible_array_member_p (TREE_TYPE (x)); + + unsigned int strict_flex_array_level = flag_strict_flex_array; + + tree attr_strict_flex_array = lookup_attribute ("strict_flex_array", + DECL_ATTRIBUTES (x)); + /* if there is a strict_flex_array attribute attached to the field, + override the flag_strict_flex_array. */ + if (attr_strict_flex_array) + { + /* get the value of the level first from the attribute. */ + unsigned HOST_WIDE_INT attr_strict_flex_array_level = 0; + gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); + attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); + gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); + attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); + gcc_assert (tree_fits_uhwi_p (attr_strict_flex_array)); + attr_strict_flex_array_level = tree_to_uhwi (attr_strict_flex_array); + + /* the attribute has higher priority than flag_struct_flex_array. */ + strict_flex_array_level = attr_strict_flex_array_level; + } + + switch (strict_flex_array_level) + { + case 0: + /* default, all trailing arrays are flexiable array members. */ + return true; + case 1: + /* Level 1: all "[1]", "[0]", and "[]" are flexiable array members. */ + if (is_one_element_array) + return true; + /* FALLTHROUGH. */ + case 2: + /* Level 2: all "[0]", and "[]" are flexiable array members. */ + if (is_zero_length_array) + return true; + /* FALLTHROUGH. */ + case 3: + /* Level 3: Only "[]" are flexible array members. */ + if (is_flexible_array) + return true; + break; + default: + gcc_unreachable (); + } + return false; +} + + /* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T. LOC is the location of the RECORD_TYPE or UNION_TYPE's definition. FIELDLIST is a chain of FIELD_DECL nodes for the fields. @@ -8781,6 +8852,8 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, bool saw_named_field = false; for (x = fieldlist; x; x = DECL_CHAIN (x)) { + bool is_last_field = (DECL_CHAIN (x) == NULL_TREE); + if (TREE_TYPE (x) == error_mark_node) continue; @@ -8819,10 +8892,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, DECL_PACKED (x) = 1; /* Detect flexible array member in an invalid context. */ - if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE - && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE - && TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE - && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE) + if (flexible_array_member_p (TREE_TYPE (x))) { if (TREE_CODE (t) == UNION_TYPE) { @@ -8830,7 +8900,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, "flexible array member in union"); TREE_TYPE (x) = error_mark_node; } - else if (DECL_CHAIN (x) != NULL_TREE) + else if (!is_last_field) { error_at (DECL_SOURCE_LOCATION (x), "flexible array member not at end of struct"); @@ -8850,6 +8920,9 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic, "invalid use of structure with flexible array member"); + /* Set DECL_NOT_FLEXARRAY flag for FIELD_DECL x. */ + DECL_NOT_FLEXARRAY (x) = !is_flexible_array_member_p (is_last_field, x); + if (DECL_NAME (x) || RECORD_OR_UNION_TYPE_P (TREE_TYPE (x))) saw_named_field = true; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index dfbe33ac652..7451410a011 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7436,6 +7436,31 @@ This warning can be disabled by @option{-Wno-if-not-aligned}. The @code{warn_if_not_aligned} attribute can also be used for types (@pxref{Common Type Attributes}.) +@cindex @code{strict_flex_array} variable attribute +@item strict_flex_array (@var{level}) +The @code{strict_flex_array} attribute should be attached to the trailing +array field of a structure. It specifies the level of strictness of +treating the trailing array field of a structure as a flexible array +member. @var{level} must be an integer betwen 0 to 3. + +@var{level}=0 is the least strict level, all trailing arrays of structures +are treated as flexible array members. @var{level}=3 is the strictest level, +only when the trailing array is declared as a flexible array member per C99 +standard onwards ([]), it is treated as a flexible array member. + +There are two more levels in between 0 and 3, which are provided to support +older codes that use GCC zero-length array extension ([0]) or one-size array +as flexible array member ([1]): +When @var{level} is 1, the trailing array is treated as a flexible array member +when it is declared as either "[]", "[0]", or "[1]"; +When @var{level} is 2, the trailing array is treated as a flexible array member +when it is declared as either "[]", or "[0]". + +This attribute can be used with or without @option{-fstrict-flex-array}. When +both the attribute and the option present at the same time, the level of the +strictness for the specific trailing array field is determined by the attribute. + + @item alloc_size (@var{position}) @itemx alloc_size (@var{position-1}, @var{position-2}) @cindex @code{alloc_size} variable attribute diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 94fe57aa4e2..9befe601817 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -207,7 +207,8 @@ in the following sections. -fopenmp -fopenmp-simd @gol -fpermitted-flt-eval-methods=@var{standard} @gol -fplan9-extensions -fsigned-bitfields -funsigned-bitfields @gol --fsigned-char -funsigned-char -fsso-struct=@var{endianness}} +-fsigned-char -funsigned-char -fstrict-flex-array[=@var{n}] @gol +-fsso-struct=@var{endianness}} @item C++ Language Options @xref{C++ Dialect Options,,Options Controlling C++ Dialect}. @@ -2825,6 +2826,30 @@ The type @code{char} is always a distinct type from each of @code{signed char} or @code{unsigned char}, even though its behavior is always just like one of those two. +@item -fstrict-flex-array +@opindex fstrict-flex-array +@opindex fno-strict-flex-array +Treat the trailing array of a structure as a flexible array member in a +stricter way. +The positive form is equivalent to @option{-fstrict-flex-array=3}, which is the +strictest. A trailing array is treated as a flexible array member only when it +is declared as a flexible array member per C99 standard onwards. +The negative form is equivalent to @option{-fstrict-flex-array=0}, which is the +least strict. All trailing arrays of structures are treated as flexible array +members. + +@item -fstrict-flex-array=@var{level} +@opindex fstrict-flex-array=@var{level} +Treat the trailing array of a structure as a flexible array member in a +stricter way. The value of @var{level} controls the level of strictness. + +The possible values of @var{level} are the same as for the +@code{strict_flex_array} attribute (@pxref{Variable Attributes}). + +You can control this behavior for a specific trailing array field of a +structure by using the variable attribute @code{strict_flex_array} attribute +(@pxref{Variable Attributes}). + @item -fsso-struct=@var{endianness} @opindex fsso-struct Set the default scalar storage order of structures and unions to the diff --git a/gcc/testsuite/gcc.dg/strict-flex-array-1.c b/gcc/testsuite/gcc.dg/strict-flex-array-1.c new file mode 100644 index 00000000000..ec886c99b25 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strict-flex-array-1.c @@ -0,0 +1,31 @@ +/* testing the correct usage of attribute strict_flex_array. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + + +int x __attribute__ ((strict_flex_array (1))); /* { dg-error "'strict_flex_array' attribute may not be specified for 'x'" } */ + +struct trailing { + int a; + int c __attribute ((strict_flex_array)); /* { dg-error "wrong number of arguments specified for 'strict_flex_array' attribute" } */ +}; + +struct trailing_1 { + int a; + int b; + int c __attribute ((strict_flex_array (2))); /* { dg-error "'strict_flex_array' attribute may not be specified for a non array field" } */ +}; + +extern int d; + +struct trailing_array_2 { + int a; + int b; + int c[1] __attribute ((strict_flex_array (d))); /* { dg-error "'strict_flex_array' attribute argument not an integer" } */ +}; + +struct trailing_array_3 { + int a; + int b; + int c[0] __attribute ((strict_flex_array (5))); /* { dg-error "'strict_flex_array' attribute argument '5' is not an integer constant between 0 and 3" } */ +}; diff --git a/gcc/tree-core.h b/gcc/tree-core.h index ea9f281f1cc..458c6e6ceea 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -1813,7 +1813,10 @@ struct GTY(()) tree_decl_common { TYPE_WARN_IF_NOT_ALIGN. */ unsigned int warn_if_not_align : 6; - /* 14 bits unused. */ + /* In FIELD_DECL, this is DECL_NOT_FLEXARRAY. */ + unsigned int decl_not_flexarray : 1; + + /* 13 bits unused. */ /* UID for points-to sets, stable over copying from inlining. */ unsigned int pt_uid; diff --git a/gcc/tree.cc b/gcc/tree.cc index 84000dd8b69..02e274699fb 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -12862,7 +12862,7 @@ get_initializer_for (tree init, tree decl) /* Determines the size of the member referenced by the COMPONENT_REF REF, using its initializer expression if necessary in order to determine the size of an initialized flexible array member. - If non-null, set *ARK when REF refers to an interior zero-length + If non-null, set *SAM when REF refers to an interior zero-length array or a trailing one-element array. Returns the size as sizetype (which might be zero for an object with an uninitialized flexible array member) or null if the size @@ -12878,16 +12878,32 @@ component_ref_size (tree ref, special_array_member *sam /* = NULL */) sam = &sambuf; *sam = special_array_member::none; + /* Whether this ref is an array at the end of a structure. */ + bool trailing = array_at_struct_end_p (ref); + /* The object/argument referenced by the COMPONENT_REF and its type. */ tree arg = TREE_OPERAND (ref, 0); tree argtype = TREE_TYPE (arg); - /* The referenced member. */ - tree member = TREE_OPERAND (ref, 1); + /* The referenced field member. */ + tree member = TREE_OPERAND (ref, 1); + tree memtype = TREE_TYPE (member); tree memsize = DECL_SIZE_UNIT (member); + + bool is_zero_length_array_ref = zero_length_array_p (memtype); + bool is_constant_length_array_ref = false; + bool is_one_element_array_ref + = one_element_array_p (memtype, &is_constant_length_array_ref); + + /* Determine the type of the special array member. */ + if (is_zero_length_array_ref) + *sam = trailing ? special_array_member::trail_0 + : special_array_member::int_0; + else if (is_one_element_array_ref && trailing) + *sam = special_array_member::trail_1; + if (memsize) { - tree memtype = TREE_TYPE (member); if (TREE_CODE (memtype) != ARRAY_TYPE) /* DECL_SIZE may be less than TYPE_SIZE in C++ when referring to the type of a class with a virtual base which doesn't @@ -12897,50 +12913,30 @@ component_ref_size (tree ref, special_array_member *sam /* = NULL */) return (tree_int_cst_equal (memsize, TYPE_SIZE_UNIT (memtype)) ? memsize : NULL_TREE); - bool trailing = array_at_struct_end_p (ref); - bool zero_length = integer_zerop (memsize); - if (!trailing && !zero_length) + if (!trailing && !is_zero_length_array_ref) /* MEMBER is either an interior array or is an array with more than one element. */ return memsize; - if (zero_length) - { - if (trailing) - *sam = special_array_member::trail_0; - else - { - *sam = special_array_member::int_0; - memsize = NULL_TREE; - } - } + if (*sam != special_array_member::trail_1 + && is_constant_length_array_ref) + /* MEMBER is a constant length array which is not a one-element + trailing array. */ + return memsize; - if (!zero_length) - if (tree dom = TYPE_DOMAIN (memtype)) - if (tree min = TYPE_MIN_VALUE (dom)) - if (tree max = TYPE_MAX_VALUE (dom)) - if (TREE_CODE (min) == INTEGER_CST - && TREE_CODE (max) == INTEGER_CST) - { - offset_int minidx = wi::to_offset (min); - offset_int maxidx = wi::to_offset (max); - offset_int neltsm1 = maxidx - minidx; - if (neltsm1 > 0) - /* MEMBER is an array with more than one element. */ - return memsize; - - if (neltsm1 == 0) - *sam = special_array_member::trail_1; - } + if (*sam == special_array_member::int_0) + memsize = NULL_TREE; - /* For a reference to a zero- or one-element array member of a union - use the size of the union instead of the size of the member. */ + /* For a reference to a flexible array member, an interior zero length + array, or an array with variable length of a union, use the size of + the union instead of the size of the member. */ if (TREE_CODE (argtype) == UNION_TYPE) memsize = TYPE_SIZE_UNIT (argtype); } - /* MEMBER is either a bona fide flexible array member, or a zero-length - array member, or an array of length one treated as such. */ + /* MEMBER now is a flexible array member, an interior zero length array, or + an array with variable length. We need to decide its size from its + initializer. */ /* If the reference is to a declared object and the member a true flexible array, try to determine its size from its initializer. */ @@ -14351,6 +14347,59 @@ default_is_empty_record (const_tree type) return is_empty_type (TYPE_MAIN_VARIANT (type)); } +/* Determine whether TYPE is a ISO flexible array memeber type "[]". */ +bool +flexible_array_member_p (const_tree type) +{ + if (TREE_CODE (type) == ARRAY_TYPE + && TYPE_SIZE (type) == NULL_TREE + && TYPE_DOMAIN (type) != NULL_TREE + && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE) + return true; + + return false; +} + +/* Determine whether TYPE is a zero-length array type "[0]". */ +bool +zero_length_array_p (const_tree type) +{ + if (TREE_CODE (type) == ARRAY_TYPE) + if (tree type_size = TYPE_SIZE_UNIT (type)) + if ((integer_zerop (type_size)) + && TYPE_DOMAIN (type) != NULL_TREE + && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE) + return true; + return false; +} + +/* Determine whether TYPE is a one-element array type "[1]". + Set IS_CONSTANT_LENGTH to true if the length is constant, + otherwise, IS_CONSTANT_LENGTH is set to false. */ +bool +one_element_array_p (const_tree type, bool *is_constant_length /* = NULL */) +{ + if (is_constant_length) + *is_constant_length = false; + + if (TREE_CODE (type) == ARRAY_TYPE) + if (tree dom = TYPE_DOMAIN (type)) + if (tree min = TYPE_MIN_VALUE (dom)) + if (tree max = TYPE_MAX_VALUE (dom)) + if (TREE_CODE (min) == INTEGER_CST + && TREE_CODE (max) == INTEGER_CST) + { + offset_int minidx = wi::to_offset (min); + offset_int maxidx = wi::to_offset (max); + offset_int neltsm1 = maxidx - minidx; + if (is_constant_length) + *is_constant_length = true; + if (neltsm1 == 0) + return true; + } + return false; +} + /* Determine whether TYPE is a structure with a flexible array member, or a union containing such a structure (possibly recursively). */ @@ -14367,10 +14416,7 @@ flexible_array_type_p (const_tree type) last = x; if (last == NULL_TREE) return false; - if (TREE_CODE (TREE_TYPE (last)) == ARRAY_TYPE - && TYPE_SIZE (TREE_TYPE (last)) == NULL_TREE - && TYPE_DOMAIN (TREE_TYPE (last)) != NULL_TREE - && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (last))) == NULL_TREE) + if (flexible_array_member_p (TREE_TYPE (last))) return true; return false; case UNION_TYPE: diff --git a/gcc/tree.h b/gcc/tree.h index e6564aaccb7..3107de5b499 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2993,6 +2993,11 @@ extern void decl_value_expr_insert (tree, tree); #define DECL_PADDING_P(NODE) \ (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_3) +/* Used in a FIELD_DECL to indicate whether this field is not a flexible + array member. */ +#define DECL_NOT_FLEXARRAY(NODE) \ + (FIELD_DECL_CHECK (NODE)->decl_common.decl_not_flexarray) + /* A numeric unique identifier for a LABEL_DECL. The UID allocation is dense, unique within any one function, and may be used to index arrays. If the value is -1, then no UID has been assigned. */ @@ -5531,10 +5536,10 @@ extern tree component_ref_field_offset (tree); returns null. */ enum struct special_array_member { - none, /* Not a special array member. */ - int_0, /* Interior array member with size zero. */ - trail_0, /* Trailing array member with size zero. */ - trail_1 /* Trailing array member with one element. */ + none, /* Not a special array member. */ + int_0, /* Interior array member with size zero. */ + trail_0, /* Trailing array member with size zero. */ + trail_1 /* Trailing array member with one element. */ }; /* Return the size of the member referenced by the COMPONENT_REF, using @@ -6489,6 +6494,9 @@ extern void gt_pch_nx (tree &, gt_pointer_operator, void *); extern bool nonnull_arg_p (const_tree); extern bool is_empty_type (const_tree); extern bool default_is_empty_record (const_tree); +extern bool zero_length_array_p (const_tree); +extern bool one_element_array_p (const_tree, bool * = NULL); +extern bool flexible_array_member_p (const_tree); extern bool flexible_array_type_p (const_tree); extern HOST_WIDE_INT arg_int_size_in_bytes (const_tree); extern tree arg_size_in_bytes (const_tree); From patchwork Tue Jul 19 14:11:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qing Zhao X-Patchwork-Id: 56168 Return-Path: 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 B9C753857419 for ; Tue, 19 Jul 2022 14:12:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B9C753857419 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1658239933; bh=A4IWMsdLN24GJLPa75uFfku3iR21WAU01uUVtE61m+4=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=mORwsBgppwZOBBowPCbH/4c7euzmS/rrPNMxv29U+hl3yWOVgvzly8j25ReZFSNxz me7M+n98J6TKVvyAhVhzvkNzu/EFg446DfceF5uMg9PkFAP7992+2kR7yabe2+5ziG 3X1IptX+HQD1KTVd44X5vc2wk8ejNxLu+Hwbl6Qw= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by sourceware.org (Postfix) with ESMTPS id 8972C3858439 for ; Tue, 19 Jul 2022 14:11:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8972C3858439 Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 26JDBFSd017914; Tue, 19 Jul 2022 14:11:24 GMT Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.appoci.oracle.com [138.1.114.2]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3hbkx0xju5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 19 Jul 2022 14:11:23 +0000 Received: from pps.filterd (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.5/8.17.1.5) with ESMTP id 26JC9xMT016422; Tue, 19 Jul 2022 14:11:22 GMT Received: from nam04-bn8-obe.outbound.protection.outlook.com (mail-bn8nam04lp2040.outbound.protection.outlook.com [104.47.74.40]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 3hc1emk55h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 19 Jul 2022 14:11:22 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=mPuXS1kyedIW+Yl1v+CXgnG+nrYhWafAtuWAtioqgNuA9u/ec+tdRMgPr54lF2UGJ8jxz2PY7uTE/viq5Y4IlbeoNzsPtOSV0VTfM+uk5Fgms3UBeQJSCGQzRJue3GchQ936Wfn9ZGXc1URrNH5R8Lf0Iw2RGjKqhbJkwnCsWwNEqdfRNWqQ0A2lgi69qxY+r0RTBycJRhx3CDo+Sgt633ThApfAZSSiveqyGM6HfKtXM4YONl60+13/CFuEyKY7sTZgXlfmRkWKFRXWdyG/Rz/tA3Idc2N0P3w/+rYNkrQFxz2XxNyLUtNyjDz/+ps+d4RPA/LSPh9AoPuA7pUdsg== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=A4IWMsdLN24GJLPa75uFfku3iR21WAU01uUVtE61m+4=; b=DSMuqUBy0n1F+hm3D81jlW0SbLYW3Ssngu+ZdpZFgki6hLBzR4lZEJ/+3W/p8Q34JAj0Ld1HYRdF7BwLyzYYyNRWvGLXwlJ8wuMQG8wonGi7MNW7aZtdAN58pnatgT8RQHdFLKesVp/1WsIH0pJxglchScRhM48MnpVT8mWgq6rH2YW87KXHyZz6jI+5NsaWY3kYL2XUYv2uftOB4cBg8mAcDpADMbF0bybU6UiNdyQC7nIXfLQwtYzUOMB8k5unOuhuX43fGesJdVWs7sz8rEcPSIlFCfkJBHANP+/X6o8gdbI8L5+gULJaJmc/Gc1dpfvV5mR9I9OTAPlXaCgBfA== 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 MWHPR10MB1886.namprd10.prod.outlook.com (2603:10b6:300:10e::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5438.17; Tue, 19 Jul 2022 14:11:19 +0000 Received: from CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::2d14:50e4:3bb:4e30]) by CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::2d14:50e4:3bb:4e30%9]) with mapi id 15.20.5438.023; Tue, 19 Jul 2022 14:11:19 +0000 To: gcc-patches Paul A Clarke via Subject: [GCC13][Patch][V2][2/2]Add a new option -fstrict-flex-array[=n] and attribute strict_flex_array(n) and use it in PR101836 Thread-Topic: [GCC13][Patch][V2][2/2]Add a new option -fstrict-flex-array[=n] and attribute strict_flex_array(n) and use it in PR101836 Thread-Index: AQHYm3lqhCG5z7mY8Eyr0tWPjjd+9w== Date: Tue, 19 Jul 2022 14:11:19 +0000 Message-ID: <1D72918C-4D6A-4583-AF14-288757C04DD0@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: 6d217f46-64f4-4238-f43c-08da69908d6b x-ms-traffictypediagnostic: MWHPR10MB1886:EE_ x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 6vU8d4ox8KXrGY7Hja3awvm4LZTXzdRfBIVqPo6EpKaVnbKd+eBmJIKskh0uuC+2DgA1McWQKyUr3Sg7khw4gf13DTr67oGQ7P0tVGUhSXxAiBqz2e8aageD157F4+Qbs1zhAKMI2gi6tiu6KA+Ir2MQGyfTbeSGXbug3oZK+Ehvjtrg3WhbiIrvKWzt9B0uJPMPmS+LRHpSCr0YSt7G3xO6uN+CjSk2uBioQxGdCpVaZqzcvSvLhx7RpR5Hri3xhsILHfY3/04coxlv/pmX4x0+WMj8F0mS+Bl6oEl7vV4VCI8r1vLnlnAwP7sAoPSxw5bQsG1W8eenvqpkxSyBtJcr9HuN6RiFvdeoN2WL7QsJ1MZ5rvcYMEzJfbvVVS+Muo/DLpjMLr2gMWGphTqi2fH2rHlfs0DOp0M2iv+HCi7CIGtTuq/i34UoEOk19kwLKXe3TLvBDNtIsExd0WDEA9GkP4Y+T3t8nayK7ueK6dogx/WNuVDJBIjlZWZqLSRahiA3Ugfg+tIGUIV5Jyi8F7ev4otUJiiiYEbqsiqx51qkA8/3Hh9l76XaRmHCcEqqkbHWXCtM2ChODSa6FTjxgnHnwZamOyUBSroN5GL2edpKPswCc4GiwwAd7cig5RVV9oK84d9TIPgvUXeUfRiMA2YX4w7MEGaI+Lwc86j6sy0kR235pWlA1taILewfhU7X16OOUld9qGzbOJ+y+iY/zRctSHUIgyvH7H5s3Nw57kGrOfOK3N5tMNInaNsb1IceX3l/6MSaWJp1JP+1w5xZpZv0YGKdnOl49VBzoAubyakF56wxUz1jXpCSKp4qLqA+IsV2+jPRgWXbt05vPLro0uxMo+MF8do+al8roPnl2W8FbrW15XcDkqMa6dvvo5xcTMahztIi4Kva9//+0FEQvw== 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:(13230016)(376002)(366004)(136003)(39860400002)(396003)(346002)(38100700002)(83380400001)(71200400001)(186003)(91956017)(6916009)(54906003)(66946007)(76116006)(36756003)(316002)(66446008)(8676002)(64756008)(4326008)(66556008)(66476007)(478600001)(84970400001)(8936002)(5660300002)(53546011)(6512007)(2616005)(6506007)(44832011)(122000001)(6486002)(33656002)(41300700001)(2906002)(38070700005)(86362001)(30864003)(45980500001); DIR:OUT; SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: Nvskd5VXMVyRDzzEbXPu3THNUfCtnvAZ+J7EsfaWGbiEnN/F5/q6+j5/X2vEnyftPm0UHFasq+/Rqe2B0v5Euk+LyjMViwoZitf0NbpuWfTRRXuIP/9rVu7okkiqYdDf31TXbCUoiMbLvoCpsFhe21ZuXaM7guDgtgm1z/GDcWcnLKmmHFFmidh2snU1uy7DudVKoitOEH7XbV65dMVSyWPuch+xr6ysknsY7gWuIrNade4Z9IZ/qSdbuJdbrWtRaJKmr9h2QXV4aN3pJeKGw2pQs2f5DJce19V0BZhiRfUADxMYQjcdDT+Mmkw46OahhaaZ9VJzL8RdlBYta6OCP1oCfC5UKBTK9hBsdCiOs0Xoay6LRuMPOGHm3PwDvAqcdBgc6Ctx0+mLw3mkwWj0gglCVCLxKMvQJ2rwMSsT9hYJKrry4hOFvgZqyPdn9HZsinQUv97v+zwF6Vofqr9mzFz55tPuWjIAN7iJDaMAOb4C0omhAljyBtKiaz2NZ7G0hc75dIPLTgmt+RKIm++Y/D1Ydaf6M2uH4WUTlr9m4EDul38oIAP3UHmUdRw4SLFLMTKVaNGv69eTKAp9Q1dz9ZEj+mUJdacr8PZY3Q/SzvAwvcyaAwJD9VuoocxO3chpa3DWefxnS1WT5CRUxX9hYfzgf9Zb8ymoyUezfAAhmCN/qLQ8h38oaBCvaILX94wJw0igGTwFENzec3+1JIc1rdQmT20Xt1beqGR9wUsve4WaID5tmC6Qf4ibQpm7GaYXRBJOJNFi/RnX8KOQ7Ymp1hkVWr7Mw6Gu4DmFhNbP6ewltTByZTHdum01NfRAMtklKL8eL0GZxajSGzwR4aSYeRt/OPFDk74pG2WWBopcPU784xUNwSOBOw0aNYyTFyzv9oh5oryPmLEwYQImmn5zD/gjNu6NbOmtNcn2tcBTPzYeZusZojHPyiyUjG0rbEpLadyKdv8PbiSqqdwo9DFuzgzsE6qHRy1wL8nlorD8BbGHBGHC2xFxYwPMvjxtW8yotfJ2VeqrbRjwHbYaFnpRr79PhTiqCepNvmDitGo0RD2nfwpeYH/JKT4Zfra1zIUlcvqSipDf80kXFHH0w9a1a0XSZ6LrD+5z4B95c2GpXpr+PxDPHH46X/USlR/PnZ+daT0YBce2ISm3Gjlvmpqaz0iku3zuu5w41GsNHEOvpm64HEtFVSp7Tw+wTRl+FBLE1+lG8SRx9ifWizfNalC4ENvTbeFfGGy8hblQfErI4usIhiU3pjSPRa3TRgHybdtzo/O3CXATTkeIv8IFpl1/rJbgr8Q9Z4ZohGo1M1AnIyoJnVYjNWHRuAvripMXP9Qg66ArMmbLsr09DS+Vx46zyf1Xml9LZxUf1qFgi6vUTwwLus5Te17M8UmhBhBl4blo9pFHUwIN+EthPF2bCtNg2zx1bm8uBZ60tYSbfuP/y5HxSpdZsdB4AgCY1tWepQndplLdXdAHz8uo3cdcoOauywXzSEJLbJYg3/5NBciouraArIL9FuFPSHv7sby/tGJ5HDC33N6mrBf72oclEweybbH8Wy/zrUZbxjivObBYxoRwkOMDpoCxJTW6dpy65LFmX76auQT1gc3yJfIe+Q7HU0PqIuTvyyDAs7QaOXkiinI= Content-ID: 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: 6d217f46-64f4-4238-f43c-08da69908d6b X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Jul 2022 14:11:19.4903 (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: e5mcvBKIgdp4q7NIOt5ijghWh6JiNEAe8HqksEWldy4H4J2NkkSjk/1XWvZnA9wDb42pHa3uWdktY6+LmJZ6FA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR10MB1886 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-07-19_02,2022-07-19_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 mlxscore=0 mlxlogscore=999 suspectscore=0 phishscore=0 adultscore=0 spamscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2206140000 definitions=main-2207190060 X-Proofpoint-GUID: 63H6BUkE2lcHIgPJVg9nY4k9j9bMcKBD X-Proofpoint-ORIG-GUID: 63H6BUkE2lcHIgPJVg9nY4k9j9bMcKBD X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_NUMSUBJECT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Qing Zhao via Gcc-patches From: Qing Zhao Reply-To: Qing Zhao Cc: jakub Jelinek , richard Biener , martin Sebor , "joseph@codesourcery.com" , kees Cook Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From a09f39ded462611286a44d9e8273de8342673ba2 Mon Sep 17 00:00:00 2001 From: Qing Zhao Date: Mon, 18 Jul 2022 18:12:26 +0000 Subject: [PATCH 2/2] Use new flag DECL_NOT_FLEXARRAY in __builtin_object_size [PR101836] Use new flag DECL_NOT_FLEXARRAY to determine whether the trailing array of a structure is flexible array member in __builtin_object_size. gcc/ChangeLog: PR tree-optimization/101836 * tree-object-size.cc (addr_object_size): Use array_at_struct_end_p and DECL_NOT_FLEXARRAY to determine a flexible array member reference. gcc/testsuite/ChangeLog: PR tree-optimization/101836 * gcc.dg/pr101836.c: New test. * gcc.dg/pr101836_1.c: New test. * gcc.dg/pr101836_2.c: New test. * gcc.dg/pr101836_3.c: New test. * gcc.dg/pr101836_4.c: New test. * gcc.dg/pr101836_5.c: New test. * gcc.dg/strict-flex-array-2.c: New test. * gcc.dg/strict-flex-array-3.c: New test. --- gcc/testsuite/gcc.dg/pr101836.c | 60 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr101836_1.c | 60 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr101836_2.c | 60 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr101836_3.c | 60 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr101836_4.c | 60 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr101836_5.c | 60 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/strict-flex-array-2.c | 60 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/strict-flex-array-3.c | 60 ++++++++++++++++++++++ gcc/tree-object-size.cc | 18 +++---- 9 files changed, 489 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr101836.c create mode 100644 gcc/testsuite/gcc.dg/pr101836_1.c create mode 100644 gcc/testsuite/gcc.dg/pr101836_2.c create mode 100644 gcc/testsuite/gcc.dg/pr101836_3.c create mode 100644 gcc/testsuite/gcc.dg/pr101836_4.c create mode 100644 gcc/testsuite/gcc.dg/pr101836_5.c create mode 100644 gcc/testsuite/gcc.dg/strict-flex-array-2.c create mode 100644 gcc/testsuite/gcc.dg/strict-flex-array-3.c diff --git a/gcc/testsuite/gcc.dg/pr101836.c b/gcc/testsuite/gcc.dg/pr101836.c new file mode 100644 index 00000000000..e5b4e5160a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836.c @@ -0,0 +1,60 @@ +/* -fstrict-flex-array is aliased with -ftrict-flex-array=3, which is the + strictest, only [] is treated as flexible array. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-array" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4]; +}; + +struct trailing_array_2 { + int a; + int b; + int c[1]; +}; + +struct trailing_array_3 { + int a; + int b; + int c[0]; +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), 16); + expect(__builtin_object_size(trailing_1->c, 1), 4); + expect(__builtin_object_size(trailing_0->c, 1), 0); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr101836_1.c b/gcc/testsuite/gcc.dg/pr101836_1.c new file mode 100644 index 00000000000..30ea20427a5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_1.c @@ -0,0 +1,60 @@ +/* -fstrict-flex-array=3 is the strictest, only [] is treated as + flexible array. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-array=3" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4]; +}; + +struct trailing_array_2 { + int a; + int b; + int c[1]; +}; + +struct trailing_array_3 { + int a; + int b; + int c[0]; +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), 16); + expect(__builtin_object_size(trailing_1->c, 1), 4); + expect(__builtin_object_size(trailing_0->c, 1), 0); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr101836_2.c b/gcc/testsuite/gcc.dg/pr101836_2.c new file mode 100644 index 00000000000..ebbe88f433c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_2.c @@ -0,0 +1,60 @@ +/* When -fstrict-flex-array=2, only [] and [0] are treated as flexiable + arrays. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-array=2" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4]; +}; + +struct trailing_array_2 { + int a; + int b; + int c[1]; +}; + +struct trailing_array_3 { + int a; + int b; + int c[0]; +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), 16); + expect(__builtin_object_size(trailing_1->c, 1), 4); + expect(__builtin_object_size(trailing_0->c, 1), -1); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr101836_3.c b/gcc/testsuite/gcc.dg/pr101836_3.c new file mode 100644 index 00000000000..d4ba0afe5bc --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_3.c @@ -0,0 +1,60 @@ +/* When -fstrict-flex-array=1, [], [0], and [1] are treated as flexible + arrays. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-array=1" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4]; +}; + +struct trailing_array_2 { + int a; + int b; + int c[1]; +}; + +struct trailing_array_3 { + int a; + int b; + int c[0]; +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), 16); + expect(__builtin_object_size(trailing_1->c, 1), -1); + expect(__builtin_object_size(trailing_0->c, 1), -1); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr101836_4.c b/gcc/testsuite/gcc.dg/pr101836_4.c new file mode 100644 index 00000000000..b10d3ce312d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_4.c @@ -0,0 +1,60 @@ +/* when -fstrict-flex-array=0, all trailing arrays are treated as + flexible arrays. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-array=0" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4]; +}; + +struct trailing_array_2 { + int a; + int b; + int c[1]; +}; + +struct trailing_array_3 { + int a; + int b; + int c[0]; +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), -1); + expect(__builtin_object_size(trailing_1->c, 1), -1); + expect(__builtin_object_size(trailing_0->c, 1), -1); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr101836_5.c b/gcc/testsuite/gcc.dg/pr101836_5.c new file mode 100644 index 00000000000..2f6b5f7ae1f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_5.c @@ -0,0 +1,60 @@ +/* -fno-strict-flex-array is aliased to -fstrict-flex-array=0, + all trailing arrays are treated as flexible array. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-strict-flex-array" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4]; +}; + +struct trailing_array_2 { + int a; + int b; + int c[1]; +}; + +struct trailing_array_3 { + int a; + int b; + int c[0]; +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), -1); + expect(__builtin_object_size(trailing_1->c, 1), -1); + expect(__builtin_object_size(trailing_0->c, 1), -1); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/strict-flex-array-2.c b/gcc/testsuite/gcc.dg/strict-flex-array-2.c new file mode 100644 index 00000000000..326ddcfeda5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strict-flex-array-2.c @@ -0,0 +1,60 @@ +/* test the combination of attribute strict_flex_array and option + -fstrict-flex-array: when both attribute and option specified, + attribute will have higher priority. */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-array=3" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4] __attribute__ ((strict_flex_array (0))); +}; + +struct trailing_array_2 { + int a; + int b; + int c[1] __attribute__ ((strict_flex_array (1))); +}; + +struct trailing_array_3 { + int a; + int b; + int c[0] __attribute__ ((strict_flex_array (2))); +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), -1); + expect(__builtin_object_size(trailing_1->c, 1), -1); + expect(__builtin_object_size(trailing_0->c, 1), -1); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/strict-flex-array-3.c b/gcc/testsuite/gcc.dg/strict-flex-array-3.c new file mode 100644 index 00000000000..990c5bb6223 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strict-flex-array-3.c @@ -0,0 +1,60 @@ +/* test the combination of attribute strict_flex_array and option + -fstrict-flex-array: when both attribute and option specified, + attribute will have higher priority. */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-array=0" } */ + +#include + +#define expect(p, _v) do { \ + size_t v = _v; \ + if (p == v) \ + printf("ok: %s == %zd\n", #p, p); \ + else \ + { \ + printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + __builtin_abort (); \ + } \ +} while (0); + +struct trailing_array_1 { + int a; + int b; + int c[4] __attribute__ ((strict_flex_array (1))); +}; + +struct trailing_array_2 { + int a; + int b; + int c[1] __attribute__ ((strict_flex_array (2))); +}; + +struct trailing_array_3 { + int a; + int b; + int c[0] __attribute__ ((strict_flex_array (3))); +}; +struct trailing_array_4 { + int a; + int b; + int c[]; +}; + +void __attribute__((__noinline__)) stuff( + struct trailing_array_1 *normal, + struct trailing_array_2 *trailing_1, + struct trailing_array_3 *trailing_0, + struct trailing_array_4 *trailing_flex) +{ + expect(__builtin_object_size(normal->c, 1), 16); + expect(__builtin_object_size(trailing_1->c, 1), 4); + expect(__builtin_object_size(trailing_0->c, 1), 0); + expect(__builtin_object_size(trailing_flex->c, 1), -1); +} + +int main(int argc, char *argv[]) +{ + stuff((void *)argv[0], (void *)argv[0], (void *)argv[0], (void *)argv[0]); + + return 0; +} diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc index 4eb454a4a33..90710ecba72 100644 --- a/gcc/tree-object-size.cc +++ b/gcc/tree-object-size.cc @@ -604,9 +604,9 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, else if (var != pt_var && TREE_CODE (pt_var) == MEM_REF) { tree v = var; - /* For &X->fld, compute object size only if fld isn't the last - field, as struct { int i; char c[1]; } is often used instead - of flexible array member. */ + bool is_flexible_array_mem_ref = false; + /* For &X->fld, compute object size if fld isn't a flexible array + member. */ while (v && v != pt_var) switch (TREE_CODE (v)) { @@ -633,6 +633,9 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, v = NULL_TREE; break; } + is_flexible_array_mem_ref + = array_at_struct_end_p (v) + && !DECL_NOT_FLEXARRAY (TREE_OPERAND (v, 1)); while (v != pt_var && TREE_CODE (v) == COMPONENT_REF) if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) != UNION_TYPE @@ -645,12 +648,9 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) == RECORD_TYPE) { - tree fld_chain = DECL_CHAIN (TREE_OPERAND (v, 1)); - for (; fld_chain; fld_chain = DECL_CHAIN (fld_chain)) - if (TREE_CODE (fld_chain) == FIELD_DECL) - break; - - if (fld_chain) + /* compute object size only if v is not a + flexible array member. */ + if (!is_flexible_array_mem_ref) { v = NULL_TREE; break;