From patchwork Wed Oct 5 19:13: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: 1747 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp747982wrs; Wed, 5 Oct 2022 12:14:57 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4gP/VoM2UQQeafnVjy5sviG6IgJ6+603RQUxAGITc/gzA/Jx1FX+snFKAFZpXAF7Uix4CH X-Received: by 2002:a05:6402:538f:b0:444:c17b:1665 with SMTP id ew15-20020a056402538f00b00444c17b1665mr1200759edb.98.1664997297157; Wed, 05 Oct 2022 12:14:57 -0700 (PDT) Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id go31-20020a1709070d9f00b0078c8d2e9b3csi7924091ejc.982.2022.10.05.12.14.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Oct 2022 12:14:57 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=UufEndfv; arc=fail (signature failed); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3973F3858023 for ; Wed, 5 Oct 2022 19:14:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3973F3858023 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1664997266; bh=Rvc9PewUcsfNi+6XgjiL8M9F8sJkTbJHkKnJ8WMNERw=; 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=UufEndfvLCQn9CN3rzOdrG6Hhxj7fEq3l7dxGvqTcoC64vw7Zfx2HgGJQTCxmD460 I8LVWh37g8D1KBCi1p/VJtvKnXmzwBubQa/66E9zeQ/SVpGjU/JcVu+A08VSkBqyr9 gSr3kZgq77K2U+RdNDEaRtuc+Ym7lDqbHmUz2gOI= 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 D83AB3858289 for ; Wed, 5 Oct 2022 19:13:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D83AB3858289 Received: from pps.filterd (m0246630.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 295GednO005552; Wed, 5 Oct 2022 19:13:31 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 3k15up1nct-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 05 Oct 2022 19:13:31 +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 295H9MPe037659; Wed, 5 Oct 2022 19:13:30 GMT Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2101.outbound.protection.outlook.com [104.47.58.101]) by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3jxc05dqyu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 05 Oct 2022 19:13:30 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=b8a//VqDvZQIIMF8Pt9FAy/expDI2Lauvj6Qd1G+e6sgxEncFL4Jmt114L8waDsprwyrX+cdKX8MozivhS8gcTfTtTBx0J3AZisGBRk7COzcUFe0IjpbY8FAbmb9aOboDcT2s4JZqSmP4rDiqRNJpPUv2cHIELoe5Y0nkrKbw7JjahdhQQ15jnomyNsB4BzgSzl3IfY3I9UJsKk8bc7BKJtmYZYxjpcfswzPuMi7LnAWv4nb6bhhBq0TFXIuonl5IfWc8yEmv/TdBOHbJRuWEf7b3vQHOveN1ZPH7tOmLOZmTu7iR1oLA+CFPnDWxaQQCeTBvkNvwF6awhRml303SQ== 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=Rvc9PewUcsfNi+6XgjiL8M9F8sJkTbJHkKnJ8WMNERw=; b=Y0j7Z3T3W01mKsTpg2Yd/eKAJAQ+iVXhWp7yiQLDuLzyMSPAwm81t6ZtkCCmcLxg1Pl3+iwPfvHb70r7hJaaaadLCUieqh4bi8U0WBxXkwvW15VqYy9qFw73MWRWuLQv6ikyn1ee1Dx3NYdeBpyTIdQ6LbYcOu/LtUB6fVvEqLg/wiwlodYx3WdVmhxLE/qIZCFn3G5b6Co/ukwSMlZeNLWDiDZ3Yr5KJI1UHOEF/Gn93Wh34gm8ydDdES+9ehLGoZYPoz52LqW69IiAbvNYNTbPeXhfcN79DRHgQQQmJbom7irxSIUDKgXnWYRyoz6B6+B+3d75DP28zTo9wySSfQ== 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 SA2PR10MB4444.namprd10.prod.outlook.com (2603:10b6:806:11f::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5676.23; Wed, 5 Oct 2022 19:13:27 +0000 Received: from CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::cbf8:6682:721e:835c]) by CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::cbf8:6682:721e:835c%6]) with mapi id 15.20.5676.032; Wed, 5 Oct 2022 19:13:27 +0000 To: gcc-patches@gcc.gnu.org, joseph@codesourcery.com, msebor@gmail.com Subject: [GCC13][Patch][V6][PATCH 1/2] Add a new option -fstrict-flex-arrays[=n] and new attribute strict_flex_array Date: Wed, 5 Oct 2022 19:13:19 +0000 Message-Id: <20221005191320.2087486-2-qing.zhao@oracle.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20221005191320.2087486-1-qing.zhao@oracle.com> References: <20221005191320.2087486-1-qing.zhao@oracle.com> X-ClientProxiedBy: MN2PR15CA0043.namprd15.prod.outlook.com (2603:10b6:208:237::12) To CH2PR10MB4344.namprd10.prod.outlook.com (2603:10b6:610:af::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PR10MB4344:EE_|SA2PR10MB4444:EE_ X-MS-Office365-Filtering-Correlation-Id: 1cea08a0-1f26-4540-83f5-08daa705aea8 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: CGecp+8ybm7vmY+MJswJ6unrAbVaE8yZHX2yDD0bX6cMC/mF8yz1XHUd8Rne6XHeECPV+n3KyddvdrEjjklPPofGMGAyRL0ghFwIv3UD7V/HNL169MI/RZ4Q1Qhq+FKxkSIo2ssew2+ZevBHsko3h+6bLXAMUgz7vH7BKowNavBmPfcZDLyBBZoTiCdffGlKGM4I1GSpG7fNF9ykeW8XxqaJp5wsVj68btIX7d5BnXs/6s1UNVD6sZsxqXWftirQ+XGuPVJIObjxa1mKzDt2VFwD8h4qYGl+kCADvtV+f2i7Z+ak6QA6S5KZ6s7KanFG+24hf+T2tDOdGCLV4JHzYsAKV7R92FcEPhINb5/pznaO8d0x71UA/3+qg2bj/B5HyJCCd0DdQXxhcjIh1nVEgxTynYq3XYUoSFqAmcxeF3cByNTb+RxdBwS1eVGzQK96I/vtrChJ0PH5JvxxSw3fzqEJ35Ouz9odBbNVqi8Wwjn+3/AHRYROgc2Eay6AeubbNqqeE71DX3Dqz7QgMA2XrVHnOsCsOKdUSsnzQpxDnL/CtLXanVOolWcMwUMjO2jyQrxgO5Vu0YPgfLAnjp8OpLG5i+r0Y0XKbxgH7hk7Im/pI/PqEn5PASgMMY/Qm12grC4atA1cNYvhkIgD9FkyrctYxbPlppXALFRb6vfoY6A33yvKGbZ2VtyB5Y2Rdk1iPIl9OBFYUedstgBBI3LeYUs6aJraly2rAYaWBdI5+Wg= 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:(13230022)(396003)(39860400002)(366004)(136003)(376002)(346002)(451199015)(36756003)(66899015)(86362001)(84970400001)(83380400001)(186003)(38100700002)(1076003)(2616005)(6512007)(26005)(6506007)(107886003)(6666004)(478600001)(6486002)(2906002)(316002)(44832011)(41300700001)(5660300002)(8936002)(66476007)(66946007)(4326008)(66556008)(30864003)(8676002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: iWjJ9LH29d6gp3Q/vEqtY7qU05n65LjUx5At4J2cRCVuyGsDtHFlsq6W4OwV9wcz54L/6Wv+XHCvoxvenicWO8tRFpwihxFSlVulo0V7zTkRpunTA/sg2DiyhLs+1nqUmFhNyiPrdr4VxqYV4SMzW9NV0SC2vncontVs4xhZu6nSuw0R2qumFEmZYo/daB8gEYpE/DDNWyr6fBVrBV6D4ZeKQhGmYnUOF+KQYw6UcP1LYAZJpcWsezsoib0seNlHdXQqocVtQu+H+5vCoB8UXDTAQMxedCcs0TKav6zSTTWFaBbYrCeXt/IvV530sYro4d/G0ZGzwlIC9SCfn4U0zpzLBJf7NnsPRj8aqdY+3j99YIOLMveVXYNvQ354VP/EfhFQI8P91tlY8wlnRhVGaSfymAdKJ/7PIywDuZGv2HeWe5MbH9FBobcq85CQVXx7zqSjaTQ3+A3pV0nrKRDJeFShDXkj8JpDpAucKauNm6nbqbzE1LA0uWPRwY733QWCho6eHNeNLGW76/sJ7zmnkzTqUKf5Gilovl8Jccw/o+RCRi2UKaxh3LyFz8zIAeSOmtK9GX5iinsabU3tXK+Gmco7rCHjDPai4Gb+yIgCRlKdgIRTxfKAwBpFvt/4n1fpFiHBMk/I2Ccx7FOBe8C2giDALf79LbOekCloI2gPh3ljvOD0SuCCJ1y4/3ApW6oUmXGsapFRB1n5Aj4nLZkx3hRcjjvkOvkDCYttul2ZnjCzKYrpVHWHuqNmzZvqDq6BrqvaAtvjaGu1NayAoMrBWa0fK0x69tjy8bvXxfCPTJpYJR04olJ5SpXiM8AQ06QCJgFuiq1z0q1YV5S8Ywr9eTQG3tPZYfCU0CnuGkRZpY5N1ma60lZrRbOWwDAHd6JpKjS5/bpsfD5HgZfqMlJ07RGumwlboHolaEhjb3vtuaL/Uzl3eZyuyPmNNzJtJruGczIWaCJPKYoTDw/rM2inJqB+eJG8uQu7sEfxIVo6NBtVp71DPZ+HxFQqB/Qt70aeV1ZJmXVqcLYt+7uIcit6eWSQBGZLbGnHhYSjgEebm1WpHXf9mbhuzWjoY7hhEJ813BGCalLXc5qwKgdasON25hMAlMvuX+CPeeCe4X0UiQbnbpJRtqU36a5gsj0I3BPEY9di79IrEa0rscOiuxPb7nrN5emcFZHIjVrm57XvqBJybuwlQiwIu9ISeHwHFb58Q7+O8Zx02MDYeKQHjqzVZsR8KnzwnL4QOVYSBMVhC1jxVI9AZCvMGF8Ir7GLrh3q7bzCZNrT8+PqbLSluxFaXdYEeQqKZlD/9UZvU5+KRnoGoIGzydHZwAGFnFgRrfQ75Q+SzekYWc4+Sxm+OiPPbxMFxFXnLOBxqwlaA0F0L9ra2PIwiOt6009nE9mf/A55LJUgOYwbQwsLlUpSugIUyrLyZURZq/wf30we9715yT97ppPwGxE8Sh11Gewyr/5OhWo0PZnZeHuEcBi+pqSCbd6hJ+Kgjall90bxVWVga5jedVSx7CP/vmMCV6CUzGfr8KmiHpfpX4c+RG7gRWJzmzEvVUmGN+s6bWZo48A2ZNqBG+F5xMMeRPiDu0Li0M+s X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: qf9udAIKLYeOwccAwGwinww+Iff5PjygvYUpayC0AL24L+d6ZVy8FE1dGvvG9BQDM7Ps9L6taMcL2Ig+3g2eEk0CkAD5IbVS+iq6Fm2Pq4WWQI3ph6ZyWDW+UB+aZ3+jt7sTBKNXrtbqqWOSmoof4NL3m31QFJh/b5h+YONBnSDedEHDDn9ghMHWFGwFwIc57VgwLPl6xsyp1TlGNzCu8f4wSeqmTlpNbzF3NGrrX5RbuCbKf6gfMrN8szqT2aI40avRJSt26Lkysclqc3tIw4TzmPEy3F6ATIwAuLl1RYTn2py0FjVoE1XYArFqN0LhP24GwGodsKjWglgHiQt4WMwZdWxTPzw5pgzs49Dc4M5hB8NxeRjHHH7oS3KmnnWjOEiaXaofJG7AZb+kkxmqNtIkbYRw9RoUuwpV/oAyv5vvlkvCFVydlXTDrVqjJPllpIaclRLAt9tikXBmWxgSaE1snEvq1JBPIv6+eveLlLT+v2Q5A5ub/uhAY03gY2mBWgMlABXGCo6a6DspRL2TLbPqSGxjoJ2LbSip3a5f4bNibDsPwgcsQf6pZ5aVk8s9gMs6VEktU6JTqGoTuEnsFxdc7mt/diJsFLOGjspFxXx2vPisTRSServRgDDdv1haEr2tfwCeNeA5/JfXXwTUdQ5YFSvkapXyDIRhrnXtAdx+tq4t79Lk9fnvyKl5J1q+CT3Thzv1blIAV3JELKFDJKKxMvchHZI7jSF0Y8A54UlAIsyLKyHO/N98O4dcY2qLJ2q/FdBLh+v3XF2wx3uC/pxbsyqPlo8tdDZcE1DzmWUw8EHDBkgPjTwL9rOzHD4Ciu1JEM7JAXpN+ZZbBjp68j5Cgzk+Zq78/upoYkwYC7Qw8xMK8xTIFgP3fXM9/4jPwZwHPfr1jgdcepyIy2H5MQ== X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1cea08a0-1f26-4540-83f5-08daa705aea8 X-MS-Exchange-CrossTenant-AuthSource: CH2PR10MB4344.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Oct 2022 19:13:27.4707 (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: FGn5+tvlB+FwGh4Ufu2B99tfNvBffnuQB1nifEYGmnCB1fifPSTVi79sj59CJ9IIacYfPgFNM/LcInoVLvvpsA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA2PR10MB4444 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-10-05_05,2022-10-05_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 mlxlogscore=999 mlxscore=0 spamscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2209130000 definitions=main-2210050120 X-Proofpoint-GUID: EqxvzopcSjRCD2l15ZUsA02fvlbisJF4 X-Proofpoint-ORIG-GUID: EqxvzopcSjRCD2l15ZUsA02fvlbisJF4 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 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, keescook@chromium.org Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1745876205483391223?= X-GMAIL-MSGID: =?utf-8?q?1745876205483391223?= Add the following new option -fstrict-flex-arrays[=n] and a corresponding attribute strict_flex_array to GCC: '-fstrict-flex-arrays' Control when to treat the trailing array of a structure as a flexible array member for the purpose of accessing the elements of such an array. 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 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' Control when to treat the trailing array of a structure as a flexible array member for the purpose of accessing the elements of such an array. 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 controls when to treat the trailing array field of a structure as a flexible array member for the purposesof accessing the elements of such an array. 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-element array as flexible array members('[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_array_attribute): New function. (c_common_attribute_table): New item for strict_flex_array. * 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_array 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 | 26 +++++ gcc/doc/invoke.texi | 28 ++++- gcc/print-tree.cc | 8 +- gcc/testsuite/g++.dg/strict-flex-array-1.C | 31 +++++ gcc/testsuite/gcc.dg/strict-flex-array-1.c | 33 ++++++ 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, 350 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 8bb80e251dc..ee82181ed31 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 *); @@ -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_array", 1, 1, true, 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, @@ -2505,6 +2509,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 1c7f89eeb94..01d480759ae 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -2076,6 +2076,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= Control when to treat the trailing array of a structure as a flexible array member for the purposes of accessing the elements of such an array. The default is treating all trailing arrays of structures as flexible array members. + fsquangle C++ ObjC++ WarnRemoved diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 740982eae31..38e037bb278 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -5009,6 +5009,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. */ @@ -5023,10 +5058,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) @@ -8714,6 +8746,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_array", + 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. @@ -8775,6 +8882,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; @@ -8813,10 +8925,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) { @@ -8824,7 +8933,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"); @@ -8844,6 +8953,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 500ac06563a..eda59f5f6c6 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -5416,6 +5416,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)) @@ -5560,6 +5561,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 a5afb467d23..f6342c3c0f8 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7459,6 +7459,32 @@ 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 controls when to treat the trailing array +field of a structure as a flexible array member for the purposesof accessing +the elements of such an array. +@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-element +array as flexible array members (@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 2ac9cfc35f9..a48fd0aace2 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}. @@ -2827,6 +2828,31 @@ 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 +Control when to treat the trailing array of a structure as a flexible array +member for the purpose of accessing the elements of such an array. +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} +Control when to treat the trailing array of a structure as a flexible array +member for the purpose of accessing the elements of such an array. 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/print-tree.cc b/gcc/print-tree.cc index 6d45a4a5966..58a98250cc4 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 00000000000..92fcffe081f --- /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_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/testsuite/gcc.dg/strict-flex-array-1.c b/gcc/testsuite/gcc.dg/strict-flex-array-1.c new file mode 100644 index 00000000000..5b8a79363b0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strict-flex-array-1.c @@ -0,0 +1,33 @@ +/* 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'" } */ + +int [[gnu::strict_flex_array(1)]] x; /* { dg-warning "'strict_flex_array' attribute does not apply to types" } */ + +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 55807fe15c6..c4f2cea2352 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -1827,7 +1827,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 219cf5e7ef4..57923da3741 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 9b114dc05bb..68a2818a9f9 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 f8d24b5d4cf..c4ead94aa65 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -12691,14 +12691,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) @@ -12708,7 +12724,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); @@ -12720,6 +12739,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)) @@ -12773,13 +12793,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). */ @@ -12801,9 +12824,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))) @@ -12811,12 +12834,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 95285e45fb7..142e9c9d335 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. */ @@ -5547,10 +5553,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