From patchwork Wed Sep 7 00:28:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qing Zhao X-Patchwork-Id: 57445 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 A5420384D18D for ; Wed, 7 Sep 2022 00:29:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A5420384D18D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1662510573; bh=/yAb9MrC3E5SgRZLvAECjKcQcpWR4q6O41Jwyppdtfo=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=t6e71Shh5i44jHD9JpbYcrnNpXulEKYw5f+ve2FGrN2FkI/Em5dSLB3nKMvo4xDC+ 13mF64FIO3b1GrgfGxPZ/BRdA12rXMrLkc+Qe6/8Nrmqc1JOYHXKlRgp/bYp9paKUc UQ/QjCh4iosDgzVXvuJUzV6T/6NIFG4Zh5QJCTzk= 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 7A78B385084C for ; Wed, 7 Sep 2022 00:28:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7A78B385084C Received: from pps.filterd (m0246617.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 286LdH3B015737; Wed, 7 Sep 2022 00:28:55 GMT Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3jbyftqc60-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 07 Sep 2022 00:28:54 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.5/8.17.1.5) with ESMTP id 287030OL023662; Wed, 7 Sep 2022 00:28:53 GMT Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2109.outbound.protection.outlook.com [104.47.58.109]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3jbwc9vav7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 07 Sep 2022 00:28:53 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=l6J+2npxS3Ffdw/g9Bx268upRrP02yBL18w9ODClLRI9rDsN4zngkTIuA07zpSpiYcDtsjh+INk9JSGZ5v0HrLOpoRZLgsiCMY3aPM419jtbVCQKT/Ms6A/v3mo3G1vAkxrpn8vJ0oPUMQfz4XmDst+oAtcooOhOrL7ZNrOirLrwpolApIYFYnCSEDAElplmu/HS6sBgp877xGAQ5/R74GVvDYfbTHx9RQMWjJxZkwzEtuRjl5rvUNRj3AINsrhSFgNQq6Vhuhi7Rrns+8BD0QTF73K3nhZxLicadUNAO38VmftmAdHZ8zrserPmLHiOeQSXNiTNcneY/k+7Z2r57A== 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=/yAb9MrC3E5SgRZLvAECjKcQcpWR4q6O41Jwyppdtfo=; b=iM3KqkeTALA80Z2pkRvpZQlgpDurwbFYDiN8Nvs5azvpwaFZQqPRoHgk3vM9rO9BtwpoFJpB9s9L0fcGH7EP9tDql8N2BSKf55DsuYumi8u30odx9vwwrc5NabMrSj0JcnAJMIIjgAvA/oZMDCfgVRkPhiJmEAHvUtBXfDJnSDPdFnLlzRXbAqRo5/Pn43zpqwCO4DkEz2h/YNqxIiH8+9dn4uBckrylOuEdTGoxqKHfBwMLYNwx6RJwHbbBg/O21ur7P2kh4YcT04KtS1TYCbnOsYeo838khTtCfU+ImWuALyEHGEiFfARZD4ud51d5n5mlDbOvj5zfribt3emBsQ== 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 CY8PR10MB6801.namprd10.prod.outlook.com (2603:10b6:930:98::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5588.10; Wed, 7 Sep 2022 00:28:50 +0000 Received: from CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::84af:9275:f1d7:de1]) by CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::84af:9275:f1d7:de1%6]) with mapi id 15.20.5588.018; Wed, 7 Sep 2022 00:28:50 +0000 To: gcc-patches@gcc.gnu.org Subject: [GCC13][Patch][V4][PATCH 1/2] Add a new option -fstrict-flex-arrays[=n] and new attribute strict_flex_arrays Date: Wed, 7 Sep 2022 00:28:16 +0000 Message-Id: <20220907002817.236178-2-qing.zhao@oracle.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220907002817.236178-1-qing.zhao@oracle.com> References: <20220907002817.236178-1-qing.zhao@oracle.com> X-ClientProxiedBy: SJ0PR03CA0331.namprd03.prod.outlook.com (2603:10b6:a03:39c::6) To CH2PR10MB4344.namprd10.prod.outlook.com (2603:10b6:610:af::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 62c385f5-7d18-4184-752d-08da9067ef84 X-MS-TrafficTypeDiagnostic: CY8PR10MB6801:EE_ X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: PJjzmgM6jxbwGXltxlfiA5/x50IgoydgJsYZtDr9+L6zM7LJUm+HdVtTVi5x6/edUiIDn3RSJF0wNagZ/RsAe0vqkwyakE2n3M4DJQY/LW+TkE3JBZzslH2g+Cs/L1fAD1Vm6basvcNoDqwl+gUHy3C3QMz7tM8nD8Ov4ieyF24bVGNMJlmz5B2I/kEIiNk8tFQD5WTTuLsivT5e/nc1sMlgk/GZsP5fnFkkTb/XQNqxi59CBYUucU+noOqIR8iZYU6GKmf+5wodhN4yT/c6qoVrqVBpKB3QY7bjUj4nkyhewtAXkJmucwFurh9iQ+G13XDqrD3YYEKuojhNDWgkb8HK9jWsKPl+kVSO6Od4z3qHSGaAE5LTNSwOcSt473jtXBQvjshI4UCtoDC9/GCb0UjjiFtWMLF1xaZNoEO2MliZd8m8Qr/oUGEiBlrteSiCu0Ss5dJ2b+FNTAzC2BkecxXrTfQOiVZJDEiOp4LXYHiSagKXFGFEqEO2lc70rAMlMvCJLeScjOJIELAkBX07HMsdarqphqsP9JOZFD2KX5kkW1ZlO/SigxHSTw/t0gXK1k2M4RmVsxosPsHxWHY8P138RWBKq+W7bJctb0xwFQQVldCgc3cAUm+4Wx3LeJcSihnRyleEnz1Oz45xspZufERWGdItB/AtEQvOL7J7Vcd2VuNPs2ZtbXaY5nULlDVU1pr73hh8WLfuUrfbHu5FwZ7wwEgPelrl5JBnhU9cFKQ= 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)(396003)(39860400002)(376002)(366004)(136003)(346002)(6666004)(478600001)(6506007)(26005)(1076003)(6486002)(41300700001)(6512007)(186003)(83380400001)(2616005)(5660300002)(2906002)(30864003)(44832011)(8936002)(6916009)(107886003)(4326008)(66476007)(8676002)(66946007)(66556008)(316002)(86362001)(38100700002)(84970400001)(36756003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: KkYw2uFQWYnfX0+znvcZnlJDKGB9PGnGvBpOYRPQzYgJSikJWExR3xzTnxHrcPhvzC4vqFex6BboD+CXyrHLCXajanRWOd0v5ZqsgBM+LDsCi9S+/DJEkrsgqaBe/iewu+0s0fQJ7Dre8nwp4Fdq9GNXK5fvbIAmHfoeYl/XXue6tImoMUNRAErCN+97OLhgM2WiahLozB/fpzkZcfPVHLzw6ypN5exhNC0xYPhfyGHzWomFFjpRxHRkU8ndyqfT+3VScjj4gxx5nfoUA/+QBof9cNesbn91G4dMm7l0WeSaw8ehY7dBU0D6x+UX3xTkBzGLImySLplgluaMyo9slCUd3NVEEr2ZeW+N7ivjUIEkDFv06GlnAyMupZ7zgDZtrTxfrYGTpTs8lTi7RNpqxMR7Gc1bW2nj27RFkKunJEDeYTCu9R4eERKZxPXVHITbywbMbJzjrMBHc0ySb/2MCjBvYoiH7eqgSEImAXpynqSgwDH8i/ZS6DDWis+1t2F8wsJBXJfBs2cdovkyCUOAXF44AOKTrwjOtTyrUi9COENNpZTJIM5ITHu9HOVlsPsaeXqWWcEuPPMMAjZTAg4tS+IMOsEcT2hMJEgALRYPhK0syAS8Gpfxf7fpMD7Ff/ucyMETlNkVtpLlbZX03AcF4HgIFmHj2j3AweUfgF2kKeDHd2R/JWUR78LqmBmA3FqY/LyjXA2j+2q0XDjM4JdOzTgxgJb1batRyzJ9ScSOeIjrDPaVkWZoZVE1kDWzUddwuO800q3Y9XkF7c2NKGfrTsBjKii99YCypNCsXs6mELvlrnOKOaKDy3K3C/0Nuhg9FCMhLbq/W1G9z9kAYgdxCnh+wcDgUoLbsxPiJUt5QAbokJgb9RmUb805KXW1So8M5AiShWLsS+TrsCKfD9+vtR0jCFxpFiKKOMvmyfG94iGCoeE8uZ6J7G7Ulq5OTAGG9XkIQLyrJNNZw3roSkj4lpJl2cdwMqs0SleauD1RMH9vz134AfpNCu2x91IdtGJ9yiaas2+1OiEIgM7QDITOedhev5gDFxDnb32yXcI21HCY5XSvSBqBf5wLg5k0Oguq2YVmfgqqwLYsvB0IczjIRr8sl5/nvUFc4Ar38OqZ0V0eXmW2gQrmwSDB6DMJ8r72/IL5ijnzX/+odfk8BC418jGlpqgnK66DTPOa40H81DqOE8bQDBe8PpK3MP3AeVamwUo/SdVU+vnFDpRbMZyNioWT829zrRLATk2YgMSFPQdigYUeWeqWuvG8LDm3obyUWLF9xW4AhNlGK8aFs35DHqY8csI0VozuayNcmFUDHE5/w6ZKUbu6ZzylcJygwcT3WEAUW8qkq6I0G9RO9czh5hu9MG8JlR1oVv34u+HOj37SE7U3X/r5ZAbowJMxBPyaX0qRLIqhthNQqkYgmmDdoicRXIW5QqIrT3XWSobReTgBuOjFdIa7NXU4l68EVf2swpVnb77gfZGHHZujfPEJ//7NvYYytR13hvG6rU5QK8rBeddJUxEa0Y44wSpxUuZkRBpf8E5M4NUGMELXiDIjVxfxqLcU2yk3K9hLks1PsfzI7nzeocKTRNneaUOaatNB X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 62c385f5-7d18-4184-752d-08da9067ef84 X-MS-Exchange-CrossTenant-AuthSource: CH2PR10MB4344.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Sep 2022 00:28:50.3156 (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: MoZDIzT+RMhOdSxzoSRUbrrHx4Q2LSb/DpkZsi7wBjg89lvDcNNybI3+bbRqeA3c5Rmhh4JERZ0lUj8lvkIm1Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY8PR10MB6801 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-09-06_11,2022-09-06_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 mlxscore=0 adultscore=0 malwarescore=0 mlxlogscore=999 bulkscore=0 suspectscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2207270000 definitions=main-2209070000 X-Proofpoint-ORIG-GUID: v_TRDi455hrPWZn9mQZZhtR49MfNFy-U X-Proofpoint-GUID: v_TRDi455hrPWZn9mQZZhtR49MfNFy-U X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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@redhat.com, rguenther@suse.de, msebor@gmail.com, joseph@codesourcery.com, keescook@chromium.org Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Add the following new option -fstrict-flex-arrays[=n] and a corresponding attribute strict_flex_arrays to GCC: '-fstrict-flex-arrays' Treat the trailing array of a structure as a flexible array member in a stricter way. The positive form is equivalent to '-fstrict-flex-arrays=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-arrays=0', which is the least strict. All trailing arrays of structures are treated as flexible array members. '-fstrict-flex-arrays=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_arrays' 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_arrays' attribute (*note Variable Attributes::). 'strict_flex_arrays (LEVEL)' The 'strict_flex_arrays' 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 the '-fstrict-flex-arrays'. 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_arrays_attribute): New function. (c_common_attribute_table): New item for strict_flex_arrays. * c.opt: (fstrict-flex-arrays): New option. (fstrict-flex-arrays=): New option. gcc/c/ChangeLog: * c-decl.cc (flexible_array_member_type_p): New function. (one_element_array_type_p): Likewise. (zero_length_array_type_p): Likewise. (add_flexible_array_elts_to_size): Call new utility routine flexible_array_member_type_p. (is_flexible_array_member_p): New function. (finish_struct): Set the new DECL_NOT_FLEXARRAY flag. gcc/cp/ChangeLog: * module.cc (trees_out::core_bools): Stream out new bit decl_not_flexarray. (trees_in::core_bools): Stream in new bit decl_not_flexarray. gcc/ChangeLog: * doc/extend.texi: Document strict_flex_arrays attribute. * doc/invoke.texi: Document -fstrict-flex-arrays[=n] option. * print-tree.cc (print_node): Print new bit decl_not_flexarray. * tree-core.h (struct tree_decl_common): New bit field decl_not_flexarray. * tree-streamer-in.cc (unpack_ts_decl_common_value_fields): Stream in new bit decl_not_flexarray. * tree-streamer-out.cc (pack_ts_decl_common_value_fields): Stream out new bit decl_not_flexarray. * tree.cc (array_at_struct_end_p): Update it with the new bit field decl_not_flexarray. * tree.h (DECL_NOT_FLEXARRAY): New flag. gcc/testsuite/ChangeLog: * g++.dg/strict-flex-array-1.C: New test. * 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 | 130 +++++++++++++++++++-- gcc/cp/module.cc | 2 + gcc/doc/extend.texi | 25 ++++ gcc/doc/invoke.texi | 27 ++++- gcc/print-tree.cc | 8 +- gcc/testsuite/g++.dg/strict-flex-array-1.C | 31 +++++ gcc/testsuite/gcc.dg/strict-flex-array-1.c | 31 +++++ gcc/tree-core.h | 5 +- gcc/tree-streamer-in.cc | 1 + gcc/tree-streamer-out.cc | 1 + gcc/tree.cc | 45 +++++-- gcc/tree.h | 14 ++- 14 files changed, 346 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/g++.dg/strict-flex-array-1.C 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 8bb80e251dc2..0becd4bbe8d2 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_arrays_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 *); @@ -368,6 +370,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_arrays", 1, 1, false, false, false, false, + handle_strict_flex_arrays_attribute, NULL }, { "weak", 0, 0, true, false, false, false, handle_weak_attribute, NULL }, { "noplt", 0, 0, true, false, false, false, @@ -2505,6 +2509,49 @@ handle_warn_if_not_aligned_attribute (tree *node, tree name, no_add_attrs, true); } +/* Handle a "strict_flex_arrays" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_strict_flex_arrays_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 4515664aa590..e053bd939559 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -2072,6 +2072,13 @@ fsized-deallocation C++ ObjC++ Var(flag_sized_deallocation) Init(-1) Enable C++14 sized deallocation support. +fstrict-flex-arrays +C C++ Common Alias(fstrict-flex-arrays=,3,0) + +fstrict-flex-arrays= +C C++ Common Joined RejectNegative UInteger Var(flag_strict_flex_arrays) Init(0) IntegerRange(0,3) +-fstrict-flex-arrays= 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 34f8feda897f..ee90808bcb0e 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -5005,6 +5005,41 @@ set_array_declarator_inner (struct c_declarator *decl, return decl; } +/* Determine whether TYPE is a ISO C99 flexible array memeber type "[]". */ +static bool +flexible_array_member_type_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 one-element array type "[1]". */ +static bool +one_element_array_type_p (const_tree type) +{ + if (TREE_CODE (type) != ARRAY_TYPE) + return false; + return integer_zerop (array_type_nelts (type)); +} + +/* Determine whether TYPE is a zero-length array type "[0]". */ +static bool +zero_length_array_type_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; +} + /* INIT is a constructor that forms DECL's initializer. If the final element initializes a flexible array field, add the size of that initializer to DECL's size. */ @@ -5019,10 +5054,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_type_p (type)) { complete_array_type (&type, elt, false); DECL_SIZE (decl) @@ -8710,6 +8742,81 @@ 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_arrays; + 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_type_p (TREE_TYPE (x)); + bool is_one_element_array = one_element_array_type_p (TREE_TYPE (x)); + bool is_flexible_array = flexible_array_member_type_p (TREE_TYPE (x)); + + unsigned int strict_flex_array_level = flag_strict_flex_arrays; + + tree attr_strict_flex_array = lookup_attribute ("strict_flex_arrays", + DECL_ATTRIBUTES (x)); + /* if there is a strict_flex_array attribute attached to the field, + override the flag_strict_flex_arrays. */ + 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. @@ -8771,6 +8878,11 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, bool saw_named_field = false; for (x = fieldlist; x; x = DECL_CHAIN (x)) { + /* whether this field is the last field of the structure or union. + for UNION, any field is the last field of it. */ + bool is_last_field = (DECL_CHAIN (x) == NULL_TREE) + || (TREE_CODE (t) == UNION_TYPE); + if (TREE_TYPE (x) == error_mark_node) continue; @@ -8809,10 +8921,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_type_p (TREE_TYPE (x))) { if (TREE_CODE (t) == UNION_TYPE) { @@ -8820,7 +8929,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"); @@ -8840,6 +8949,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/cp/module.cc b/gcc/cp/module.cc index f27f4d091e5e..75ee2514f66b 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -5414,6 +5414,7 @@ trees_out::core_bools (tree t) WB (t->decl_common.decl_by_reference_flag); WB (t->decl_common.decl_read_flag); WB (t->decl_common.decl_nonshareable_flag); + WB (t->decl_common.decl_not_flexarray); } if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS)) @@ -5558,6 +5559,7 @@ trees_in::core_bools (tree t) RB (t->decl_common.decl_by_reference_flag); RB (t->decl_common.decl_read_flag); RB (t->decl_common.decl_nonshareable_flag); + RB (t->decl_common.decl_not_flexarray); } if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS)) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 0fedab96610b..62328d77c78c 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7459,6 +7459,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_arrays} variable attribute +@item strict_flex_arrays (@var{level}) +The @code{strict_flex_arrays} 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 (@samp{[]}), 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 (@samp{[0]}) or one-size +array as flexible array member (@samp{[1]}): +When @var{level} is 1, the trailing array is treated as a flexible array member +when it is declared as either @samp{[]}, @samp{[0]}, or @samp{[1]}; +When @var{level} is 2, the trailing array is treated as a flexible array member +when it is declared as either @samp{[]}, or @samp{[0]}. + +This attribute can be used with or without the @option{-fstrict-flex-arrays}. +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 9d662e353163..db1a68cd545c 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-arrays[=@var{n}] @gol +-fsso-struct=@var{endianness}} @item C++ Language Options @xref{C++ Dialect Options,,Options Controlling C++ Dialect}. @@ -2826,6 +2827,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-arrays +@opindex fstrict-flex-arrays +@opindex fno-strict-flex-arrays +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-arrays=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-arrays=0}, which is the +least strict. All trailing arrays of structures are treated as flexible array +members. + +@item -fstrict-flex-arrays=@var{level} +@opindex fstrict-flex-arrays=@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_arrays} 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_arrays} 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/print-tree.cc b/gcc/print-tree.cc index 6d45a4a59669..58a98250cc4f 100644 --- a/gcc/print-tree.cc +++ b/gcc/print-tree.cc @@ -517,8 +517,12 @@ print_node (FILE *file, const char *prefix, tree node, int indent, fprintf (file, " align:%d warn_if_not_align:%d", DECL_ALIGN (node), DECL_WARN_IF_NOT_ALIGN (node)); if (code == FIELD_DECL) - fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED, - DECL_OFFSET_ALIGN (node)); + { + fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED, + DECL_OFFSET_ALIGN (node)); + fprintf (file, " decl_not_flexarray: %d", + DECL_NOT_FLEXARRAY (node)); + } if (code == FUNCTION_DECL && fndecl_built_in_p (node)) { diff --git a/gcc/testsuite/g++.dg/strict-flex-array-1.C b/gcc/testsuite/g++.dg/strict-flex-array-1.C new file mode 100644 index 000000000000..cd6a65d2b7e6 --- /dev/null +++ b/gcc/testsuite/g++.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_arrays (1))); /* { dg-error "'strict_flex_arrays' attribute may not be specified for 'x'" } */ + +struct trailing { + int a; + int c __attribute ((strict_flex_arrays)); /* { dg-error "wrong number of arguments specified for 'strict_flex_arrays' attribute" } */ +}; + +struct trailing_1 { + int a; + int b; + int c __attribute ((strict_flex_arrays (2))); /* { dg-error "'strict_flex_arrays' 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_arrays (d))); /* { dg-error "'strict_flex_arrays' attribute argument not an integer" } */ +}; + +struct trailing_array_3 { + int a; + int b; + int c[0] __attribute ((strict_flex_arrays (5))); /* { dg-error "'strict_flex_arrays' attribute argument '5' is not an integer constant between 0 and 3" } */ +}; 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 000000000000..cd6a65d2b7e6 --- /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_arrays (1))); /* { dg-error "'strict_flex_arrays' attribute may not be specified for 'x'" } */ + +struct trailing { + int a; + int c __attribute ((strict_flex_arrays)); /* { dg-error "wrong number of arguments specified for 'strict_flex_arrays' attribute" } */ +}; + +struct trailing_1 { + int a; + int b; + int c __attribute ((strict_flex_arrays (2))); /* { dg-error "'strict_flex_arrays' 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_arrays (d))); /* { dg-error "'strict_flex_arrays' attribute argument not an integer" } */ +}; + +struct trailing_array_3 { + int a; + int b; + int c[0] __attribute ((strict_flex_arrays (5))); /* { dg-error "'strict_flex_arrays' 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 80c2bcb333dd..18bd6d82a32d 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -1823,7 +1823,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-streamer-in.cc b/gcc/tree-streamer-in.cc index 219cf5e7ef45..57923da3741e 100644 --- a/gcc/tree-streamer-in.cc +++ b/gcc/tree-streamer-in.cc @@ -261,6 +261,7 @@ unpack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) else SET_DECL_FIELD_ABI_IGNORED (expr, val); expr->decl_common.off_align = bp_unpack_value (bp, 8); + DECL_NOT_FLEXARRAY (expr) = (unsigned) bp_unpack_value (bp, 1); } else if (VAR_P (expr)) diff --git a/gcc/tree-streamer-out.cc b/gcc/tree-streamer-out.cc index 9b114dc05bb1..68a2818a9f93 100644 --- a/gcc/tree-streamer-out.cc +++ b/gcc/tree-streamer-out.cc @@ -229,6 +229,7 @@ pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) else bp_pack_value (bp, DECL_FIELD_ABI_IGNORED (expr), 1); bp_pack_value (bp, expr->decl_common.off_align, 8); + bp_pack_value (bp, DECL_NOT_FLEXARRAY (expr), 1); } else if (VAR_P (expr)) diff --git a/gcc/tree.cc b/gcc/tree.cc index 2f488e4467c4..e4664eab54ef 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -12688,14 +12688,30 @@ array_ref_up_bound (tree exp) } /* Returns true if REF is an array reference, component reference, - or memory reference to an array at the end of a structure. - If this is the case, the array may be allocated larger - than its upper bound implies. */ + or memory reference to an array whose actual size might be larger + than its upper bound implies, there are multiple cases: + A. a ref to a flexible array member at the end of a structure; + B. a ref to an array with a different type against the original decl; + for example: + short a[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + (*((char(*)[16])&a[0]))[i+8] + + C. a ref to an array that was passed as a parameter; + for example: + + int test (uint8_t *p, uint32_t t[1][1], int n) { + for (int i = 0; i < 4; i++, p++) + t[i][0] = ...; + + FIXME, the name of this routine need to be changed to be more accurate. */ bool array_at_struct_end_p (tree ref) { - tree atype; + /* the TYPE for this array referece. */ + tree atype = NULL_TREE; + /* the FIELD_DECL for the array field in the containing structure. */ + tree afield_decl = NULL_TREE; if (TREE_CODE (ref) == ARRAY_REF || TREE_CODE (ref) == ARRAY_RANGE_REF) @@ -12705,7 +12721,10 @@ array_at_struct_end_p (tree ref) } else if (TREE_CODE (ref) == COMPONENT_REF && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 1))) == ARRAY_TYPE) - atype = TREE_TYPE (TREE_OPERAND (ref, 1)); + { + atype = TREE_TYPE (TREE_OPERAND (ref, 1)); + afield_decl = TREE_OPERAND (ref, 1); + } else if (TREE_CODE (ref) == MEM_REF) { tree arg = TREE_OPERAND (ref, 0); @@ -12717,6 +12736,7 @@ array_at_struct_end_p (tree ref) if (tree fld = last_field (argtype)) { atype = TREE_TYPE (fld); + afield_decl = fld; if (TREE_CODE (atype) != ARRAY_TYPE) return false; if (VAR_P (arg) && DECL_SIZE (fld)) @@ -12770,13 +12790,16 @@ array_at_struct_end_p (tree ref) ref = TREE_OPERAND (ref, 0); } - /* The array now is at struct end. Treat flexible arrays as + gcc_assert (!afield_decl + || (afield_decl && TREE_CODE (afield_decl) == FIELD_DECL)); + + /* The array now is at struct end. Treat flexible array member as always subject to extend, even into just padding constrained by an underlying decl. */ if (! TYPE_SIZE (atype) || ! TYPE_DOMAIN (atype) || ! TYPE_MAX_VALUE (TYPE_DOMAIN (atype))) - return true; + return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; /* If the reference is based on a declared entity, the size of the array is constrained by its given domain. (Do not trust commons PR/69368). */ @@ -12798,9 +12821,9 @@ array_at_struct_end_p (tree ref) if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (atype))) != INTEGER_CST || TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (atype))) != INTEGER_CST || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (atype))) != INTEGER_CST) - return true; + return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; if (! get_addr_base_and_unit_offset (ref_to_array, &offset)) - return true; + return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; /* If at least one extra element fits it is a flexarray. */ if (known_le ((wi::to_offset (TYPE_MAX_VALUE (TYPE_DOMAIN (atype))) @@ -12808,12 +12831,12 @@ array_at_struct_end_p (tree ref) + 2) * wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (atype))), wi::to_offset (DECL_SIZE_UNIT (ref)) - offset)) - return true; + return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; return false; } - return true; + return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; } /* Return a tree representing the offset, in bytes, of the field referenced diff --git a/gcc/tree.h b/gcc/tree.h index 266e24a05633..81076b045003 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3005,6 +3005,12 @@ 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. This is only valid for the last array type field of a + structure. */ +#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. */ @@ -5543,10 +5549,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 From patchwork Wed Sep 7 00:28:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qing Zhao X-Patchwork-Id: 57446 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 1AF613850223 for ; Wed, 7 Sep 2022 00:29:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1AF613850223 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1662510575; bh=T5a6I+KyxZ35QBsSB+3XyNmSGjosNjwMk4BiKVDTmb4=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=OooUVgdj862jLHIlhe2XMpdP+sWQJI5Fv2d7UYisLRpB45i8jeVftJ3lw/WocDTO+ MDQNrf9i+IqLEBgrnV1H09R/YkCV0V5jSuRvv8NbtG/xFGGgfaqFH9QatZUIYJdZBZ sE1LE1NPJpUnIMwI9ugs+rw2sx+pHM8uWFpZjHD4= 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 78DC0385086A for ; Wed, 7 Sep 2022 00:29:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 78DC0385086A Received: from pps.filterd (m0246617.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 286LdH3C015737; Wed, 7 Sep 2022 00:28:58 GMT Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3jbyftqc62-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 07 Sep 2022 00:28:58 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.5/8.17.1.5) with ESMTP id 286NKuab039726; Wed, 7 Sep 2022 00:28:57 GMT Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2109.outbound.protection.outlook.com [104.47.58.109]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3jbwc9vt8m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 07 Sep 2022 00:28:56 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FsZfqv8hcm8jPZ/pWM7zREjr4VyKQOUgvr37b04zuWcIIjFvXWZDy1ppAruHzxaGVQgGYT3o6eIbMZOeUC6s26eXVzKs2K3neMijwavyVwp159gdCrie6uGCPsDrp+j4+1duwjPdIZD8iiD1cDrQRJ5ywNQfIrkaC8YO6ccKL8wfzusJhObpnK58sbgb3+NIZhgxbDoBZSQ1juZrF4/Ip5Fps8xARQqyOPjf9+m8Os3qyQ+j+39sq0649FIXXGMoDA4IWamcHNZeEmxaBgm9rvEfUBP5koVM5Lz8yzkzrnmsrZ5mlf2VLAxjHLAR1bG7UxEd3I78eMycG3NcHHqcIQ== 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=T5a6I+KyxZ35QBsSB+3XyNmSGjosNjwMk4BiKVDTmb4=; b=RmvLkitYsGoMwxuBHrMuKNFVgBNprf0ta/M7gP3uTHF4Lnu3htOYBYSfU9Q1SNBqOKcsPjIdP/NHq6jn+Oskp17xC4JxA0jTXBlRQLEssdbxcaTCZ1s/65WnrYnQ+2B3B/hPql6vEMjDks4rlK9P0tCSpyeJ2DoDFVLUfk6uFltStnAupzUSw4ZqfbcVbrvBOtl/x6JXw3fz19XsTlq0sGEF1GJuoqc4rPpG7BhgamdvaDhn9MHPYGQOzcImpe2L+WSpQYCuPkeLOywA/zxqO3WLcuJRqaCAB+j+R4zSOjhNOp2Q+JyEBlkygA2nhNMDi1bGdrmqPzO7OTUFCYFooA== 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 CY8PR10MB6801.namprd10.prod.outlook.com (2603:10b6:930:98::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5588.10; Wed, 7 Sep 2022 00:28:54 +0000 Received: from CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::84af:9275:f1d7:de1]) by CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::84af:9275:f1d7:de1%6]) with mapi id 15.20.5588.018; Wed, 7 Sep 2022 00:28:54 +0000 To: gcc-patches@gcc.gnu.org Subject: [GCC13][Patch][V4][PATCH 2/2] Use array_at_struct_end_p in __builtin_object_size [PR101836] Date: Wed, 7 Sep 2022 00:28:17 +0000 Message-Id: <20220907002817.236178-3-qing.zhao@oracle.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220907002817.236178-1-qing.zhao@oracle.com> References: <20220907002817.236178-1-qing.zhao@oracle.com> X-ClientProxiedBy: BYAPR21CA0030.namprd21.prod.outlook.com (2603:10b6:a03:114::40) To CH2PR10MB4344.namprd10.prod.outlook.com (2603:10b6:610:af::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: f3f0bfc1-9e7d-4d91-a963-08da9067f20a X-MS-TrafficTypeDiagnostic: CY8PR10MB6801:EE_ X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: KtBfZko7Xn4LjHWus0e4nIzZuTEE4cw20C/N4wphL7mvoGLrIkF3WqmDyuLAe5vRhJSJtKlqcz2pkQmHRkRV+9djsb/7UCA9z9O6eWVnnYpsYnW0JhhAwVFsKPxrMxSr9d8OwfRO5vnQn/728l0CLTeWtBEF+b1bh408wTPeSxYHB4qAo69UFfL/zuMXrZRS4hoFAiF78bjXOm/Of2vXyCwkTUSVJl0kP3snRWLZ3CSYSNLQjGEasvnyUQ/WPjnb+KJbobEva/zWuMUA11B0DZucTJOQcUHQF8D1TBQ4zhlxAF6WXC7I59b9HH1Pww7yTswpMQ7itb1u5bSvtKciFv6k3g+kNMnX4bskMYobEH/mqqdbk63Fn7Q0k2fVcquJdcZxiqIV/JV54Qf7UZySCGrztXmHjQ4TcSP9GJ7HaLjRPTTdUaFcqhTPOsXxy9fvfb93nsWia/Rq82oyJJMPuM2v7rrK9KZr157Lsm+BbnOp3Q9QJ0UA/rITepNk15e0p7FnoLG+zv8SPxbl8cQTbt07DOmLAaiBw5yeBcibLTJcBS7dz8rSII/eSqmTcEN1QSAXVEQZBqvJ6WRsJe4AuPhePZvnHMqJz/n/kC/8pB16kuk4EPnZqQ60f1EPYniO0yOd161hWDYYeP62czwko+H82wWb2AKM7oW1lAt67b29dG/fR3Iif12NZRBzxLfCiJH8MyMtAWU1f4fc6pb4DaMj6Lc8Mvk2ZRg3P9SrIcJ9TsvWOsxJgaJC7rHZxNDf/NYyToh+cD4ktxx/pqjCLg== 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)(396003)(39860400002)(376002)(366004)(136003)(346002)(6666004)(478600001)(6506007)(26005)(1076003)(6486002)(41300700001)(6512007)(186003)(83380400001)(2616005)(5660300002)(2906002)(30864003)(44832011)(8936002)(6916009)(107886003)(4326008)(66476007)(8676002)(66946007)(66556008)(316002)(86362001)(38100700002)(84970400001)(36756003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: mvcdanKlf9+IISS65XrT4iTvO2WbKdRehcv8I4mgn6hNnWoX2BXoU+ayrt+jdpV4FEGtxOpeGgvIFPB52+wKcddwH/OG0ICiUNiU/VAS6gfHgY54LVrzY9Yw9quuYzVaqwmvU2f0x6rDc0MOD124EH6PeNNHnd7AQ/YJecotg3EFyc8UjUlw26PkY6mTNkV618eT+svdog65GBRE+BJi6b1Ao9fuhW6EAb0uAQ2TTf1Yya8s4Cynay8B8XJNwiyupqYxVgN8p4Ybq/QMCPm4bn+oSq+dNL1Zx+xa95LxTog6vMxOf02nmO59p7zKOs4Mzvq3iOmXotvduqwjRksOi0PTDgWN9MmVEYE085uNOB3qTkZ8GHyOV5NwY/GOsnWvSYhgCgbn3joYXRQZnuyhS9vYlVaNQExH9t2A0wONvNZ1wQQtvjwZlQ/0+cncnOewL9I2HyrVo1cvjeX+3ve0WvWRVhDyHKKMAnRTLGCoTLiZUJ5n/Rdhl7gKH4zMnyrmS7MgRxs8FOqBhgR3Bq+1cA9YgTpkPniHwDjdnsuFy5ZGvtgzgu6V0SXBZ509zK94fiLvxab8Gmw18qh4/cQXp5YETwgd6U4boZ6ILd+hqw41odI/4rF7KGcekLFbhdaYfcVS/c7dRRqZMoOSCowTViLpc4XD6Qp3jv7NSzpOISFdWTyV2M/kkuwk4cOZCmZQS6OtirBCGy0eW5WrHjY0m0eqhD4KFo8T/CL9rQy0a1Dy0HA22KSMFAPvtQ9HOp7lrQxYFcg3yOul6KPsI2Nh/G2I5YAhSKZzJrBfDqhNikZcw5lFJ0IcmmzVsIwhoe01jAFe/+5cdzRLWbANn/T1f0Dxlg0gH9tlkPQtMQPJIMsy7LbvkMqZWblcuMwx6FjibkwSyDYvvYjWKN5gO7TnMmR28bd9MqyaEUM7J20S6OTmJMt3tKicO2f91qXCMtQ/Z2hVP5HT2uE8M5BZAzm2bbsuTmGO1+Brsat0w6cfER0qMXj+uEW34eAXD4d09CqVeSEHVYG16bIRosBWpNJz/fpu9cw6HBMCKrbqo64F726IhRoUGzUsYi0BxXP4feCuzcVRs78KW+bm5dM274YurilPfc0nH2EZZ6MN3rRBjHArheJxzDlWOrUkNztLXLWPlweCs6Q3d2uk0S/l1Q3R2MP/OYQc5q8djV+MElP1CU9vUSqBg5QlYA82t5FQhmHNVaMZsIaREaDVDjFw+GiQbRFE3iRYH3lT1oec6/No0ZiDSEboF5f9jZFiXxQuETP5LEV+leMWZv4PU61rX89qWsgM5nMvvU3s2FBf5UbaO8oPXIDuJbeeawEWCfO7DR+cNwL24UBJlKgqMOxAx9fcMT7itjPysDBuky/r8FfukP13xcpAgCY5H32RaNn240xToXzG3mPqg+AflrkwXnzEhNHVFHBDKqPt9xjADJWeagg7j57DM18E7ZmiN/6kl/RmEifPcJ/m6aJUHivHCs81Z8fjkvqxh5kS1Q5zVSSJvKDAHH9ksv+cbj6Uo+6iE0LfsFj1sqZs6BUE7LvTSdpFPickQ65EjN8Tf5S4VDnqASF9JE3L9YDc26EF6DlzBbm2 X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: f3f0bfc1-9e7d-4d91-a963-08da9067f20a X-MS-Exchange-CrossTenant-AuthSource: CH2PR10MB4344.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Sep 2022 00:28:54.5349 (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: 7UqZwMMbE6lHxB5zF+Djr0uKiXB1FNlWQ8Gw26HaDKpC549pnF4O9Up7Ut8ClGL4kRIhqsp7YHCU2molORnvSQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY8PR10MB6801 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-09-06_11,2022-09-06_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 mlxlogscore=941 phishscore=0 mlxscore=0 spamscore=0 malwarescore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2207270000 definitions=main-2209070000 X-Proofpoint-ORIG-GUID: UB_g0mZaHIr5OqBQRl1-LzrSjMFeNU8G X-Proofpoint-GUID: UB_g0mZaHIr5OqBQRl1-LzrSjMFeNU8G 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, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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@redhat.com, rguenther@suse.de, msebor@gmail.com, joseph@codesourcery.com, keescook@chromium.org Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Use array_at_struct_end_p 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 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 | 16 +++--- 9 files changed, 487 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 000000000000..efad02cfe899 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836.c @@ -0,0 +1,60 @@ +/* -fstrict-flex-arrays is aliased with -ftrict-flex-arrays=3, which is the + strictest, only [] is treated as flexible array. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays" } */ + +#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 000000000000..e2931ce1012e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_1.c @@ -0,0 +1,60 @@ +/* -fstrict-flex-arrays=3 is the strictest, only [] is treated as + flexible array. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays=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 000000000000..78974187721f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_2.c @@ -0,0 +1,60 @@ +/* When -fstrict-flex-arrays=2, only [] and [0] are treated as flexiable + arrays. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays=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 000000000000..0e69388e81fb --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_3.c @@ -0,0 +1,60 @@ +/* When -fstrict-flex-arrays=1, [], [0], and [1] are treated as flexible + arrays. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays=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 000000000000..e0025aa9a7b5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_4.c @@ -0,0 +1,60 @@ +/* when -fstrict-flex-arrays=0, all trailing arrays are treated as + flexible arrays. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays=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 000000000000..0ad8bbf693ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101836_5.c @@ -0,0 +1,60 @@ +/* -fno-strict-flex-arrays is aliased to -fstrict-flex-arrays=0, + all trailing arrays are treated as flexible array. */ +/* PR tree-optimization/101836 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-strict-flex-arrays" } */ + +#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 000000000000..e474b9ec43fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/strict-flex-array-2.c @@ -0,0 +1,60 @@ +/* test the combination of attribute strict_flex_arrays and option + -fstrict-flex-arrays: when both attribute and option specified, + attribute will have higher priority. */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays=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_arrays (0))); +}; + +struct trailing_array_2 { + int a; + int b; + int c[1] __attribute__ ((strict_flex_arrays (1))); +}; + +struct trailing_array_3 { + int a; + int b; + int c[0] __attribute__ ((strict_flex_arrays (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 000000000000..b45e7b32f6d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strict-flex-array-3.c @@ -0,0 +1,60 @@ +/* test the combination of attribute strict_flex_arrays and option + -fstrict-flex-arrays: when both attribute and option specified, + attribute will have higher priority. */ +/* { dg-do run } */ +/* { dg-options "-O2 -fstrict-flex-arrays=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_arrays (1))); +}; + +struct trailing_array_2 { + int a; + int b; + int c[1] __attribute__ ((strict_flex_arrays (2))); +}; + +struct trailing_array_3 { + int a; + int b; + int c[0] __attribute__ ((strict_flex_arrays (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 4eb454a4a33b..1f04cb80fd0a 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. */ + /* For &X->fld, compute object size if fld isn't a flexible array + member. */ + bool is_flexible_array_mem_ref = false; while (v && v != pt_var) switch (TREE_CODE (v)) { @@ -633,6 +633,7 @@ 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); while (v != pt_var && TREE_CODE (v) == COMPONENT_REF) if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) != UNION_TYPE @@ -645,12 +646,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;