Message ID | 20221206161844.2397151-1-qing.zhao@oracle.com |
---|---|
State | New |
Headers |
Return-Path: <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id ACCD23842309 for <patchwork@sourceware.org>; Tue, 6 Dec 2022 16:19:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org ACCD23842309 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1670343572; bh=x3u40CY0KKjl3opVm++tQHqfVtBi5jbpSahZAFeR1XA=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=Mg+V2HIYh6i0T6PsDCL7A51oNXl8YZoBJ9AXpr7lyFjGoonDmhHfEmzSJlZsF0FBz kzl5Ls8Jkfiq1egT5XOtmjtGSj4HWeWe/0JM2yBLrsKXVHKii7fgoPAxvp1BDD7kyL otqLeIbdkFd9Lek1wRSF2eH/HeMx8LVOtQHr4K68= 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 8C30B38469A5; Tue, 6 Dec 2022 16:18:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8C30B38469A5 Received: from pps.filterd (m0246630.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2B6Efin4015644; Tue, 6 Dec 2022 16:18:55 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 3m7yb3fnvp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 06 Dec 2022 16:18:54 +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 2B6Fo2MV001236; Tue, 6 Dec 2022 16:18:52 GMT Received: from nam12-mw2-obe.outbound.protection.outlook.com (mail-mw2nam12lp2043.outbound.protection.outlook.com [104.47.66.43]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3m8ucfc3y8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 06 Dec 2022 16:18:52 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ZV3+t116UR+zLY4H8PlUPNk3CE3ctqdfidTqS6iuf0tiJddwGeD+h3rKAn1dkDlB63BfeQwq9xrb9gLHmYGOzXz3EVEfbSaQRzHeDyxEcDGAQCIDYltvCoVqxsl+7X0cIS4w3VDGyDjssPvVQpaw8EwgThazldmY+jymZwAQx9Iy5TUT3bb6tuXokRfUaOU0CjBTcZlG1ansOLv+2/Ptar+7mbWRDdX8Oz1YE8bkf3qX1hB9mENgy5TxtKi49umOWGUSywVdUPamaBMKcoX3mpBk3mj2yYL741TbNjardOoVdGueKieROnPLD9TdxH8WRO8TNGYoYwT6wUxvyl1jHw== 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=x3u40CY0KKjl3opVm++tQHqfVtBi5jbpSahZAFeR1XA=; b=P7c0BLo5d+WiBaMDOxR9Xj10wz+cza22xFcARuQwQ1KhACEA87rG29cIkZZRlbJhEV4EJkhLZDRwm0Bi1ywS4L1leH6wxalCqRaQzrxXy8yjGjuV57Fcirf59R0jTEwANpMDf4G3D/8cbqAJhFELviidrgnHhJ8UE/yCiP8OZrSpyy+fwzjFO5jbJRlLbIov4lqtYGjghKCD/XQvBvcW+Os+cAv351xAuD3fRtzE2GgU4G0q68qAXD61M2MIam2O/QbUnyOvPNbRL8IqRGhsGjDrfUKf8aBCn3Alo5o4bwgmPmwDIGni7HpJWKhP7HbswRO6mKvbSVw3hqU3HspXqg== 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 SN7PR10MB6666.namprd10.prod.outlook.com (2603:10b6:806:298::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5880.14; Tue, 6 Dec 2022 16:18:49 +0000 Received: from CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::9423:79b3:c0dc:1113]) by CH2PR10MB4344.namprd10.prod.outlook.com ([fe80::9423:79b3:c0dc:1113%9]) with mapi id 15.20.5880.014; Tue, 6 Dec 2022 16:18:49 +0000 To: rguenther@suse.de, joseph@codesourcery.com Cc: gcc-patches@gcc.gnu.org, keescook@chromium.org, siddhesh@gcc.gnu.org, Qing Zhao <qing.zhao@oracle.com> Subject: [V3][PATCH 2/2] Add a new warning option -Wstrict-flex-arrays. Date: Tue, 6 Dec 2022 16:18:44 +0000 Message-Id: <20221206161844.2397151-1-qing.zhao@oracle.com> X-Mailer: git-send-email 2.31.1 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: SN6PR01CA0018.prod.exchangelabs.com (2603:10b6:805:b6::31) To CH2PR10MB4344.namprd10.prod.outlook.com (2603:10b6:610:af::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PR10MB4344:EE_|SN7PR10MB6666:EE_ X-MS-Office365-Filtering-Correlation-Id: b7e0a754-eec5-4b55-b067-08dad7a58eb9 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: npbxzkA3w8poicQp/FNGEBcowO6HvUsOxF9hXXGy1Lpxj1ftX1cUcNDXh8PMMd+dvVjdihhm+eY1ajsaAM2qc1ULMs2GH9fRh7V2lxLKnnHSefI3t4o0bvghnj922RqVgMHPfonOM4sYM/Uthmz9a2ULNgX9DCEdnNGmpkWvs2fXghOtgUI7Q7xrW5TRauvN+xWglhXOCSulnzvockvViwk7OUA6HW+99LsQ649N7TzmibEAbLpJvoHwimv5ipzh0YT+NPm3O8/MOvQ719/B1HQHzCK3hrsyNBq8p+tyLyRo5X9BS2wZzWl7CQYtAzuxAJLm1VBNRRX/XL/ERRoiys3QR8SRO30uza4QhdL+XyWa2VN0U+IgHkwi0qRZ4H6C70pdjUKDAmYs6x5Bz66Py2oENo43gGPfX/s4y3by7yzbTFwzrNajLViPPpx0NMkuqYsT6WJ01i091j2+0ncPYgAeaA9R1SfNmh0GB3pT6qDpohVgkKWNVj0IqlSYVcL9NBxz6/ktoLKEbLVvKMLm32lXHlseIYZ7z59X+Hxyrkis0iGKMCVs/xSksX0PON5LXj+zozLAQuxpBq4TYQNTWphQrU9apnitwEu/nGbWNJQAetocshqUGhpt5fBj0cnGvaUo9huuj3fAFSgFtNvO6CLILMSImUia6mwdswLUiWS5iTmloLHaPjl1SuJXy4eAAmuTjqagE2HYwIakH9cGmg== 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)(376002)(346002)(136003)(396003)(39860400002)(366004)(451199015)(8676002)(66556008)(66946007)(66476007)(44832011)(30864003)(5660300002)(41300700001)(8936002)(2906002)(316002)(4326008)(84970400001)(36756003)(38100700002)(86362001)(478600001)(83380400001)(186003)(1076003)(2616005)(107886003)(6666004)(6486002)(6506007)(6512007)(26005); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: UT860ZkGHeapgayi5pbswT4nAXdcxJ3b6Vum9whR7LihMDo5jwL/M/Vzu1kGSuvz8R5hBcxvbQ0jBfSuychB0uNglRgIYD0eNdwZMtBjFSL/yy5FQJ5zZI3ftJ2G8vC77LlgICOpDg7DaLsTtplqNEwX/SS6miYNDXOfzyeLagB9jy+jXYsWb0C9WguZo5Gc1duP9CZU0ZVcekzEyVb8cNwZTN5XydRFeElBkGeogHNSLoSTLy/V7sCBvqdtm7vsf8CqoqHx97rSwhOBJCkejw7682TzL3KIya8lc5kWOZv8/cl4M035f14WYzRwUV/hzeuAy3MCs+oTMZHwsiI+pi/X8f8ileJNMRwyumkcpwQ0XrrUgiCzqDCV2+wnSpjtBIlPj3lcbjw7mYr+kCpTN+rbS5TeuhblPrwEnd3geRkbjhu3Puu87Tm7YJkeT8SoAKI+gzSO2vMjIEL5KrUNQBCLbwsIijgBv7amvpR/yAcZvsLaLcMMDmwmc3eB4pPPkHvsO1i1Yo89WNsql2Icwi2mI2MuwbMGHdzD+jbGPxpLjZWwc1idmCBkb7S6T0TZ8uZboaKIhgO2osQ6KwozOctSKrrAEBFpBgOhZ4NGodQJBlQh0JlhUUDWg9sbcS/5B12fxkTcvYtlSeoF8a9BYOEG7NJ0/Milh/+RRZO+YMWWgLaIMtc4QbGwF0MQkzsdHwJnfb6mxWGKiC6H05D1MWN0OhJ48oFL0qdokK8GcpspeTJdCyUq3WyPVKW+DToJaKEKK4dPA3NpfpjFqAaLYP3drKr4+Jy50707Dn+BES5VoOwuKHEk2ru1wOWIceNANw+vpJtwuSsuJazxZKscPzYVYwmWulhXN1CBj/aosZ0ZdTcleJRggdQ4k9z88+WsYdRYVZ3KtJRV2uaN+OC6jivrweVaCD8CLk5YKHuAM9r7tDQGKBSteysbRfgH89Ty5XV48c2d36e0aYTy4epwwI2aoHl69GPn6VHmSqH4jC5mhhfRIWWhlbb1+U2ycnEy7eoFZCh9wl5FeB5ofJ4mLpSWzoHtd9tGCFFMJcqwfC3CpE9zrnppLXBV7zvbnjf0c74ychYJh47amNAns5MT4nsB+QyPzoZzwx4BytGH0J7kgQi/fXQzmfHBYj2vpnlX07akc7mhtkPP2nnLp7dnpDxzKCC14uVtPuW/WLM1nZ6GpbrGvKxCdEvHqK0pt4XAFdiJP/x2J70H4Ue6Zwj9/J8k8scWygPBcucc3+BfQRmLrTOeL+ZbPRMibxuL26oJBCrO4tXIrCATCDec12ppBRhAbnVPMu0qmQ8oJ205+p9BPPpJ7L7hMmKrZNC9jszm/SCn3VkJSbqoF5EvXAgn6ULEkFAU6mNOpVYvTrRNCVI0QmPSx0l0w5gG89NGBibkBiKtZam0L3bxTCbROdLSb14aDJXZWdDQX6Qkx0FbU1Jl8tSnrLcmNo78wcCJSFHRZ02QaIqACi+jpdQRYilICUDic0JjjAmxGc19ZjMxnpKEE8xOcSgWKXsqqrFUkVtx8UTssex7zi8QhHJ3nYOJaQNxU23XREoOXQpS6i7CvSqUogmvjYyfuB3NUSEVHbhC X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: Vyo4JYj2PfZ1Z/bgnvpflbZfP2ovCl9RsKLQpAXL7WxmbEq2NT6mG1uDDokpL81GIQ1kFk9Qo0beq43KawR4pveZYCBXvBcHU8X/+/n396jQJNzGUFtoAoiioH9AGNwTT9FFLedASLBsy0BKvgby5AZY9xyqb9UmlpdiZJrtKumfXIYCcO49DyGy04KUiJ9VTSOUS3nMRwVpvdZucwEIZ2sHT5j7gYt3B+++TpToe155RMck4imZPxFVr0b0JNiqSykPWupON2cB2vVT7ydLAE7//UnyXRtbJoCgOaMSUJxb9YBqgKfEDhErP/5vkmEzSUFsnJTYzvKcW4va4w+OeLL50z4RWNLa+G1rizQNG2rZiH21JWwBZvlrYkxtQYtJpniQz/v9F6aU6ywHf1zQqY5k4J1WWiNQZ7q46Ckz9TX4lEQFh3gJ+H0DNDTsEUueKKR2UimPBs9n2QSLVFV/m+IJx3TpBkAdHXGCoDmqwyhHPMxQeUHRPBKsC85gTlgMtU5pgcnJ8twzZH3H2+CTAGkvplNAib/xvrPiRaYy/q2c2brbBQ9ZxiHY1L03hsypttIaDpvtMVzHmompkuPLD4Bklmyi246z4yXUacfkJTde3tV9ceWqXHW9VqR0drD9Iw9ylSHGfG/MQFMrLQF8Nu3ydJfwFNaz9x47tKJcTqPug8/6HA9i2svc4yh8B9eD2of03yHqDH+yK1nKxRNhnEjrGcVUgIVvC/d45C4fwL3wzcFDITI39v3tE8U/lGuiD9T6i/NGYDYnb97MvsSl88Cuu807bEvqCZ98dmD0t9QTBo8V1BKhv7vmqlAQeFl/edi0SLT8ESduEYSWEmcPrJDqaexumSaZ39cBtp+tn0m9zcVlCs1iV7W3bfkO+bfI X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: b7e0a754-eec5-4b55-b067-08dad7a58eb9 X-MS-Exchange-CrossTenant-AuthSource: CH2PR10MB4344.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Dec 2022 16:18:49.2174 (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: /OJocwlWLE4cF3Tew85DzwS0rLp6LkqID+jMYgAesgaKTcZbj0rCsLuzpZsuBUGGPieeZnSqzxnr9IBAeJ6jWA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR10MB6666 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-06_10,2022-12-06_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 mlxlogscore=999 bulkscore=0 malwarescore=0 mlxscore=0 suspectscore=0 adultscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2210170000 definitions=main-2212060136 X-Proofpoint-ORIG-GUID: LUEJBLdvprjDJXuwXWPsvpNzLN9upyoy X-Proofpoint-GUID: LUEJBLdvprjDJXuwXWPsvpNzLN9upyoy 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 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 <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> From: Qing Zhao via Gcc-patches <gcc-patches@gcc.gnu.org> Reply-To: Qing Zhao <qing.zhao@oracle.com> Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> |
Series |
Update -Warray-bounds with -fstrict-flex-arrays
|
|
Commit Message
Qing Zhao
Dec. 6, 2022, 4:18 p.m. UTC
'-Wstrict-flex-arrays' Warn about inproper usages of flexible array members according to the LEVEL of the 'strict_flex_array (LEVEL)' attribute attached to the trailing array field of a structure if it's available, otherwise according to the LEVEL of the option '-fstrict-flex-arrays=LEVEL'. This option is effective only when LEVEL is bigger than 0. Otherwise, it will be ignored with a warning. when LEVEL=1, warnings will be issued for a trailing array reference of a structure that have 2 or more elements if the trailing array is referenced as a flexible array member. when LEVEL=2, in addition to LEVEL=1, additional warnings will be issued for a trailing one-element array reference of a structure if the array is referenced as a flexible array member. when LEVEL=3, in addition to LEVEL=2, additional warnings will be issued for a trailing zero-length array reference of a structure if the array is referenced as a flexible array member. gcc/ChangeLog: * doc/invoke.texi: Document -Wstrict-flex-arrays option. * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Add two more arguments. (array_bounds_checker::check_array_ref): Issue warnings for -Wstrict-flex-arrays. * opts.cc (finish_options): Issue warning for unsupported combination of -Wstrict_flex_arrays and -fstrict-flex-array. * tree-vrp.cc (execute_ranger_vrp): Enable the pass when warn_strict_flex_array is true. gcc/c-family/ChangeLog: * c.opt (Wstrict-flex-arrays): New option. gcc/testsuite/ChangeLog: * gcc.dg/Warray-bounds-flex-arrays-1.c: Update testing case with -Wstrict-flex-arrays. * gcc.dg/Warray-bounds-flex-arrays-2.c: Likewise. * gcc.dg/Warray-bounds-flex-arrays-3.c: Likewise. * gcc.dg/Warray-bounds-flex-arrays-4.c: Likewise. * gcc.dg/Warray-bounds-flex-arrays-5.c: Likewise. * gcc.dg/Warray-bounds-flex-arrays-6.c: Likewise. * c-c++-common/Wstrict-flex-arrays.c: New test. * gcc.dg/Wstrict-flex-arrays-2.c: New test. * gcc.dg/Wstrict-flex-arrays-3.c: New test. * gcc.dg/Wstrict-flex-arrays.c: New test. --- gcc/c-family/c.opt | 5 + gcc/doc/invoke.texi | 27 ++++- gcc/gimple-array-bounds.cc | 103 ++++++++++++++---- gcc/opts.cc | 8 ++ .../c-c++-common/Wstrict-flex-arrays.c | 9 ++ .../gcc.dg/Warray-bounds-flex-arrays-1.c | 5 +- .../gcc.dg/Warray-bounds-flex-arrays-2.c | 6 +- .../gcc.dg/Warray-bounds-flex-arrays-3.c | 7 +- .../gcc.dg/Warray-bounds-flex-arrays-4.c | 5 +- .../gcc.dg/Warray-bounds-flex-arrays-5.c | 6 +- .../gcc.dg/Warray-bounds-flex-arrays-6.c | 7 +- gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c | 39 +++++++ gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c | 39 +++++++ gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c | 39 +++++++ gcc/tree-vrp.cc | 2 +- 15 files changed, 273 insertions(+), 34 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c
Comments
Richard, Do you have any decision on this one? Do we need this warning option For GCC? thanks. Qing > On Dec 6, 2022, at 11:18 AM, Qing Zhao <qing.zhao@oracle.com> wrote: > > '-Wstrict-flex-arrays' > Warn about inproper usages of flexible array members according to > the LEVEL of the 'strict_flex_array (LEVEL)' attribute attached to > the trailing array field of a structure if it's available, > otherwise according to the LEVEL of the option > '-fstrict-flex-arrays=LEVEL'. > > This option is effective only when LEVEL is bigger than 0. > Otherwise, it will be ignored with a warning. > > when LEVEL=1, warnings will be issued for a trailing array > reference of a structure that have 2 or more elements if the > trailing array is referenced as a flexible array member. > > when LEVEL=2, in addition to LEVEL=1, additional warnings will be > issued for a trailing one-element array reference of a structure if > the array is referenced as a flexible array member. > > when LEVEL=3, in addition to LEVEL=2, additional warnings will be > issued for a trailing zero-length array reference of a structure if > the array is referenced as a flexible array member. > > gcc/ChangeLog: > > * doc/invoke.texi: Document -Wstrict-flex-arrays option. > * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Add two more > arguments. > (array_bounds_checker::check_array_ref): Issue warnings for > -Wstrict-flex-arrays. > * opts.cc (finish_options): Issue warning for unsupported combination > of -Wstrict_flex_arrays and -fstrict-flex-array. > * tree-vrp.cc (execute_ranger_vrp): Enable the pass when > warn_strict_flex_array is true. > > gcc/c-family/ChangeLog: > > * c.opt (Wstrict-flex-arrays): New option. > > gcc/testsuite/ChangeLog: > > * gcc.dg/Warray-bounds-flex-arrays-1.c: Update testing case with > -Wstrict-flex-arrays. > * gcc.dg/Warray-bounds-flex-arrays-2.c: Likewise. > * gcc.dg/Warray-bounds-flex-arrays-3.c: Likewise. > * gcc.dg/Warray-bounds-flex-arrays-4.c: Likewise. > * gcc.dg/Warray-bounds-flex-arrays-5.c: Likewise. > * gcc.dg/Warray-bounds-flex-arrays-6.c: Likewise. > * c-c++-common/Wstrict-flex-arrays.c: New test. > * gcc.dg/Wstrict-flex-arrays-2.c: New test. > * gcc.dg/Wstrict-flex-arrays-3.c: New test. > * gcc.dg/Wstrict-flex-arrays.c: New test. > --- > gcc/c-family/c.opt | 5 + > gcc/doc/invoke.texi | 27 ++++- > gcc/gimple-array-bounds.cc | 103 ++++++++++++++---- > gcc/opts.cc | 8 ++ > .../c-c++-common/Wstrict-flex-arrays.c | 9 ++ > .../gcc.dg/Warray-bounds-flex-arrays-1.c | 5 +- > .../gcc.dg/Warray-bounds-flex-arrays-2.c | 6 +- > .../gcc.dg/Warray-bounds-flex-arrays-3.c | 7 +- > .../gcc.dg/Warray-bounds-flex-arrays-4.c | 5 +- > .../gcc.dg/Warray-bounds-flex-arrays-5.c | 6 +- > .../gcc.dg/Warray-bounds-flex-arrays-6.c | 7 +- > gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c | 39 +++++++ > gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c | 39 +++++++ > gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c | 39 +++++++ > gcc/tree-vrp.cc | 2 +- > 15 files changed, 273 insertions(+), 34 deletions(-) > create mode 100644 gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c > create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > > diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt > index 0d0ad0a6374..33edeefd285 100644 > --- a/gcc/c-family/c.opt > +++ b/gcc/c-family/c.opt > @@ -976,6 +976,11 @@ Wstringop-truncation > C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ LTO ObjC++, Wall) > Warn about truncation in string manipulation functions like strncat and strncpy. > > +Wstrict-flex-arrays > +C C++ Var(warn_strict_flex_arrays) Warning > +Warn about inproper usages of flexible array members > +according to the level of -fstrict-flex-arrays. > + > Wsuggest-attribute=format > C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning > Warn about functions which might be candidates for format attributes. > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > index 726392409b6..4402b0427ef 100644 > --- a/gcc/doc/invoke.texi > +++ b/gcc/doc/invoke.texi > @@ -398,7 +398,7 @@ Objective-C and Objective-C++ Dialects}. > -Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol > -Wstring-compare @gol > -Wno-stringop-overflow -Wno-stringop-overread @gol > --Wno-stringop-truncation @gol > +-Wno-stringop-truncation -Wstrict-flex-arrays @gol > -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol > -Wswitch -Wno-switch-bool -Wswitch-default -Wswitch-enum @gol > -Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand @gol > @@ -7835,6 +7835,31 @@ however, are not suitable arguments to functions that expect > such arrays GCC issues warnings unless it can prove that the use is > safe. @xref{Common Variable Attributes}. > > +@item -Wstrict-flex-arrays > +@opindex Wstrict-flex-arrays > +@opindex Wno-strict-flex-arrays > +Warn about inproper usages of flexible array members > +according to the @var{level} of the @code{strict_flex_array (@var{level})} > +attribute attached to the trailing array field of a structure if it's > +available, otherwise according to the @var{level} of the option > +@option{-fstrict-flex-arrays=@var{level}}. > + > +This option is effective only when @var{level} is bigger than 0. Otherwise, > +it will be ignored with a warning. > + > +when @var{level}=1, warnings will be issued for a trailing array reference > +of a structure that have 2 or more elements if the trailing array is referenced > +as a flexible array member. > + > +when @var{level}=2, in addition to @var{level}=1, additional warnings will be > +issued for a trailing one-element array reference of a structure > +if the array is referenced as a flexible array member. > + > +when @var{level}=3, in addition to @var{level}=2, additional warnings will be > +issued for a trailing zero-length array reference of a structure > +if the array is referenced as a flexible array member. > + > + > @item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]} > @opindex Wsuggest-attribute= > @opindex Wno-suggest-attribute= > diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc > index db3459af325..825f11331b5 100644 > --- a/gcc/gimple-array-bounds.cc > +++ b/gcc/gimple-array-bounds.cc > @@ -252,25 +252,34 @@ get_up_bounds_for_array_ref (tree ref, tree *decl, > > /* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND > and UP_BOUND_P1, check whether the array reference REF is out of bound. > - Issue warnings if out of bound, return TRUE if warnings are issued. */ > + When out of bounds, set OUT_OF_BOUND to true. > + Issue warnings if FOR_ARRAY_BOUND is true. > + return TRUE if warnings are issued. */ > + > > static bool > check_out_of_bounds_and_warn (location_t location, tree ref, > tree low_sub_org, tree low_sub, tree up_sub, > tree up_bound, tree up_bound_p1, > const value_range *vr, > - bool ignore_off_by_one) > + bool ignore_off_by_one, bool for_array_bound, > + bool *out_of_bound) > { > tree low_bound = array_ref_low_bound (ref); > tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); > > bool warned = false; > + *out_of_bound = false; > > /* Empty array. */ > if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1)) > - warned = warning_at (location, OPT_Warray_bounds_, > - "array subscript %E is outside array bounds of %qT", > - low_sub_org, artype); > + { > + *out_of_bound = true; > + if (for_array_bound) > + warned = warning_at (location, OPT_Warray_bounds_, > + "array subscript %E is outside array" > + " bounds of %qT", low_sub_org, artype); > + } > > if (warned) > ; /* Do nothing. */ > @@ -283,24 +292,33 @@ check_out_of_bounds_and_warn (location_t location, tree ref, > : tree_int_cst_le (up_bound, up_sub)) > && TREE_CODE (low_sub) == INTEGER_CST > && tree_int_cst_le (low_sub, low_bound)) > - warned = warning_at (location, OPT_Warray_bounds_, > - "array subscript [%E, %E] is outside " > - "array bounds of %qT", > - low_sub, up_sub, artype); > + { > + *out_of_bound = true; > + warned = warning_at (location, OPT_Warray_bounds_, > + "array subscript [%E, %E] is outside " > + "array bounds of %qT", > + low_sub, up_sub, artype); > + } > } > else if (up_bound > && TREE_CODE (up_sub) == INTEGER_CST > && (ignore_off_by_one > ? !tree_int_cst_le (up_sub, up_bound_p1) > : !tree_int_cst_le (up_sub, up_bound))) > - warned = warning_at (location, OPT_Warray_bounds_, > - "array subscript %E is above array bounds of %qT", > - up_sub, artype); > + { > + *out_of_bound = true; > + warned = warning_at (location, OPT_Warray_bounds_, > + "array subscript %E is above array bounds of %qT", > + up_sub, artype); > + } > else if (TREE_CODE (low_sub) == INTEGER_CST > && tree_int_cst_lt (low_sub, low_bound)) > - warned = warning_at (location, OPT_Warray_bounds_, > - "array subscript %E is below array bounds of %qT", > - low_sub, artype); > + { > + *out_of_bound = true; > + warned = warning_at (location, OPT_Warray_bounds_, > + "array subscript %E is below array bounds of %qT", > + low_sub, artype); > + } > return warned; > } > > @@ -333,14 +351,21 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > > tree arg = TREE_OPERAND (ref, 0); > const bool compref = TREE_CODE (arg) == COMPONENT_REF; > + unsigned int strict_flex_array_level = flag_strict_flex_arrays; > > if (compref) > - /* Try to determine special array member type for this COMPONENT_REF. */ > - sam = component_ref_sam_type (arg); > + { > + /* Try to determine special array member type for this COMPONENT_REF. */ > + sam = component_ref_sam_type (arg); > + /* Get the level of strict_flex_array for this array field. */ > + tree afield_decl = TREE_OPERAND (arg, 1); > + strict_flex_array_level = strict_flex_array_level_of (afield_decl); > + } > > get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); > > bool warned = false; > + bool out_of_bound = false; > > tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); > tree low_sub_org = TREE_OPERAND (ref, 1); > @@ -361,7 +386,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > warned = check_out_of_bounds_and_warn (location, ref, > low_sub_org, low_sub, up_sub, > up_bound, up_bound_p1, vr, > - ignore_off_by_one); > + ignore_off_by_one, warn_array_bounds, > + &out_of_bound); > > > if (!warned && sam == special_array_member::int_0) > @@ -373,19 +399,56 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > "of an interior zero-length array %qT")), > low_sub, artype); > > - if (warned) > + if (warned || out_of_bound) > { > - if (dump_file && (dump_flags & TDF_DETAILS)) > + if (warned && dump_file && (dump_flags & TDF_DETAILS)) > { > fprintf (dump_file, "Array bound warning for "); > dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); > fprintf (dump_file, "\n"); > } > > + /* issue warnings for -Wstrict-flex-arrays according to the level of > + flag_strict_flex_arrays. */ > + if (out_of_bound && warn_strict_flex_arrays) > + switch (strict_flex_array_level) > + { > + case 3: > + /* Issue additional warnings for trailing arrays [0]. */ > + if (sam == special_array_member::trail_0) > + warned = warning_at (location, OPT_Wstrict_flex_arrays, > + "trailing array %qT should not be used as " > + "a flexible array member for level 3", > + artype); > + /* FALLTHROUGH. */ > + case 2: > + /* Issue additional warnings for trailing arrays [1]. */ > + if (sam == special_array_member::trail_1) > + warned = warning_at (location, OPT_Wstrict_flex_arrays, > + "trailing array %qT should not be used as " > + "a flexible array member for level 2 and " > + "above", artype); > + /* FALLTHROUGH. */ > + case 1: > + /* Issue warnings for trailing arrays [n]. */ > + if (sam == special_array_member::trail_n) > + warned = warning_at (location, OPT_Wstrict_flex_arrays, > + "trailing array %qT should not be used as " > + "a flexible array member for level 1 and " > + "above", artype); > + break; > + case 0: > + /* Do nothing. */ > + break; > + default: > + gcc_unreachable (); > + } > + > /* Avoid more warnings when checking more significant subscripts > of the same expression. */ > ref = TREE_OPERAND (ref, 0); > suppress_warning (ref, OPT_Warray_bounds_); > + suppress_warning (ref, OPT_Wstrict_flex_arrays); > > if (decl) > ref = decl; > diff --git a/gcc/opts.cc b/gcc/opts.cc > index 73fc97756e4..8db53ad6c77 100644 > --- a/gcc/opts.cc > +++ b/gcc/opts.cc > @@ -1411,6 +1411,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, > opts->x_profile_flag = 0; > } > > + if (opts->x_warn_strict_flex_arrays) > + if (opts->x_flag_strict_flex_arrays == 0) > + { > + opts->x_warn_strict_flex_arrays = 0; > + warning_at (UNKNOWN_LOCATION, 0, > + "%<-Wstrict-flex-arrays%> is ignored when" > + " %<-fstrict-flex-arrays%> does not present"); > + } > > diagnose_options (opts, opts_set, loc); > } > diff --git a/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c > new file mode 100644 > index 00000000000..72b4b7c6406 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c > @@ -0,0 +1,9 @@ > +/* Test the usage of option -Wstrict-flex-arrays. */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -Wstrict-flex-arrays" } */ > + > +int main(int argc, char *argv[]) > +{ > + return 0; > +} > +/* { dg-warning "is ignored when \'-fstrict-flex-arrays\' does not present" "" { target *-*-* } 0 } */ > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > index d36ba4d86cb..65c9fec43af 100644 > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > @@ -1,6 +1,6 @@ > -/* Test -fstrict-flex-arrays + -Warray-bounds. */ > +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ > /* { dg-do compile} */ > -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */ > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds" } */ > > struct trailing_array_1 { > int a; > @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_4 *trailing_flex) > { > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ > trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > index f63206e1948..2b5a895c598 100644 > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > @@ -1,6 +1,6 @@ > -/* Test -fstrict-flex-arrays + -Warray-bounds. */ > +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ > /* { dg-do compile } */ > -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */ > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds" } */ > > struct trailing_array_1 { > int a; > @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_4 *trailing_flex) > { > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ > + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > index e3273714e8b..25b903f2615 100644 > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > @@ -1,6 +1,6 @@ > -/* Test -fstrict-flex-arrays + -Warray-bounds. */ > +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ > /* { dg-do compile } */ > -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */ > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds" } */ > > struct trailing_array_1 { > int a; > @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_4 *trailing_flex) > { > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ > + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */ > > } > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > index cabaea77dc2..5fc500a19ca 100644 > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > @@ -1,6 +1,6 @@ > -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ > +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ > /* { dg-do compile } */ > -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */ > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds=2" } */ > > struct trailing_array_1 { > int a; > @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_4 *trailing_flex) > { > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ > trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > index 8b7db6e4f39..30bb4ca8832 100644 > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > @@ -1,6 +1,6 @@ > -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ > +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ > /* { dg-do compile } */ > -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */ > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds=2" } */ > > struct trailing_array_1 { > int a; > @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_4 *trailing_flex) > { > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > index 035bf481396..e847a44516e 100644 > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > @@ -1,6 +1,6 @@ > -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ > +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ > /* { dg-do compile } */ > -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */ > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds=2" } */ > > struct trailing_array_1 { > int a; > @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( > struct trailing_array_4 *trailing_flex) > { > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ > + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > > } > diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > new file mode 100644 > index 00000000000..2e241f96208 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > @@ -0,0 +1,39 @@ > +/* Test -Wstrict-flex-arrays. */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2" } */ > + > +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) > +{ > + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ > + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ > + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ > + > +} > diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > new file mode 100644 > index 00000000000..97eb65ba0a9 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > @@ -0,0 +1,39 @@ > +/* Test -Wstrict-flex-arrays. */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3" } */ > + > +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) > +{ > + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ > + trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */ > + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */ > + > +} > diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > new file mode 100644 > index 00000000000..110fdc72778 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > @@ -0,0 +1,39 @@ > +/* Test -Wstrict-flex-arrays. */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1" } */ > + > +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) > +{ > + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > + trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > + > +} > diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc > index 3846dc1d849..e6c6c5a301d 100644 > --- a/gcc/tree-vrp.cc > +++ b/gcc/tree-vrp.cc > @@ -1087,7 +1087,7 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p, > if (dump_file && (dump_flags & TDF_DETAILS)) > ranger->dump (dump_file); > > - if (warn_array_bounds && warn_array_bounds_p) > + if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p) > { > // Set all edges as executable, except those ranger says aren't. > int non_exec_flag = ranger->non_executable_edge_flag; > -- > 2.31.1 >
On Tue, 13 Dec 2022, Qing Zhao wrote: > Richard, > > Do you have any decision on this one? > Do we need this warning option For GCC? Looking at the testcases it seems that the diagnostic amends -Warray-bounds diagnostics for trailing but not flexible arrays? Wouldn't it be better to generally diagnose this, so have -Warray-bounds, with -fstrict-flex-arrays, for struct X { int a[1]; }; int foo (struct X *p) { return p->a[1]; } emit warning: array subscript 1 is above array bounds ... note: the trailing array is only a flexible array member with -fno-strict-flex-arrays ? Having -Wstrict-flex-arrays=N and N not agree with the -fstrict-flex-arrays level sounds hardly useful to me but the information that we ran into a trailing array but didn't consider it a flex array because of -fstrict-flex-arrays is always a useful information? But maybe I misunderstood this new diagnostic? Thanks, Richard. > thanks. > > Qing > > > On Dec 6, 2022, at 11:18 AM, Qing Zhao <qing.zhao@oracle.com> wrote: > > > > '-Wstrict-flex-arrays' > > Warn about inproper usages of flexible array members according to > > the LEVEL of the 'strict_flex_array (LEVEL)' attribute attached to > > the trailing array field of a structure if it's available, > > otherwise according to the LEVEL of the option > > '-fstrict-flex-arrays=LEVEL'. > > > > This option is effective only when LEVEL is bigger than 0. > > Otherwise, it will be ignored with a warning. > > > > when LEVEL=1, warnings will be issued for a trailing array > > reference of a structure that have 2 or more elements if the > > trailing array is referenced as a flexible array member. > > > > when LEVEL=2, in addition to LEVEL=1, additional warnings will be > > issued for a trailing one-element array reference of a structure if > > the array is referenced as a flexible array member. > > > > when LEVEL=3, in addition to LEVEL=2, additional warnings will be > > issued for a trailing zero-length array reference of a structure if > > the array is referenced as a flexible array member. > > > > gcc/ChangeLog: > > > > * doc/invoke.texi: Document -Wstrict-flex-arrays option. > > * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Add two more > > arguments. > > (array_bounds_checker::check_array_ref): Issue warnings for > > -Wstrict-flex-arrays. > > * opts.cc (finish_options): Issue warning for unsupported combination > > of -Wstrict_flex_arrays and -fstrict-flex-array. > > * tree-vrp.cc (execute_ranger_vrp): Enable the pass when > > warn_strict_flex_array is true. > > > > gcc/c-family/ChangeLog: > > > > * c.opt (Wstrict-flex-arrays): New option. > > > > gcc/testsuite/ChangeLog: > > > > * gcc.dg/Warray-bounds-flex-arrays-1.c: Update testing case with > > -Wstrict-flex-arrays. > > * gcc.dg/Warray-bounds-flex-arrays-2.c: Likewise. > > * gcc.dg/Warray-bounds-flex-arrays-3.c: Likewise. > > * gcc.dg/Warray-bounds-flex-arrays-4.c: Likewise. > > * gcc.dg/Warray-bounds-flex-arrays-5.c: Likewise. > > * gcc.dg/Warray-bounds-flex-arrays-6.c: Likewise. > > * c-c++-common/Wstrict-flex-arrays.c: New test. > > * gcc.dg/Wstrict-flex-arrays-2.c: New test. > > * gcc.dg/Wstrict-flex-arrays-3.c: New test. > > * gcc.dg/Wstrict-flex-arrays.c: New test. > > --- > > gcc/c-family/c.opt | 5 + > > gcc/doc/invoke.texi | 27 ++++- > > gcc/gimple-array-bounds.cc | 103 ++++++++++++++---- > > gcc/opts.cc | 8 ++ > > .../c-c++-common/Wstrict-flex-arrays.c | 9 ++ > > .../gcc.dg/Warray-bounds-flex-arrays-1.c | 5 +- > > .../gcc.dg/Warray-bounds-flex-arrays-2.c | 6 +- > > .../gcc.dg/Warray-bounds-flex-arrays-3.c | 7 +- > > .../gcc.dg/Warray-bounds-flex-arrays-4.c | 5 +- > > .../gcc.dg/Warray-bounds-flex-arrays-5.c | 6 +- > > .../gcc.dg/Warray-bounds-flex-arrays-6.c | 7 +- > > gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c | 39 +++++++ > > gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c | 39 +++++++ > > gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c | 39 +++++++ > > gcc/tree-vrp.cc | 2 +- > > 15 files changed, 273 insertions(+), 34 deletions(-) > > create mode 100644 gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c > > create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > > create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > > create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > > > > diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt > > index 0d0ad0a6374..33edeefd285 100644 > > --- a/gcc/c-family/c.opt > > +++ b/gcc/c-family/c.opt > > @@ -976,6 +976,11 @@ Wstringop-truncation > > C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ LTO ObjC++, Wall) > > Warn about truncation in string manipulation functions like strncat and strncpy. > > > > +Wstrict-flex-arrays > > +C C++ Var(warn_strict_flex_arrays) Warning > > +Warn about inproper usages of flexible array members > > +according to the level of -fstrict-flex-arrays. > > + > > Wsuggest-attribute=format > > C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning > > Warn about functions which might be candidates for format attributes. > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > > index 726392409b6..4402b0427ef 100644 > > --- a/gcc/doc/invoke.texi > > +++ b/gcc/doc/invoke.texi > > @@ -398,7 +398,7 @@ Objective-C and Objective-C++ Dialects}. > > -Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol > > -Wstring-compare @gol > > -Wno-stringop-overflow -Wno-stringop-overread @gol > > --Wno-stringop-truncation @gol > > +-Wno-stringop-truncation -Wstrict-flex-arrays @gol > > -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol > > -Wswitch -Wno-switch-bool -Wswitch-default -Wswitch-enum @gol > > -Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand @gol > > @@ -7835,6 +7835,31 @@ however, are not suitable arguments to functions that expect > > such arrays GCC issues warnings unless it can prove that the use is > > safe. @xref{Common Variable Attributes}. > > > > +@item -Wstrict-flex-arrays > > +@opindex Wstrict-flex-arrays > > +@opindex Wno-strict-flex-arrays > > +Warn about inproper usages of flexible array members > > +according to the @var{level} of the @code{strict_flex_array (@var{level})} > > +attribute attached to the trailing array field of a structure if it's > > +available, otherwise according to the @var{level} of the option > > +@option{-fstrict-flex-arrays=@var{level}}. > > + > > +This option is effective only when @var{level} is bigger than 0. Otherwise, > > +it will be ignored with a warning. > > + > > +when @var{level}=1, warnings will be issued for a trailing array reference > > +of a structure that have 2 or more elements if the trailing array is referenced > > +as a flexible array member. > > + > > +when @var{level}=2, in addition to @var{level}=1, additional warnings will be > > +issued for a trailing one-element array reference of a structure > > +if the array is referenced as a flexible array member. > > + > > +when @var{level}=3, in addition to @var{level}=2, additional warnings will be > > +issued for a trailing zero-length array reference of a structure > > +if the array is referenced as a flexible array member. > > + > > + > > @item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]} > > @opindex Wsuggest-attribute= > > @opindex Wno-suggest-attribute= > > diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc > > index db3459af325..825f11331b5 100644 > > --- a/gcc/gimple-array-bounds.cc > > +++ b/gcc/gimple-array-bounds.cc > > @@ -252,25 +252,34 @@ get_up_bounds_for_array_ref (tree ref, tree *decl, > > > > /* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND > > and UP_BOUND_P1, check whether the array reference REF is out of bound. > > - Issue warnings if out of bound, return TRUE if warnings are issued. */ > > + When out of bounds, set OUT_OF_BOUND to true. > > + Issue warnings if FOR_ARRAY_BOUND is true. > > + return TRUE if warnings are issued. */ > > + > > > > static bool > > check_out_of_bounds_and_warn (location_t location, tree ref, > > tree low_sub_org, tree low_sub, tree up_sub, > > tree up_bound, tree up_bound_p1, > > const value_range *vr, > > - bool ignore_off_by_one) > > + bool ignore_off_by_one, bool for_array_bound, > > + bool *out_of_bound) > > { > > tree low_bound = array_ref_low_bound (ref); > > tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); > > > > bool warned = false; > > + *out_of_bound = false; > > > > /* Empty array. */ > > if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1)) > > - warned = warning_at (location, OPT_Warray_bounds_, > > - "array subscript %E is outside array bounds of %qT", > > - low_sub_org, artype); > > + { > > + *out_of_bound = true; > > + if (for_array_bound) > > + warned = warning_at (location, OPT_Warray_bounds_, > > + "array subscript %E is outside array" > > + " bounds of %qT", low_sub_org, artype); > > + } > > > > if (warned) > > ; /* Do nothing. */ > > @@ -283,24 +292,33 @@ check_out_of_bounds_and_warn (location_t location, tree ref, > > : tree_int_cst_le (up_bound, up_sub)) > > && TREE_CODE (low_sub) == INTEGER_CST > > && tree_int_cst_le (low_sub, low_bound)) > > - warned = warning_at (location, OPT_Warray_bounds_, > > - "array subscript [%E, %E] is outside " > > - "array bounds of %qT", > > - low_sub, up_sub, artype); > > + { > > + *out_of_bound = true; > > + warned = warning_at (location, OPT_Warray_bounds_, > > + "array subscript [%E, %E] is outside " > > + "array bounds of %qT", > > + low_sub, up_sub, artype); > > + } > > } > > else if (up_bound > > && TREE_CODE (up_sub) == INTEGER_CST > > && (ignore_off_by_one > > ? !tree_int_cst_le (up_sub, up_bound_p1) > > : !tree_int_cst_le (up_sub, up_bound))) > > - warned = warning_at (location, OPT_Warray_bounds_, > > - "array subscript %E is above array bounds of %qT", > > - up_sub, artype); > > + { > > + *out_of_bound = true; > > + warned = warning_at (location, OPT_Warray_bounds_, > > + "array subscript %E is above array bounds of %qT", > > + up_sub, artype); > > + } > > else if (TREE_CODE (low_sub) == INTEGER_CST > > && tree_int_cst_lt (low_sub, low_bound)) > > - warned = warning_at (location, OPT_Warray_bounds_, > > - "array subscript %E is below array bounds of %qT", > > - low_sub, artype); > > + { > > + *out_of_bound = true; > > + warned = warning_at (location, OPT_Warray_bounds_, > > + "array subscript %E is below array bounds of %qT", > > + low_sub, artype); > > + } > > return warned; > > } > > > > @@ -333,14 +351,21 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > > > > tree arg = TREE_OPERAND (ref, 0); > > const bool compref = TREE_CODE (arg) == COMPONENT_REF; > > + unsigned int strict_flex_array_level = flag_strict_flex_arrays; > > > > if (compref) > > - /* Try to determine special array member type for this COMPONENT_REF. */ > > - sam = component_ref_sam_type (arg); > > + { > > + /* Try to determine special array member type for this COMPONENT_REF. */ > > + sam = component_ref_sam_type (arg); > > + /* Get the level of strict_flex_array for this array field. */ > > + tree afield_decl = TREE_OPERAND (arg, 1); > > + strict_flex_array_level = strict_flex_array_level_of (afield_decl); > > + } > > > > get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); > > > > bool warned = false; > > + bool out_of_bound = false; > > > > tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); > > tree low_sub_org = TREE_OPERAND (ref, 1); > > @@ -361,7 +386,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > > warned = check_out_of_bounds_and_warn (location, ref, > > low_sub_org, low_sub, up_sub, > > up_bound, up_bound_p1, vr, > > - ignore_off_by_one); > > + ignore_off_by_one, warn_array_bounds, > > + &out_of_bound); > > > > > > if (!warned && sam == special_array_member::int_0) > > @@ -373,19 +399,56 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > > "of an interior zero-length array %qT")), > > low_sub, artype); > > > > - if (warned) > > + if (warned || out_of_bound) > > { > > - if (dump_file && (dump_flags & TDF_DETAILS)) > > + if (warned && dump_file && (dump_flags & TDF_DETAILS)) > > { > > fprintf (dump_file, "Array bound warning for "); > > dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); > > fprintf (dump_file, "\n"); > > } > > > > + /* issue warnings for -Wstrict-flex-arrays according to the level of > > + flag_strict_flex_arrays. */ > > + if (out_of_bound && warn_strict_flex_arrays) > > + switch (strict_flex_array_level) > > + { > > + case 3: > > + /* Issue additional warnings for trailing arrays [0]. */ > > + if (sam == special_array_member::trail_0) > > + warned = warning_at (location, OPT_Wstrict_flex_arrays, > > + "trailing array %qT should not be used as " > > + "a flexible array member for level 3", > > + artype); > > + /* FALLTHROUGH. */ > > + case 2: > > + /* Issue additional warnings for trailing arrays [1]. */ > > + if (sam == special_array_member::trail_1) > > + warned = warning_at (location, OPT_Wstrict_flex_arrays, > > + "trailing array %qT should not be used as " > > + "a flexible array member for level 2 and " > > + "above", artype); > > + /* FALLTHROUGH. */ > > + case 1: > > + /* Issue warnings for trailing arrays [n]. */ > > + if (sam == special_array_member::trail_n) > > + warned = warning_at (location, OPT_Wstrict_flex_arrays, > > + "trailing array %qT should not be used as " > > + "a flexible array member for level 1 and " > > + "above", artype); > > + break; > > + case 0: > > + /* Do nothing. */ > > + break; > > + default: > > + gcc_unreachable (); > > + } > > + > > /* Avoid more warnings when checking more significant subscripts > > of the same expression. */ > > ref = TREE_OPERAND (ref, 0); > > suppress_warning (ref, OPT_Warray_bounds_); > > + suppress_warning (ref, OPT_Wstrict_flex_arrays); > > > > if (decl) > > ref = decl; > > diff --git a/gcc/opts.cc b/gcc/opts.cc > > index 73fc97756e4..8db53ad6c77 100644 > > --- a/gcc/opts.cc > > +++ b/gcc/opts.cc > > @@ -1411,6 +1411,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, > > opts->x_profile_flag = 0; > > } > > > > + if (opts->x_warn_strict_flex_arrays) > > + if (opts->x_flag_strict_flex_arrays == 0) > > + { > > + opts->x_warn_strict_flex_arrays = 0; > > + warning_at (UNKNOWN_LOCATION, 0, > > + "%<-Wstrict-flex-arrays%> is ignored when" > > + " %<-fstrict-flex-arrays%> does not present"); > > + } > > > > diagnose_options (opts, opts_set, loc); > > } > > diff --git a/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c > > new file mode 100644 > > index 00000000000..72b4b7c6406 > > --- /dev/null > > +++ b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c > > @@ -0,0 +1,9 @@ > > +/* Test the usage of option -Wstrict-flex-arrays. */ > > +/* { dg-do compile } */ > > +/* { dg-options "-O2 -Wstrict-flex-arrays" } */ > > + > > +int main(int argc, char *argv[]) > > +{ > > + return 0; > > +} > > +/* { dg-warning "is ignored when \'-fstrict-flex-arrays\' does not present" "" { target *-*-* } 0 } */ > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > > index d36ba4d86cb..65c9fec43af 100644 > > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > > @@ -1,6 +1,6 @@ > > -/* Test -fstrict-flex-arrays + -Warray-bounds. */ > > +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ > > /* { dg-do compile} */ > > -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */ > > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds" } */ > > > > struct trailing_array_1 { > > int a; > > @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( > > struct trailing_array_4 *trailing_flex) > > { > > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > > + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > > trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ > > trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > > index f63206e1948..2b5a895c598 100644 > > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > > @@ -1,6 +1,6 @@ > > -/* Test -fstrict-flex-arrays + -Warray-bounds. */ > > +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */ > > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds" } */ > > > > struct trailing_array_1 { > > int a; > > @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( > > struct trailing_array_4 *trailing_flex) > > { > > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > > + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > > trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ > > + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > > trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > > > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > > index e3273714e8b..25b903f2615 100644 > > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > > @@ -1,6 +1,6 @@ > > -/* Test -fstrict-flex-arrays + -Warray-bounds. */ > > +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */ > > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds" } */ > > > > struct trailing_array_1 { > > int a; > > @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( > > struct trailing_array_4 *trailing_flex) > > { > > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > > + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > > trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > > + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > > trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ > > + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ > > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */ > > > > } > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > > index cabaea77dc2..5fc500a19ca 100644 > > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > > @@ -1,6 +1,6 @@ > > -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ > > +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */ > > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds=2" } */ > > > > struct trailing_array_1 { > > int a; > > @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( > > struct trailing_array_4 *trailing_flex) > > { > > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > > + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > > trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ > > trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > > index 8b7db6e4f39..30bb4ca8832 100644 > > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > > @@ -1,6 +1,6 @@ > > -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ > > +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */ > > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds=2" } */ > > > > struct trailing_array_1 { > > int a; > > @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( > > struct trailing_array_4 *trailing_flex) > > { > > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > > + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > > trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > > + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > > trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > > > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > > index 035bf481396..e847a44516e 100644 > > --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > > @@ -1,6 +1,6 @@ > > -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ > > +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ > > /* { dg-do compile } */ > > -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */ > > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds=2" } */ > > > > struct trailing_array_1 { > > int a; > > @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( > > struct trailing_array_4 *trailing_flex) > > { > > normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > > + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > > trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > > + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > > trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ > > + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ > > trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > > > > } > > diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > > new file mode 100644 > > index 00000000000..2e241f96208 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > > @@ -0,0 +1,39 @@ > > +/* Test -Wstrict-flex-arrays. */ > > +/* { dg-do compile } */ > > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2" } */ > > + > > +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) > > +{ > > + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > > + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ > > + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ > > + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ > > + > > +} > > diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > > new file mode 100644 > > index 00000000000..97eb65ba0a9 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > > @@ -0,0 +1,39 @@ > > +/* Test -Wstrict-flex-arrays. */ > > +/* { dg-do compile } */ > > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3" } */ > > + > > +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) > > +{ > > + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > > + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ > > + trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */ > > + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */ > > + > > +} > > diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > > new file mode 100644 > > index 00000000000..110fdc72778 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > > @@ -0,0 +1,39 @@ > > +/* Test -Wstrict-flex-arrays. */ > > +/* { dg-do compile } */ > > +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1" } */ > > + > > +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) > > +{ > > + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > > + trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > > + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > > + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > > + > > +} > > diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc > > index 3846dc1d849..e6c6c5a301d 100644 > > --- a/gcc/tree-vrp.cc > > +++ b/gcc/tree-vrp.cc > > @@ -1087,7 +1087,7 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p, > > if (dump_file && (dump_flags & TDF_DETAILS)) > > ranger->dump (dump_file); > > > > - if (warn_array_bounds && warn_array_bounds_p) > > + if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p) > > { > > // Set all edges as executable, except those ranger says aren't. > > int non_exec_flag = ranger->non_executable_edge_flag; > > -- > > 2.31.1 > > > >
> On Dec 14, 2022, at 4:03 AM, Richard Biener <rguenther@suse.de> wrote: > > On Tue, 13 Dec 2022, Qing Zhao wrote: > >> Richard, >> >> Do you have any decision on this one? >> Do we need this warning option For GCC? > > Looking at the testcases it seems that the diagnostic amends > -Warray-bounds diagnostics for trailing but not flexible arrays? Yes. > Wouldn't it be better to generally diagnose this, so have > -Warray-bounds, with -fstrict-flex-arrays, for > > struct X { int a[1]; }; > int foo (struct X *p) > { > return p->a[1]; > } > > emit > > warning: array subscript 1 is above array bounds ... > note: the trailing array is only a flexible array member with > -fno-strict-flex-arrays This is good too. My only concern with doing this is, the default warning messages of -Warray-bounds would be different than the current ones, will this have any impact on the current users? > > ? Having -Wstrict-flex-arrays=N and N not agree with the > -fstrict-flex-arrays level sounds hardly useful to me but the > information that we ran into a trailing array but didn't consider > it a flex array because of -fstrict-flex-arrays is always a > useful information? -Wstrict-flex-arrays does NOT have the argument “N”. Its level will be consistent with the level “N” of the corresponding -fstrict-flex-array=N. -Wstrict-flex-arrays option is only valid when -fstrict-flex-arrays is present, it will report any misuse of treating trailing array as flexible array at the LEVEL of -fstrict-flex-arrays. Let me know if it is still not very clear. thanks. Qing > > But maybe I misunderstood this new diagnostic? > > Thanks, > Richard. > > >> thanks. >> >> Qing >> >>> On Dec 6, 2022, at 11:18 AM, Qing Zhao <qing.zhao@oracle.com> wrote: >>> >>> '-Wstrict-flex-arrays' >>> Warn about inproper usages of flexible array members according to >>> the LEVEL of the 'strict_flex_array (LEVEL)' attribute attached to >>> the trailing array field of a structure if it's available, >>> otherwise according to the LEVEL of the option >>> '-fstrict-flex-arrays=LEVEL'. >>> >>> This option is effective only when LEVEL is bigger than 0. >>> Otherwise, it will be ignored with a warning. >>> >>> when LEVEL=1, warnings will be issued for a trailing array >>> reference of a structure that have 2 or more elements if the >>> trailing array is referenced as a flexible array member. >>> >>> when LEVEL=2, in addition to LEVEL=1, additional warnings will be >>> issued for a trailing one-element array reference of a structure if >>> the array is referenced as a flexible array member. >>> >>> when LEVEL=3, in addition to LEVEL=2, additional warnings will be >>> issued for a trailing zero-length array reference of a structure if >>> the array is referenced as a flexible array member. >>> >>> gcc/ChangeLog: >>> >>> * doc/invoke.texi: Document -Wstrict-flex-arrays option. >>> * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Add two more >>> arguments. >>> (array_bounds_checker::check_array_ref): Issue warnings for >>> -Wstrict-flex-arrays. >>> * opts.cc (finish_options): Issue warning for unsupported combination >>> of -Wstrict_flex_arrays and -fstrict-flex-array. >>> * tree-vrp.cc (execute_ranger_vrp): Enable the pass when >>> warn_strict_flex_array is true. >>> >>> gcc/c-family/ChangeLog: >>> >>> * c.opt (Wstrict-flex-arrays): New option. >>> >>> gcc/testsuite/ChangeLog: >>> >>> * gcc.dg/Warray-bounds-flex-arrays-1.c: Update testing case with >>> -Wstrict-flex-arrays. >>> * gcc.dg/Warray-bounds-flex-arrays-2.c: Likewise. >>> * gcc.dg/Warray-bounds-flex-arrays-3.c: Likewise. >>> * gcc.dg/Warray-bounds-flex-arrays-4.c: Likewise. >>> * gcc.dg/Warray-bounds-flex-arrays-5.c: Likewise. >>> * gcc.dg/Warray-bounds-flex-arrays-6.c: Likewise. >>> * c-c++-common/Wstrict-flex-arrays.c: New test. >>> * gcc.dg/Wstrict-flex-arrays-2.c: New test. >>> * gcc.dg/Wstrict-flex-arrays-3.c: New test. >>> * gcc.dg/Wstrict-flex-arrays.c: New test. >>> --- >>> gcc/c-family/c.opt | 5 + >>> gcc/doc/invoke.texi | 27 ++++- >>> gcc/gimple-array-bounds.cc | 103 ++++++++++++++---- >>> gcc/opts.cc | 8 ++ >>> .../c-c++-common/Wstrict-flex-arrays.c | 9 ++ >>> .../gcc.dg/Warray-bounds-flex-arrays-1.c | 5 +- >>> .../gcc.dg/Warray-bounds-flex-arrays-2.c | 6 +- >>> .../gcc.dg/Warray-bounds-flex-arrays-3.c | 7 +- >>> .../gcc.dg/Warray-bounds-flex-arrays-4.c | 5 +- >>> .../gcc.dg/Warray-bounds-flex-arrays-5.c | 6 +- >>> .../gcc.dg/Warray-bounds-flex-arrays-6.c | 7 +- >>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c | 39 +++++++ >>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c | 39 +++++++ >>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c | 39 +++++++ >>> gcc/tree-vrp.cc | 2 +- >>> 15 files changed, 273 insertions(+), 34 deletions(-) >>> create mode 100644 gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>> >>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt >>> index 0d0ad0a6374..33edeefd285 100644 >>> --- a/gcc/c-family/c.opt >>> +++ b/gcc/c-family/c.opt >>> @@ -976,6 +976,11 @@ Wstringop-truncation >>> C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ LTO ObjC++, Wall) >>> Warn about truncation in string manipulation functions like strncat and strncpy. >>> >>> +Wstrict-flex-arrays >>> +C C++ Var(warn_strict_flex_arrays) Warning >>> +Warn about inproper usages of flexible array members >>> +according to the level of -fstrict-flex-arrays. >>> + >>> Wsuggest-attribute=format >>> C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning >>> Warn about functions which might be candidates for format attributes. >>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi >>> index 726392409b6..4402b0427ef 100644 >>> --- a/gcc/doc/invoke.texi >>> +++ b/gcc/doc/invoke.texi >>> @@ -398,7 +398,7 @@ Objective-C and Objective-C++ Dialects}. >>> -Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol >>> -Wstring-compare @gol >>> -Wno-stringop-overflow -Wno-stringop-overread @gol >>> --Wno-stringop-truncation @gol >>> +-Wno-stringop-truncation -Wstrict-flex-arrays @gol >>> -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol >>> -Wswitch -Wno-switch-bool -Wswitch-default -Wswitch-enum @gol >>> -Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand @gol >>> @@ -7835,6 +7835,31 @@ however, are not suitable arguments to functions that expect >>> such arrays GCC issues warnings unless it can prove that the use is >>> safe. @xref{Common Variable Attributes}. >>> >>> +@item -Wstrict-flex-arrays >>> +@opindex Wstrict-flex-arrays >>> +@opindex Wno-strict-flex-arrays >>> +Warn about inproper usages of flexible array members >>> +according to the @var{level} of the @code{strict_flex_array (@var{level})} >>> +attribute attached to the trailing array field of a structure if it's >>> +available, otherwise according to the @var{level} of the option >>> +@option{-fstrict-flex-arrays=@var{level}}. >>> + >>> +This option is effective only when @var{level} is bigger than 0. Otherwise, >>> +it will be ignored with a warning. >>> + >>> +when @var{level}=1, warnings will be issued for a trailing array reference >>> +of a structure that have 2 or more elements if the trailing array is referenced >>> +as a flexible array member. >>> + >>> +when @var{level}=2, in addition to @var{level}=1, additional warnings will be >>> +issued for a trailing one-element array reference of a structure >>> +if the array is referenced as a flexible array member. >>> + >>> +when @var{level}=3, in addition to @var{level}=2, additional warnings will be >>> +issued for a trailing zero-length array reference of a structure >>> +if the array is referenced as a flexible array member. >>> + >>> + >>> @item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]} >>> @opindex Wsuggest-attribute= >>> @opindex Wno-suggest-attribute= >>> diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc >>> index db3459af325..825f11331b5 100644 >>> --- a/gcc/gimple-array-bounds.cc >>> +++ b/gcc/gimple-array-bounds.cc >>> @@ -252,25 +252,34 @@ get_up_bounds_for_array_ref (tree ref, tree *decl, >>> >>> /* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND >>> and UP_BOUND_P1, check whether the array reference REF is out of bound. >>> - Issue warnings if out of bound, return TRUE if warnings are issued. */ >>> + When out of bounds, set OUT_OF_BOUND to true. >>> + Issue warnings if FOR_ARRAY_BOUND is true. >>> + return TRUE if warnings are issued. */ >>> + >>> >>> static bool >>> check_out_of_bounds_and_warn (location_t location, tree ref, >>> tree low_sub_org, tree low_sub, tree up_sub, >>> tree up_bound, tree up_bound_p1, >>> const value_range *vr, >>> - bool ignore_off_by_one) >>> + bool ignore_off_by_one, bool for_array_bound, >>> + bool *out_of_bound) >>> { >>> tree low_bound = array_ref_low_bound (ref); >>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); >>> >>> bool warned = false; >>> + *out_of_bound = false; >>> >>> /* Empty array. */ >>> if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1)) >>> - warned = warning_at (location, OPT_Warray_bounds_, >>> - "array subscript %E is outside array bounds of %qT", >>> - low_sub_org, artype); >>> + { >>> + *out_of_bound = true; >>> + if (for_array_bound) >>> + warned = warning_at (location, OPT_Warray_bounds_, >>> + "array subscript %E is outside array" >>> + " bounds of %qT", low_sub_org, artype); >>> + } >>> >>> if (warned) >>> ; /* Do nothing. */ >>> @@ -283,24 +292,33 @@ check_out_of_bounds_and_warn (location_t location, tree ref, >>> : tree_int_cst_le (up_bound, up_sub)) >>> && TREE_CODE (low_sub) == INTEGER_CST >>> && tree_int_cst_le (low_sub, low_bound)) >>> - warned = warning_at (location, OPT_Warray_bounds_, >>> - "array subscript [%E, %E] is outside " >>> - "array bounds of %qT", >>> - low_sub, up_sub, artype); >>> + { >>> + *out_of_bound = true; >>> + warned = warning_at (location, OPT_Warray_bounds_, >>> + "array subscript [%E, %E] is outside " >>> + "array bounds of %qT", >>> + low_sub, up_sub, artype); >>> + } >>> } >>> else if (up_bound >>> && TREE_CODE (up_sub) == INTEGER_CST >>> && (ignore_off_by_one >>> ? !tree_int_cst_le (up_sub, up_bound_p1) >>> : !tree_int_cst_le (up_sub, up_bound))) >>> - warned = warning_at (location, OPT_Warray_bounds_, >>> - "array subscript %E is above array bounds of %qT", >>> - up_sub, artype); >>> + { >>> + *out_of_bound = true; >>> + warned = warning_at (location, OPT_Warray_bounds_, >>> + "array subscript %E is above array bounds of %qT", >>> + up_sub, artype); >>> + } >>> else if (TREE_CODE (low_sub) == INTEGER_CST >>> && tree_int_cst_lt (low_sub, low_bound)) >>> - warned = warning_at (location, OPT_Warray_bounds_, >>> - "array subscript %E is below array bounds of %qT", >>> - low_sub, artype); >>> + { >>> + *out_of_bound = true; >>> + warned = warning_at (location, OPT_Warray_bounds_, >>> + "array subscript %E is below array bounds of %qT", >>> + low_sub, artype); >>> + } >>> return warned; >>> } >>> >>> @@ -333,14 +351,21 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>> >>> tree arg = TREE_OPERAND (ref, 0); >>> const bool compref = TREE_CODE (arg) == COMPONENT_REF; >>> + unsigned int strict_flex_array_level = flag_strict_flex_arrays; >>> >>> if (compref) >>> - /* Try to determine special array member type for this COMPONENT_REF. */ >>> - sam = component_ref_sam_type (arg); >>> + { >>> + /* Try to determine special array member type for this COMPONENT_REF. */ >>> + sam = component_ref_sam_type (arg); >>> + /* Get the level of strict_flex_array for this array field. */ >>> + tree afield_decl = TREE_OPERAND (arg, 1); >>> + strict_flex_array_level = strict_flex_array_level_of (afield_decl); >>> + } >>> >>> get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); >>> >>> bool warned = false; >>> + bool out_of_bound = false; >>> >>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); >>> tree low_sub_org = TREE_OPERAND (ref, 1); >>> @@ -361,7 +386,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>> warned = check_out_of_bounds_and_warn (location, ref, >>> low_sub_org, low_sub, up_sub, >>> up_bound, up_bound_p1, vr, >>> - ignore_off_by_one); >>> + ignore_off_by_one, warn_array_bounds, >>> + &out_of_bound); >>> >>> >>> if (!warned && sam == special_array_member::int_0) >>> @@ -373,19 +399,56 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>> "of an interior zero-length array %qT")), >>> low_sub, artype); >>> >>> - if (warned) >>> + if (warned || out_of_bound) >>> { >>> - if (dump_file && (dump_flags & TDF_DETAILS)) >>> + if (warned && dump_file && (dump_flags & TDF_DETAILS)) >>> { >>> fprintf (dump_file, "Array bound warning for "); >>> dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); >>> fprintf (dump_file, "\n"); >>> } >>> >>> + /* issue warnings for -Wstrict-flex-arrays according to the level of >>> + flag_strict_flex_arrays. */ >>> + if (out_of_bound && warn_strict_flex_arrays) >>> + switch (strict_flex_array_level) >>> + { >>> + case 3: >>> + /* Issue additional warnings for trailing arrays [0]. */ >>> + if (sam == special_array_member::trail_0) >>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>> + "trailing array %qT should not be used as " >>> + "a flexible array member for level 3", >>> + artype); >>> + /* FALLTHROUGH. */ >>> + case 2: >>> + /* Issue additional warnings for trailing arrays [1]. */ >>> + if (sam == special_array_member::trail_1) >>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>> + "trailing array %qT should not be used as " >>> + "a flexible array member for level 2 and " >>> + "above", artype); >>> + /* FALLTHROUGH. */ >>> + case 1: >>> + /* Issue warnings for trailing arrays [n]. */ >>> + if (sam == special_array_member::trail_n) >>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>> + "trailing array %qT should not be used as " >>> + "a flexible array member for level 1 and " >>> + "above", artype); >>> + break; >>> + case 0: >>> + /* Do nothing. */ >>> + break; >>> + default: >>> + gcc_unreachable (); >>> + } >>> + >>> /* Avoid more warnings when checking more significant subscripts >>> of the same expression. */ >>> ref = TREE_OPERAND (ref, 0); >>> suppress_warning (ref, OPT_Warray_bounds_); >>> + suppress_warning (ref, OPT_Wstrict_flex_arrays); >>> >>> if (decl) >>> ref = decl; >>> diff --git a/gcc/opts.cc b/gcc/opts.cc >>> index 73fc97756e4..8db53ad6c77 100644 >>> --- a/gcc/opts.cc >>> +++ b/gcc/opts.cc >>> @@ -1411,6 +1411,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, >>> opts->x_profile_flag = 0; >>> } >>> >>> + if (opts->x_warn_strict_flex_arrays) >>> + if (opts->x_flag_strict_flex_arrays == 0) >>> + { >>> + opts->x_warn_strict_flex_arrays = 0; >>> + warning_at (UNKNOWN_LOCATION, 0, >>> + "%<-Wstrict-flex-arrays%> is ignored when" >>> + " %<-fstrict-flex-arrays%> does not present"); >>> + } >>> >>> diagnose_options (opts, opts_set, loc); >>> } >>> diff --git a/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>> new file mode 100644 >>> index 00000000000..72b4b7c6406 >>> --- /dev/null >>> +++ b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>> @@ -0,0 +1,9 @@ >>> +/* Test the usage of option -Wstrict-flex-arrays. */ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays" } */ >>> + >>> +int main(int argc, char *argv[]) >>> +{ >>> + return 0; >>> +} >>> +/* { dg-warning "is ignored when \'-fstrict-flex-arrays\' does not present" "" { target *-*-* } 0 } */ >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>> index d36ba4d86cb..65c9fec43af 100644 >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>> @@ -1,6 +1,6 @@ >>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>> /* { dg-do compile} */ >>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds" } */ >>> >>> struct trailing_array_1 { >>> int a; >>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( >>> struct trailing_array_4 *trailing_flex) >>> { >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ >>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>> index f63206e1948..2b5a895c598 100644 >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>> @@ -1,6 +1,6 @@ >>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>> /* { dg-do compile } */ >>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds" } */ >>> >>> struct trailing_array_1 { >>> int a; >>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( >>> struct trailing_array_4 *trailing_flex) >>> { >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>> trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ >>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>> >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>> index e3273714e8b..25b903f2615 100644 >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>> @@ -1,6 +1,6 @@ >>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>> /* { dg-do compile } */ >>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds" } */ >>> >>> struct trailing_array_1 { >>> int a; >>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( >>> struct trailing_array_4 *trailing_flex) >>> { >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ >>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */ >>> >>> } >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>> index cabaea77dc2..5fc500a19ca 100644 >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>> @@ -1,6 +1,6 @@ >>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>> /* { dg-do compile } */ >>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds=2" } */ >>> >>> struct trailing_array_1 { >>> int a; >>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( >>> struct trailing_array_4 *trailing_flex) >>> { >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ >>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>> index 8b7db6e4f39..30bb4ca8832 100644 >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>> @@ -1,6 +1,6 @@ >>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>> /* { dg-do compile } */ >>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds=2" } */ >>> >>> struct trailing_array_1 { >>> int a; >>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( >>> struct trailing_array_4 *trailing_flex) >>> { >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>> >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>> index 035bf481396..e847a44516e 100644 >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>> @@ -1,6 +1,6 @@ >>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>> /* { dg-do compile } */ >>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds=2" } */ >>> >>> struct trailing_array_1 { >>> int a; >>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( >>> struct trailing_array_4 *trailing_flex) >>> { >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ >>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>> >>> } >>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>> new file mode 100644 >>> index 00000000000..2e241f96208 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>> @@ -0,0 +1,39 @@ >>> +/* Test -Wstrict-flex-arrays. */ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2" } */ >>> + >>> +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) >>> +{ >>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ >>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ >>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ >>> + >>> +} >>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>> new file mode 100644 >>> index 00000000000..97eb65ba0a9 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>> @@ -0,0 +1,39 @@ >>> +/* Test -Wstrict-flex-arrays. */ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3" } */ >>> + >>> +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) >>> +{ >>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ >>> + trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */ >>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */ >>> + >>> +} >>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>> new file mode 100644 >>> index 00000000000..110fdc72778 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>> @@ -0,0 +1,39 @@ >>> +/* Test -Wstrict-flex-arrays. */ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1" } */ >>> + >>> +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) >>> +{ >>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>> + trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>> + >>> +} >>> diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc >>> index 3846dc1d849..e6c6c5a301d 100644 >>> --- a/gcc/tree-vrp.cc >>> +++ b/gcc/tree-vrp.cc >>> @@ -1087,7 +1087,7 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p, >>> if (dump_file && (dump_flags & TDF_DETAILS)) >>> ranger->dump (dump_file); >>> >>> - if (warn_array_bounds && warn_array_bounds_p) >>> + if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p) >>> { >>> // Set all edges as executable, except those ranger says aren't. >>> int non_exec_flag = ranger->non_executable_edge_flag; >>> -- >>> 2.31.1 >>> >> >> > > -- > Richard Biener <rguenther@suse.de> > SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, > Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; > HRB 36809 (AG Nuernberg)
> On Dec 14, 2022, at 9:08 AM, Qing Zhao via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > >> On Dec 14, 2022, at 4:03 AM, Richard Biener <rguenther@suse.de> wrote: >> >> On Tue, 13 Dec 2022, Qing Zhao wrote: >> >>> Richard, >>> >>> Do you have any decision on this one? >>> Do we need this warning option For GCC? >> >> Looking at the testcases it seems that the diagnostic amends >> -Warray-bounds diagnostics for trailing but not flexible arrays? > > Yes. > >> Wouldn't it be better to generally diagnose this, so have >> -Warray-bounds, with -fstrict-flex-arrays, for >> >> struct X { int a[1]; }; >> int foo (struct X *p) >> { >> return p->a[1]; >> } >> >> emit >> >> warning: array subscript 1 is above array bounds ... >> note: the trailing array is only a flexible array member with >> -fno-strict-flex-arrays > > This is good too. > My only concern with doing this is, the default warning messages of -Warray-bounds would be different than > the current ones, will this have any impact on the current users? My bad, the default warning message of -Warray-bounds without -fstrict-flex-arrays should not be changed. Only when -fstrict-flex-arrays=N (N>0), the warning messages of -Warray-bounds will be different than the current one. This should be fine. > >> >> ? Having -Wstrict-flex-arrays=N and N not agree with the >> -fstrict-flex-arrays level sounds hardly useful to me but the >> information that we ran into a trailing array but didn't consider >> it a flex array because of -fstrict-flex-arrays is always a >> useful information? > > -Wstrict-flex-arrays does NOT have the argument “N”. Its level will be consistent with the level “N” of the corresponding > -fstrict-flex-array=N. > -Wstrict-flex-arrays option is only valid when -fstrict-flex-arrays is present, it will report any misuse of treating trailing array > as flexible array at the LEVEL of -fstrict-flex-arrays. > > Let me know if it is still not very clear. > > thanks. > > Qing >> >> But maybe I misunderstood this new diagnostic? >> >> Thanks, >> Richard. >> >> >>> thanks. >>> >>> Qing >>> >>>> On Dec 6, 2022, at 11:18 AM, Qing Zhao <qing.zhao@oracle.com> wrote: >>>> >>>> '-Wstrict-flex-arrays' >>>> Warn about inproper usages of flexible array members according to >>>> the LEVEL of the 'strict_flex_array (LEVEL)' attribute attached to >>>> the trailing array field of a structure if it's available, >>>> otherwise according to the LEVEL of the option >>>> '-fstrict-flex-arrays=LEVEL'. >>>> >>>> This option is effective only when LEVEL is bigger than 0. >>>> Otherwise, it will be ignored with a warning. >>>> >>>> when LEVEL=1, warnings will be issued for a trailing array >>>> reference of a structure that have 2 or more elements if the >>>> trailing array is referenced as a flexible array member. >>>> >>>> when LEVEL=2, in addition to LEVEL=1, additional warnings will be >>>> issued for a trailing one-element array reference of a structure if >>>> the array is referenced as a flexible array member. >>>> >>>> when LEVEL=3, in addition to LEVEL=2, additional warnings will be >>>> issued for a trailing zero-length array reference of a structure if >>>> the array is referenced as a flexible array member. >>>> >>>> gcc/ChangeLog: >>>> >>>> * doc/invoke.texi: Document -Wstrict-flex-arrays option. >>>> * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Add two more >>>> arguments. >>>> (array_bounds_checker::check_array_ref): Issue warnings for >>>> -Wstrict-flex-arrays. >>>> * opts.cc (finish_options): Issue warning for unsupported combination >>>> of -Wstrict_flex_arrays and -fstrict-flex-array. >>>> * tree-vrp.cc (execute_ranger_vrp): Enable the pass when >>>> warn_strict_flex_array is true. >>>> >>>> gcc/c-family/ChangeLog: >>>> >>>> * c.opt (Wstrict-flex-arrays): New option. >>>> >>>> gcc/testsuite/ChangeLog: >>>> >>>> * gcc.dg/Warray-bounds-flex-arrays-1.c: Update testing case with >>>> -Wstrict-flex-arrays. >>>> * gcc.dg/Warray-bounds-flex-arrays-2.c: Likewise. >>>> * gcc.dg/Warray-bounds-flex-arrays-3.c: Likewise. >>>> * gcc.dg/Warray-bounds-flex-arrays-4.c: Likewise. >>>> * gcc.dg/Warray-bounds-flex-arrays-5.c: Likewise. >>>> * gcc.dg/Warray-bounds-flex-arrays-6.c: Likewise. >>>> * c-c++-common/Wstrict-flex-arrays.c: New test. >>>> * gcc.dg/Wstrict-flex-arrays-2.c: New test. >>>> * gcc.dg/Wstrict-flex-arrays-3.c: New test. >>>> * gcc.dg/Wstrict-flex-arrays.c: New test. >>>> --- >>>> gcc/c-family/c.opt | 5 + >>>> gcc/doc/invoke.texi | 27 ++++- >>>> gcc/gimple-array-bounds.cc | 103 ++++++++++++++---- >>>> gcc/opts.cc | 8 ++ >>>> .../c-c++-common/Wstrict-flex-arrays.c | 9 ++ >>>> .../gcc.dg/Warray-bounds-flex-arrays-1.c | 5 +- >>>> .../gcc.dg/Warray-bounds-flex-arrays-2.c | 6 +- >>>> .../gcc.dg/Warray-bounds-flex-arrays-3.c | 7 +- >>>> .../gcc.dg/Warray-bounds-flex-arrays-4.c | 5 +- >>>> .../gcc.dg/Warray-bounds-flex-arrays-5.c | 6 +- >>>> .../gcc.dg/Warray-bounds-flex-arrays-6.c | 7 +- >>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c | 39 +++++++ >>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c | 39 +++++++ >>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c | 39 +++++++ >>>> gcc/tree-vrp.cc | 2 +- >>>> 15 files changed, 273 insertions(+), 34 deletions(-) >>>> create mode 100644 gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>>> >>>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt >>>> index 0d0ad0a6374..33edeefd285 100644 >>>> --- a/gcc/c-family/c.opt >>>> +++ b/gcc/c-family/c.opt >>>> @@ -976,6 +976,11 @@ Wstringop-truncation >>>> C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ LTO ObjC++, Wall) >>>> Warn about truncation in string manipulation functions like strncat and strncpy. >>>> >>>> +Wstrict-flex-arrays >>>> +C C++ Var(warn_strict_flex_arrays) Warning >>>> +Warn about inproper usages of flexible array members >>>> +according to the level of -fstrict-flex-arrays. >>>> + >>>> Wsuggest-attribute=format >>>> C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning >>>> Warn about functions which might be candidates for format attributes. >>>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi >>>> index 726392409b6..4402b0427ef 100644 >>>> --- a/gcc/doc/invoke.texi >>>> +++ b/gcc/doc/invoke.texi >>>> @@ -398,7 +398,7 @@ Objective-C and Objective-C++ Dialects}. >>>> -Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol >>>> -Wstring-compare @gol >>>> -Wno-stringop-overflow -Wno-stringop-overread @gol >>>> --Wno-stringop-truncation @gol >>>> +-Wno-stringop-truncation -Wstrict-flex-arrays @gol >>>> -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol >>>> -Wswitch -Wno-switch-bool -Wswitch-default -Wswitch-enum @gol >>>> -Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand @gol >>>> @@ -7835,6 +7835,31 @@ however, are not suitable arguments to functions that expect >>>> such arrays GCC issues warnings unless it can prove that the use is >>>> safe. @xref{Common Variable Attributes}. >>>> >>>> +@item -Wstrict-flex-arrays >>>> +@opindex Wstrict-flex-arrays >>>> +@opindex Wno-strict-flex-arrays >>>> +Warn about inproper usages of flexible array members >>>> +according to the @var{level} of the @code{strict_flex_array (@var{level})} >>>> +attribute attached to the trailing array field of a structure if it's >>>> +available, otherwise according to the @var{level} of the option >>>> +@option{-fstrict-flex-arrays=@var{level}}. >>>> + >>>> +This option is effective only when @var{level} is bigger than 0. Otherwise, >>>> +it will be ignored with a warning. >>>> + >>>> +when @var{level}=1, warnings will be issued for a trailing array reference >>>> +of a structure that have 2 or more elements if the trailing array is referenced >>>> +as a flexible array member. >>>> + >>>> +when @var{level}=2, in addition to @var{level}=1, additional warnings will be >>>> +issued for a trailing one-element array reference of a structure >>>> +if the array is referenced as a flexible array member. >>>> + >>>> +when @var{level}=3, in addition to @var{level}=2, additional warnings will be >>>> +issued for a trailing zero-length array reference of a structure >>>> +if the array is referenced as a flexible array member. >>>> + >>>> + >>>> @item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]} >>>> @opindex Wsuggest-attribute= >>>> @opindex Wno-suggest-attribute= >>>> diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc >>>> index db3459af325..825f11331b5 100644 >>>> --- a/gcc/gimple-array-bounds.cc >>>> +++ b/gcc/gimple-array-bounds.cc >>>> @@ -252,25 +252,34 @@ get_up_bounds_for_array_ref (tree ref, tree *decl, >>>> >>>> /* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND >>>> and UP_BOUND_P1, check whether the array reference REF is out of bound. >>>> - Issue warnings if out of bound, return TRUE if warnings are issued. */ >>>> + When out of bounds, set OUT_OF_BOUND to true. >>>> + Issue warnings if FOR_ARRAY_BOUND is true. >>>> + return TRUE if warnings are issued. */ >>>> + >>>> >>>> static bool >>>> check_out_of_bounds_and_warn (location_t location, tree ref, >>>> tree low_sub_org, tree low_sub, tree up_sub, >>>> tree up_bound, tree up_bound_p1, >>>> const value_range *vr, >>>> - bool ignore_off_by_one) >>>> + bool ignore_off_by_one, bool for_array_bound, >>>> + bool *out_of_bound) >>>> { >>>> tree low_bound = array_ref_low_bound (ref); >>>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); >>>> >>>> bool warned = false; >>>> + *out_of_bound = false; >>>> >>>> /* Empty array. */ >>>> if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1)) >>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>> - "array subscript %E is outside array bounds of %qT", >>>> - low_sub_org, artype); >>>> + { >>>> + *out_of_bound = true; >>>> + if (for_array_bound) >>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>> + "array subscript %E is outside array" >>>> + " bounds of %qT", low_sub_org, artype); >>>> + } >>>> >>>> if (warned) >>>> ; /* Do nothing. */ >>>> @@ -283,24 +292,33 @@ check_out_of_bounds_and_warn (location_t location, tree ref, >>>> : tree_int_cst_le (up_bound, up_sub)) >>>> && TREE_CODE (low_sub) == INTEGER_CST >>>> && tree_int_cst_le (low_sub, low_bound)) >>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>> - "array subscript [%E, %E] is outside " >>>> - "array bounds of %qT", >>>> - low_sub, up_sub, artype); >>>> + { >>>> + *out_of_bound = true; >>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>> + "array subscript [%E, %E] is outside " >>>> + "array bounds of %qT", >>>> + low_sub, up_sub, artype); >>>> + } >>>> } >>>> else if (up_bound >>>> && TREE_CODE (up_sub) == INTEGER_CST >>>> && (ignore_off_by_one >>>> ? !tree_int_cst_le (up_sub, up_bound_p1) >>>> : !tree_int_cst_le (up_sub, up_bound))) >>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>> - "array subscript %E is above array bounds of %qT", >>>> - up_sub, artype); >>>> + { >>>> + *out_of_bound = true; >>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>> + "array subscript %E is above array bounds of %qT", >>>> + up_sub, artype); >>>> + } >>>> else if (TREE_CODE (low_sub) == INTEGER_CST >>>> && tree_int_cst_lt (low_sub, low_bound)) >>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>> - "array subscript %E is below array bounds of %qT", >>>> - low_sub, artype); >>>> + { >>>> + *out_of_bound = true; >>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>> + "array subscript %E is below array bounds of %qT", >>>> + low_sub, artype); >>>> + } >>>> return warned; >>>> } >>>> >>>> @@ -333,14 +351,21 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>>> >>>> tree arg = TREE_OPERAND (ref, 0); >>>> const bool compref = TREE_CODE (arg) == COMPONENT_REF; >>>> + unsigned int strict_flex_array_level = flag_strict_flex_arrays; >>>> >>>> if (compref) >>>> - /* Try to determine special array member type for this COMPONENT_REF. */ >>>> - sam = component_ref_sam_type (arg); >>>> + { >>>> + /* Try to determine special array member type for this COMPONENT_REF. */ >>>> + sam = component_ref_sam_type (arg); >>>> + /* Get the level of strict_flex_array for this array field. */ >>>> + tree afield_decl = TREE_OPERAND (arg, 1); >>>> + strict_flex_array_level = strict_flex_array_level_of (afield_decl); >>>> + } >>>> >>>> get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); >>>> >>>> bool warned = false; >>>> + bool out_of_bound = false; >>>> >>>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); >>>> tree low_sub_org = TREE_OPERAND (ref, 1); >>>> @@ -361,7 +386,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>>> warned = check_out_of_bounds_and_warn (location, ref, >>>> low_sub_org, low_sub, up_sub, >>>> up_bound, up_bound_p1, vr, >>>> - ignore_off_by_one); >>>> + ignore_off_by_one, warn_array_bounds, >>>> + &out_of_bound); >>>> >>>> >>>> if (!warned && sam == special_array_member::int_0) >>>> @@ -373,19 +399,56 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>>> "of an interior zero-length array %qT")), >>>> low_sub, artype); >>>> >>>> - if (warned) >>>> + if (warned || out_of_bound) >>>> { >>>> - if (dump_file && (dump_flags & TDF_DETAILS)) >>>> + if (warned && dump_file && (dump_flags & TDF_DETAILS)) >>>> { >>>> fprintf (dump_file, "Array bound warning for "); >>>> dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); >>>> fprintf (dump_file, "\n"); >>>> } >>>> >>>> + /* issue warnings for -Wstrict-flex-arrays according to the level of >>>> + flag_strict_flex_arrays. */ >>>> + if (out_of_bound && warn_strict_flex_arrays) >>>> + switch (strict_flex_array_level) >>>> + { >>>> + case 3: >>>> + /* Issue additional warnings for trailing arrays [0]. */ >>>> + if (sam == special_array_member::trail_0) >>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>>> + "trailing array %qT should not be used as " >>>> + "a flexible array member for level 3", >>>> + artype); >>>> + /* FALLTHROUGH. */ >>>> + case 2: >>>> + /* Issue additional warnings for trailing arrays [1]. */ >>>> + if (sam == special_array_member::trail_1) >>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>>> + "trailing array %qT should not be used as " >>>> + "a flexible array member for level 2 and " >>>> + "above", artype); >>>> + /* FALLTHROUGH. */ >>>> + case 1: >>>> + /* Issue warnings for trailing arrays [n]. */ >>>> + if (sam == special_array_member::trail_n) >>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>>> + "trailing array %qT should not be used as " >>>> + "a flexible array member for level 1 and " >>>> + "above", artype); >>>> + break; >>>> + case 0: >>>> + /* Do nothing. */ >>>> + break; >>>> + default: >>>> + gcc_unreachable (); >>>> + } >>>> + >>>> /* Avoid more warnings when checking more significant subscripts >>>> of the same expression. */ >>>> ref = TREE_OPERAND (ref, 0); >>>> suppress_warning (ref, OPT_Warray_bounds_); >>>> + suppress_warning (ref, OPT_Wstrict_flex_arrays); >>>> >>>> if (decl) >>>> ref = decl; >>>> diff --git a/gcc/opts.cc b/gcc/opts.cc >>>> index 73fc97756e4..8db53ad6c77 100644 >>>> --- a/gcc/opts.cc >>>> +++ b/gcc/opts.cc >>>> @@ -1411,6 +1411,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, >>>> opts->x_profile_flag = 0; >>>> } >>>> >>>> + if (opts->x_warn_strict_flex_arrays) >>>> + if (opts->x_flag_strict_flex_arrays == 0) >>>> + { >>>> + opts->x_warn_strict_flex_arrays = 0; >>>> + warning_at (UNKNOWN_LOCATION, 0, >>>> + "%<-Wstrict-flex-arrays%> is ignored when" >>>> + " %<-fstrict-flex-arrays%> does not present"); >>>> + } >>>> >>>> diagnose_options (opts, opts_set, loc); >>>> } >>>> diff --git a/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>>> new file mode 100644 >>>> index 00000000000..72b4b7c6406 >>>> --- /dev/null >>>> +++ b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>>> @@ -0,0 +1,9 @@ >>>> +/* Test the usage of option -Wstrict-flex-arrays. */ >>>> +/* { dg-do compile } */ >>>> +/* { dg-options "-O2 -Wstrict-flex-arrays" } */ >>>> + >>>> +int main(int argc, char *argv[]) >>>> +{ >>>> + return 0; >>>> +} >>>> +/* { dg-warning "is ignored when \'-fstrict-flex-arrays\' does not present" "" { target *-*-* } 0 } */ >>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>>> index d36ba4d86cb..65c9fec43af 100644 >>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>>> @@ -1,6 +1,6 @@ >>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>>> /* { dg-do compile} */ >>>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */ >>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds" } */ >>>> >>>> struct trailing_array_1 { >>>> int a; >>>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( >>>> struct trailing_array_4 *trailing_flex) >>>> { >>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ >>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>>> index f63206e1948..2b5a895c598 100644 >>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>>> @@ -1,6 +1,6 @@ >>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>>> /* { dg-do compile } */ >>>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */ >>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds" } */ >>>> >>>> struct trailing_array_1 { >>>> int a; >>>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( >>>> struct trailing_array_4 *trailing_flex) >>>> { >>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>> trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ >>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>> >>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>>> index e3273714e8b..25b903f2615 100644 >>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>>> @@ -1,6 +1,6 @@ >>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>>> /* { dg-do compile } */ >>>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */ >>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds" } */ >>>> >>>> struct trailing_array_1 { >>>> int a; >>>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( >>>> struct trailing_array_4 *trailing_flex) >>>> { >>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ >>>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ >>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */ >>>> >>>> } >>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>>> index cabaea77dc2..5fc500a19ca 100644 >>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>>> @@ -1,6 +1,6 @@ >>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>>> /* { dg-do compile } */ >>>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */ >>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds=2" } */ >>>> >>>> struct trailing_array_1 { >>>> int a; >>>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( >>>> struct trailing_array_4 *trailing_flex) >>>> { >>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ >>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>>> index 8b7db6e4f39..30bb4ca8832 100644 >>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>>> @@ -1,6 +1,6 @@ >>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>>> /* { dg-do compile } */ >>>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */ >>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds=2" } */ >>>> >>>> struct trailing_array_1 { >>>> int a; >>>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( >>>> struct trailing_array_4 *trailing_flex) >>>> { >>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>> >>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>>> index 035bf481396..e847a44516e 100644 >>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>>> @@ -1,6 +1,6 @@ >>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>>> /* { dg-do compile } */ >>>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */ >>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds=2" } */ >>>> >>>> struct trailing_array_1 { >>>> int a; >>>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( >>>> struct trailing_array_4 *trailing_flex) >>>> { >>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ >>>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ >>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>> >>>> } >>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>>> new file mode 100644 >>>> index 00000000000..2e241f96208 >>>> --- /dev/null >>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>>> @@ -0,0 +1,39 @@ >>>> +/* Test -Wstrict-flex-arrays. */ >>>> +/* { dg-do compile } */ >>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2" } */ >>>> + >>>> +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) >>>> +{ >>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ >>>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ >>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ >>>> + >>>> +} >>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>>> new file mode 100644 >>>> index 00000000000..97eb65ba0a9 >>>> --- /dev/null >>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>>> @@ -0,0 +1,39 @@ >>>> +/* Test -Wstrict-flex-arrays. */ >>>> +/* { dg-do compile } */ >>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3" } */ >>>> + >>>> +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) >>>> +{ >>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ >>>> + trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */ >>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */ >>>> + >>>> +} >>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>>> new file mode 100644 >>>> index 00000000000..110fdc72778 >>>> --- /dev/null >>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>>> @@ -0,0 +1,39 @@ >>>> +/* Test -Wstrict-flex-arrays. */ >>>> +/* { dg-do compile } */ >>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1" } */ >>>> + >>>> +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) >>>> +{ >>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>>> + trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>>> + >>>> +} >>>> diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc >>>> index 3846dc1d849..e6c6c5a301d 100644 >>>> --- a/gcc/tree-vrp.cc >>>> +++ b/gcc/tree-vrp.cc >>>> @@ -1087,7 +1087,7 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p, >>>> if (dump_file && (dump_flags & TDF_DETAILS)) >>>> ranger->dump (dump_file); >>>> >>>> - if (warn_array_bounds && warn_array_bounds_p) >>>> + if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p) >>>> { >>>> // Set all edges as executable, except those ranger says aren't. >>>> int non_exec_flag = ranger->non_executable_edge_flag; >>>> -- >>>> 2.31.1 >>>> >>> >>> >> >> -- >> Richard Biener <rguenther@suse.de> >> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, >> Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; >> HRB 36809 (AG Nuernberg)
Hi, Richard, I guess that we now agreed on the following: “ the information that we ran into a trailing array but didn't consider it a flex array because of -fstrict-flex-arrays is always a useful information” The only thing we didn’t decide is: A. Amend such new information to -Warray-bounds when -fstrict-flex-arrays=N (N>0) specified. OR B. Issue such new information with a new warning option -Wstrict-flex-arrays when -fstrict-flex-arrays=N (N>0) specified. My current patch implemented B. If you think A is better, I will change the patch as A. Let me know your opinion. thanks. Qing > On Dec 14, 2022, at 4:03 AM, Richard Biener <rguenther@suse.de> wrote: > > On Tue, 13 Dec 2022, Qing Zhao wrote: > >> Richard, >> >> Do you have any decision on this one? >> Do we need this warning option For GCC? > > Looking at the testcases it seems that the diagnostic amends > -Warray-bounds diagnostics for trailing but not flexible arrays? > Wouldn't it be better to generally diagnose this, so have > -Warray-bounds, with -fstrict-flex-arrays, for > > struct X { int a[1]; }; > int foo (struct X *p) > { > return p->a[1]; > } > > emit > > warning: array subscript 1 is above array bounds ... > note: the trailing array is only a flexible array member with > -fno-strict-flex-arrays > > ? Having -Wstrict-flex-arrays=N and N not agree with the > -fstrict-flex-arrays level sounds hardly useful to me but the > information that we ran into a trailing array but didn't consider > it a flex array because of -fstrict-flex-arrays is always a > useful information? > > But maybe I misunderstood this new diagnostic? > > Thanks, > Richard. > > >> thanks. >> >> Qing >> >>> On Dec 6, 2022, at 11:18 AM, Qing Zhao <qing.zhao@oracle.com> wrote: >>> >>> '-Wstrict-flex-arrays' >>> Warn about inproper usages of flexible array members according to >>> the LEVEL of the 'strict_flex_array (LEVEL)' attribute attached to >>> the trailing array field of a structure if it's available, >>> otherwise according to the LEVEL of the option >>> '-fstrict-flex-arrays=LEVEL'. >>> >>> This option is effective only when LEVEL is bigger than 0. >>> Otherwise, it will be ignored with a warning. >>> >>> when LEVEL=1, warnings will be issued for a trailing array >>> reference of a structure that have 2 or more elements if the >>> trailing array is referenced as a flexible array member. >>> >>> when LEVEL=2, in addition to LEVEL=1, additional warnings will be >>> issued for a trailing one-element array reference of a structure if >>> the array is referenced as a flexible array member. >>> >>> when LEVEL=3, in addition to LEVEL=2, additional warnings will be >>> issued for a trailing zero-length array reference of a structure if >>> the array is referenced as a flexible array member. >>> >>> gcc/ChangeLog: >>> >>> * doc/invoke.texi: Document -Wstrict-flex-arrays option. >>> * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Add two more >>> arguments. >>> (array_bounds_checker::check_array_ref): Issue warnings for >>> -Wstrict-flex-arrays. >>> * opts.cc (finish_options): Issue warning for unsupported combination >>> of -Wstrict_flex_arrays and -fstrict-flex-array. >>> * tree-vrp.cc (execute_ranger_vrp): Enable the pass when >>> warn_strict_flex_array is true. >>> >>> gcc/c-family/ChangeLog: >>> >>> * c.opt (Wstrict-flex-arrays): New option. >>> >>> gcc/testsuite/ChangeLog: >>> >>> * gcc.dg/Warray-bounds-flex-arrays-1.c: Update testing case with >>> -Wstrict-flex-arrays. >>> * gcc.dg/Warray-bounds-flex-arrays-2.c: Likewise. >>> * gcc.dg/Warray-bounds-flex-arrays-3.c: Likewise. >>> * gcc.dg/Warray-bounds-flex-arrays-4.c: Likewise. >>> * gcc.dg/Warray-bounds-flex-arrays-5.c: Likewise. >>> * gcc.dg/Warray-bounds-flex-arrays-6.c: Likewise. >>> * c-c++-common/Wstrict-flex-arrays.c: New test. >>> * gcc.dg/Wstrict-flex-arrays-2.c: New test. >>> * gcc.dg/Wstrict-flex-arrays-3.c: New test. >>> * gcc.dg/Wstrict-flex-arrays.c: New test. >>> --- >>> gcc/c-family/c.opt | 5 + >>> gcc/doc/invoke.texi | 27 ++++- >>> gcc/gimple-array-bounds.cc | 103 ++++++++++++++---- >>> gcc/opts.cc | 8 ++ >>> .../c-c++-common/Wstrict-flex-arrays.c | 9 ++ >>> .../gcc.dg/Warray-bounds-flex-arrays-1.c | 5 +- >>> .../gcc.dg/Warray-bounds-flex-arrays-2.c | 6 +- >>> .../gcc.dg/Warray-bounds-flex-arrays-3.c | 7 +- >>> .../gcc.dg/Warray-bounds-flex-arrays-4.c | 5 +- >>> .../gcc.dg/Warray-bounds-flex-arrays-5.c | 6 +- >>> .../gcc.dg/Warray-bounds-flex-arrays-6.c | 7 +- >>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c | 39 +++++++ >>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c | 39 +++++++ >>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c | 39 +++++++ >>> gcc/tree-vrp.cc | 2 +- >>> 15 files changed, 273 insertions(+), 34 deletions(-) >>> create mode 100644 gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>> >>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt >>> index 0d0ad0a6374..33edeefd285 100644 >>> --- a/gcc/c-family/c.opt >>> +++ b/gcc/c-family/c.opt >>> @@ -976,6 +976,11 @@ Wstringop-truncation >>> C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ LTO ObjC++, Wall) >>> Warn about truncation in string manipulation functions like strncat and strncpy. >>> >>> +Wstrict-flex-arrays >>> +C C++ Var(warn_strict_flex_arrays) Warning >>> +Warn about inproper usages of flexible array members >>> +according to the level of -fstrict-flex-arrays. >>> + >>> Wsuggest-attribute=format >>> C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning >>> Warn about functions which might be candidates for format attributes. >>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi >>> index 726392409b6..4402b0427ef 100644 >>> --- a/gcc/doc/invoke.texi >>> +++ b/gcc/doc/invoke.texi >>> @@ -398,7 +398,7 @@ Objective-C and Objective-C++ Dialects}. >>> -Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol >>> -Wstring-compare @gol >>> -Wno-stringop-overflow -Wno-stringop-overread @gol >>> --Wno-stringop-truncation @gol >>> +-Wno-stringop-truncation -Wstrict-flex-arrays @gol >>> -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol >>> -Wswitch -Wno-switch-bool -Wswitch-default -Wswitch-enum @gol >>> -Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand @gol >>> @@ -7835,6 +7835,31 @@ however, are not suitable arguments to functions that expect >>> such arrays GCC issues warnings unless it can prove that the use is >>> safe. @xref{Common Variable Attributes}. >>> >>> +@item -Wstrict-flex-arrays >>> +@opindex Wstrict-flex-arrays >>> +@opindex Wno-strict-flex-arrays >>> +Warn about inproper usages of flexible array members >>> +according to the @var{level} of the @code{strict_flex_array (@var{level})} >>> +attribute attached to the trailing array field of a structure if it's >>> +available, otherwise according to the @var{level} of the option >>> +@option{-fstrict-flex-arrays=@var{level}}. >>> + >>> +This option is effective only when @var{level} is bigger than 0. Otherwise, >>> +it will be ignored with a warning. >>> + >>> +when @var{level}=1, warnings will be issued for a trailing array reference >>> +of a structure that have 2 or more elements if the trailing array is referenced >>> +as a flexible array member. >>> + >>> +when @var{level}=2, in addition to @var{level}=1, additional warnings will be >>> +issued for a trailing one-element array reference of a structure >>> +if the array is referenced as a flexible array member. >>> + >>> +when @var{level}=3, in addition to @var{level}=2, additional warnings will be >>> +issued for a trailing zero-length array reference of a structure >>> +if the array is referenced as a flexible array member. >>> + >>> + >>> @item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]} >>> @opindex Wsuggest-attribute= >>> @opindex Wno-suggest-attribute= >>> diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc >>> index db3459af325..825f11331b5 100644 >>> --- a/gcc/gimple-array-bounds.cc >>> +++ b/gcc/gimple-array-bounds.cc >>> @@ -252,25 +252,34 @@ get_up_bounds_for_array_ref (tree ref, tree *decl, >>> >>> /* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND >>> and UP_BOUND_P1, check whether the array reference REF is out of bound. >>> - Issue warnings if out of bound, return TRUE if warnings are issued. */ >>> + When out of bounds, set OUT_OF_BOUND to true. >>> + Issue warnings if FOR_ARRAY_BOUND is true. >>> + return TRUE if warnings are issued. */ >>> + >>> >>> static bool >>> check_out_of_bounds_and_warn (location_t location, tree ref, >>> tree low_sub_org, tree low_sub, tree up_sub, >>> tree up_bound, tree up_bound_p1, >>> const value_range *vr, >>> - bool ignore_off_by_one) >>> + bool ignore_off_by_one, bool for_array_bound, >>> + bool *out_of_bound) >>> { >>> tree low_bound = array_ref_low_bound (ref); >>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); >>> >>> bool warned = false; >>> + *out_of_bound = false; >>> >>> /* Empty array. */ >>> if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1)) >>> - warned = warning_at (location, OPT_Warray_bounds_, >>> - "array subscript %E is outside array bounds of %qT", >>> - low_sub_org, artype); >>> + { >>> + *out_of_bound = true; >>> + if (for_array_bound) >>> + warned = warning_at (location, OPT_Warray_bounds_, >>> + "array subscript %E is outside array" >>> + " bounds of %qT", low_sub_org, artype); >>> + } >>> >>> if (warned) >>> ; /* Do nothing. */ >>> @@ -283,24 +292,33 @@ check_out_of_bounds_and_warn (location_t location, tree ref, >>> : tree_int_cst_le (up_bound, up_sub)) >>> && TREE_CODE (low_sub) == INTEGER_CST >>> && tree_int_cst_le (low_sub, low_bound)) >>> - warned = warning_at (location, OPT_Warray_bounds_, >>> - "array subscript [%E, %E] is outside " >>> - "array bounds of %qT", >>> - low_sub, up_sub, artype); >>> + { >>> + *out_of_bound = true; >>> + warned = warning_at (location, OPT_Warray_bounds_, >>> + "array subscript [%E, %E] is outside " >>> + "array bounds of %qT", >>> + low_sub, up_sub, artype); >>> + } >>> } >>> else if (up_bound >>> && TREE_CODE (up_sub) == INTEGER_CST >>> && (ignore_off_by_one >>> ? !tree_int_cst_le (up_sub, up_bound_p1) >>> : !tree_int_cst_le (up_sub, up_bound))) >>> - warned = warning_at (location, OPT_Warray_bounds_, >>> - "array subscript %E is above array bounds of %qT", >>> - up_sub, artype); >>> + { >>> + *out_of_bound = true; >>> + warned = warning_at (location, OPT_Warray_bounds_, >>> + "array subscript %E is above array bounds of %qT", >>> + up_sub, artype); >>> + } >>> else if (TREE_CODE (low_sub) == INTEGER_CST >>> && tree_int_cst_lt (low_sub, low_bound)) >>> - warned = warning_at (location, OPT_Warray_bounds_, >>> - "array subscript %E is below array bounds of %qT", >>> - low_sub, artype); >>> + { >>> + *out_of_bound = true; >>> + warned = warning_at (location, OPT_Warray_bounds_, >>> + "array subscript %E is below array bounds of %qT", >>> + low_sub, artype); >>> + } >>> return warned; >>> } >>> >>> @@ -333,14 +351,21 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>> >>> tree arg = TREE_OPERAND (ref, 0); >>> const bool compref = TREE_CODE (arg) == COMPONENT_REF; >>> + unsigned int strict_flex_array_level = flag_strict_flex_arrays; >>> >>> if (compref) >>> - /* Try to determine special array member type for this COMPONENT_REF. */ >>> - sam = component_ref_sam_type (arg); >>> + { >>> + /* Try to determine special array member type for this COMPONENT_REF. */ >>> + sam = component_ref_sam_type (arg); >>> + /* Get the level of strict_flex_array for this array field. */ >>> + tree afield_decl = TREE_OPERAND (arg, 1); >>> + strict_flex_array_level = strict_flex_array_level_of (afield_decl); >>> + } >>> >>> get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); >>> >>> bool warned = false; >>> + bool out_of_bound = false; >>> >>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); >>> tree low_sub_org = TREE_OPERAND (ref, 1); >>> @@ -361,7 +386,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>> warned = check_out_of_bounds_and_warn (location, ref, >>> low_sub_org, low_sub, up_sub, >>> up_bound, up_bound_p1, vr, >>> - ignore_off_by_one); >>> + ignore_off_by_one, warn_array_bounds, >>> + &out_of_bound); >>> >>> >>> if (!warned && sam == special_array_member::int_0) >>> @@ -373,19 +399,56 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>> "of an interior zero-length array %qT")), >>> low_sub, artype); >>> >>> - if (warned) >>> + if (warned || out_of_bound) >>> { >>> - if (dump_file && (dump_flags & TDF_DETAILS)) >>> + if (warned && dump_file && (dump_flags & TDF_DETAILS)) >>> { >>> fprintf (dump_file, "Array bound warning for "); >>> dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); >>> fprintf (dump_file, "\n"); >>> } >>> >>> + /* issue warnings for -Wstrict-flex-arrays according to the level of >>> + flag_strict_flex_arrays. */ >>> + if (out_of_bound && warn_strict_flex_arrays) >>> + switch (strict_flex_array_level) >>> + { >>> + case 3: >>> + /* Issue additional warnings for trailing arrays [0]. */ >>> + if (sam == special_array_member::trail_0) >>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>> + "trailing array %qT should not be used as " >>> + "a flexible array member for level 3", >>> + artype); >>> + /* FALLTHROUGH. */ >>> + case 2: >>> + /* Issue additional warnings for trailing arrays [1]. */ >>> + if (sam == special_array_member::trail_1) >>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>> + "trailing array %qT should not be used as " >>> + "a flexible array member for level 2 and " >>> + "above", artype); >>> + /* FALLTHROUGH. */ >>> + case 1: >>> + /* Issue warnings for trailing arrays [n]. */ >>> + if (sam == special_array_member::trail_n) >>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>> + "trailing array %qT should not be used as " >>> + "a flexible array member for level 1 and " >>> + "above", artype); >>> + break; >>> + case 0: >>> + /* Do nothing. */ >>> + break; >>> + default: >>> + gcc_unreachable (); >>> + } >>> + >>> /* Avoid more warnings when checking more significant subscripts >>> of the same expression. */ >>> ref = TREE_OPERAND (ref, 0); >>> suppress_warning (ref, OPT_Warray_bounds_); >>> + suppress_warning (ref, OPT_Wstrict_flex_arrays); >>> >>> if (decl) >>> ref = decl; >>> diff --git a/gcc/opts.cc b/gcc/opts.cc >>> index 73fc97756e4..8db53ad6c77 100644 >>> --- a/gcc/opts.cc >>> +++ b/gcc/opts.cc >>> @@ -1411,6 +1411,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, >>> opts->x_profile_flag = 0; >>> } >>> >>> + if (opts->x_warn_strict_flex_arrays) >>> + if (opts->x_flag_strict_flex_arrays == 0) >>> + { >>> + opts->x_warn_strict_flex_arrays = 0; >>> + warning_at (UNKNOWN_LOCATION, 0, >>> + "%<-Wstrict-flex-arrays%> is ignored when" >>> + " %<-fstrict-flex-arrays%> does not present"); >>> + } >>> >>> diagnose_options (opts, opts_set, loc); >>> } >>> diff --git a/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>> new file mode 100644 >>> index 00000000000..72b4b7c6406 >>> --- /dev/null >>> +++ b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>> @@ -0,0 +1,9 @@ >>> +/* Test the usage of option -Wstrict-flex-arrays. */ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays" } */ >>> + >>> +int main(int argc, char *argv[]) >>> +{ >>> + return 0; >>> +} >>> +/* { dg-warning "is ignored when \'-fstrict-flex-arrays\' does not present" "" { target *-*-* } 0 } */ >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>> index d36ba4d86cb..65c9fec43af 100644 >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>> @@ -1,6 +1,6 @@ >>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>> /* { dg-do compile} */ >>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds" } */ >>> >>> struct trailing_array_1 { >>> int a; >>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( >>> struct trailing_array_4 *trailing_flex) >>> { >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ >>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>> index f63206e1948..2b5a895c598 100644 >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>> @@ -1,6 +1,6 @@ >>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>> /* { dg-do compile } */ >>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds" } */ >>> >>> struct trailing_array_1 { >>> int a; >>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( >>> struct trailing_array_4 *trailing_flex) >>> { >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>> trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ >>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>> >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>> index e3273714e8b..25b903f2615 100644 >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>> @@ -1,6 +1,6 @@ >>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>> /* { dg-do compile } */ >>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds" } */ >>> >>> struct trailing_array_1 { >>> int a; >>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( >>> struct trailing_array_4 *trailing_flex) >>> { >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ >>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */ >>> >>> } >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>> index cabaea77dc2..5fc500a19ca 100644 >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>> @@ -1,6 +1,6 @@ >>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>> /* { dg-do compile } */ >>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds=2" } */ >>> >>> struct trailing_array_1 { >>> int a; >>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( >>> struct trailing_array_4 *trailing_flex) >>> { >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ >>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>> index 8b7db6e4f39..30bb4ca8832 100644 >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>> @@ -1,6 +1,6 @@ >>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>> /* { dg-do compile } */ >>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds=2" } */ >>> >>> struct trailing_array_1 { >>> int a; >>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( >>> struct trailing_array_4 *trailing_flex) >>> { >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>> >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>> index 035bf481396..e847a44516e 100644 >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>> @@ -1,6 +1,6 @@ >>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>> /* { dg-do compile } */ >>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds=2" } */ >>> >>> struct trailing_array_1 { >>> int a; >>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( >>> struct trailing_array_4 *trailing_flex) >>> { >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ >>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>> >>> } >>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>> new file mode 100644 >>> index 00000000000..2e241f96208 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>> @@ -0,0 +1,39 @@ >>> +/* Test -Wstrict-flex-arrays. */ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2" } */ >>> + >>> +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) >>> +{ >>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ >>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ >>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ >>> + >>> +} >>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>> new file mode 100644 >>> index 00000000000..97eb65ba0a9 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>> @@ -0,0 +1,39 @@ >>> +/* Test -Wstrict-flex-arrays. */ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3" } */ >>> + >>> +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) >>> +{ >>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ >>> + trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */ >>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */ >>> + >>> +} >>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>> new file mode 100644 >>> index 00000000000..110fdc72778 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>> @@ -0,0 +1,39 @@ >>> +/* Test -Wstrict-flex-arrays. */ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1" } */ >>> + >>> +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) >>> +{ >>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>> + trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>> + >>> +} >>> diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc >>> index 3846dc1d849..e6c6c5a301d 100644 >>> --- a/gcc/tree-vrp.cc >>> +++ b/gcc/tree-vrp.cc >>> @@ -1087,7 +1087,7 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p, >>> if (dump_file && (dump_flags & TDF_DETAILS)) >>> ranger->dump (dump_file); >>> >>> - if (warn_array_bounds && warn_array_bounds_p) >>> + if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p) >>> { >>> // Set all edges as executable, except those ranger says aren't. >>> int non_exec_flag = ranger->non_executable_edge_flag; >>> -- >>> 2.31.1 >>> >> >> > > -- > Richard Biener <rguenther@suse.de> > SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, > Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; > HRB 36809 (AG Nuernberg)
On Wed, 14 Dec 2022, Qing Zhao wrote: > Hi, Richard, > > I guess that we now agreed on the following: > > “ the information that we ran into a trailing array but didn't consider > it a flex array because of -fstrict-flex-arrays is always a useful information” > > The only thing we didn’t decide is: > > A. Amend such new information to -Warray-bounds when -fstrict-flex-arrays=N (N>0) specified. > > OR > > B. Issue such new information with a new warning option -Wstrict-flex-arrays when -fstrict-flex-arrays=N (N>0) specified. > > My current patch implemented B. Plus it implements it to specify a different flex-array variant for the extra diagnostic. > If you think A is better, I will change the patch as A. I would tend to A since, as I said, it's useful information that shouldn't be hidden and not adding an option removes odd combination possibilities such as -Wno-array-bounds -Wstrict-flex-arrays. In particular I find, say, -fstrict-flex-arrays=2 -Wstrict-flex-arrays=1 hardly useful. But I'm interested in other opinions. Thanks, Richard. > Let me know your opinion. > > thanks. > > Qing > > > > On Dec 14, 2022, at 4:03 AM, Richard Biener <rguenther@suse.de> wrote: > > > > On Tue, 13 Dec 2022, Qing Zhao wrote: > > > >> Richard, > >> > >> Do you have any decision on this one? > >> Do we need this warning option For GCC? > > > > Looking at the testcases it seems that the diagnostic amends > > -Warray-bounds diagnostics for trailing but not flexible arrays? > > Wouldn't it be better to generally diagnose this, so have > > -Warray-bounds, with -fstrict-flex-arrays, for > > > > struct X { int a[1]; }; > > int foo (struct X *p) > > { > > return p->a[1]; > > } > > > > emit > > > > warning: array subscript 1 is above array bounds ... > > note: the trailing array is only a flexible array member with > > -fno-strict-flex-arrays > > > > ? Having -Wstrict-flex-arrays=N and N not agree with the > > -fstrict-flex-arrays level sounds hardly useful to me but the > > information that we ran into a trailing array but didn't consider > > it a flex array because of -fstrict-flex-arrays is always a > > useful information? > > > > But maybe I misunderstood this new diagnostic? > > > > Thanks, > > Richard. > > > > > >> thanks. > >> > >> Qing > >> > >>> On Dec 6, 2022, at 11:18 AM, Qing Zhao <qing.zhao@oracle.com> wrote: > >>> > >>> '-Wstrict-flex-arrays' > >>> Warn about inproper usages of flexible array members according to > >>> the LEVEL of the 'strict_flex_array (LEVEL)' attribute attached to > >>> the trailing array field of a structure if it's available, > >>> otherwise according to the LEVEL of the option > >>> '-fstrict-flex-arrays=LEVEL'. > >>> > >>> This option is effective only when LEVEL is bigger than 0. > >>> Otherwise, it will be ignored with a warning. > >>> > >>> when LEVEL=1, warnings will be issued for a trailing array > >>> reference of a structure that have 2 or more elements if the > >>> trailing array is referenced as a flexible array member. > >>> > >>> when LEVEL=2, in addition to LEVEL=1, additional warnings will be > >>> issued for a trailing one-element array reference of a structure if > >>> the array is referenced as a flexible array member. > >>> > >>> when LEVEL=3, in addition to LEVEL=2, additional warnings will be > >>> issued for a trailing zero-length array reference of a structure if > >>> the array is referenced as a flexible array member. > >>> > >>> gcc/ChangeLog: > >>> > >>> * doc/invoke.texi: Document -Wstrict-flex-arrays option. > >>> * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Add two more > >>> arguments. > >>> (array_bounds_checker::check_array_ref): Issue warnings for > >>> -Wstrict-flex-arrays. > >>> * opts.cc (finish_options): Issue warning for unsupported combination > >>> of -Wstrict_flex_arrays and -fstrict-flex-array. > >>> * tree-vrp.cc (execute_ranger_vrp): Enable the pass when > >>> warn_strict_flex_array is true. > >>> > >>> gcc/c-family/ChangeLog: > >>> > >>> * c.opt (Wstrict-flex-arrays): New option. > >>> > >>> gcc/testsuite/ChangeLog: > >>> > >>> * gcc.dg/Warray-bounds-flex-arrays-1.c: Update testing case with > >>> -Wstrict-flex-arrays. > >>> * gcc.dg/Warray-bounds-flex-arrays-2.c: Likewise. > >>> * gcc.dg/Warray-bounds-flex-arrays-3.c: Likewise. > >>> * gcc.dg/Warray-bounds-flex-arrays-4.c: Likewise. > >>> * gcc.dg/Warray-bounds-flex-arrays-5.c: Likewise. > >>> * gcc.dg/Warray-bounds-flex-arrays-6.c: Likewise. > >>> * c-c++-common/Wstrict-flex-arrays.c: New test. > >>> * gcc.dg/Wstrict-flex-arrays-2.c: New test. > >>> * gcc.dg/Wstrict-flex-arrays-3.c: New test. > >>> * gcc.dg/Wstrict-flex-arrays.c: New test. > >>> --- > >>> gcc/c-family/c.opt | 5 + > >>> gcc/doc/invoke.texi | 27 ++++- > >>> gcc/gimple-array-bounds.cc | 103 ++++++++++++++---- > >>> gcc/opts.cc | 8 ++ > >>> .../c-c++-common/Wstrict-flex-arrays.c | 9 ++ > >>> .../gcc.dg/Warray-bounds-flex-arrays-1.c | 5 +- > >>> .../gcc.dg/Warray-bounds-flex-arrays-2.c | 6 +- > >>> .../gcc.dg/Warray-bounds-flex-arrays-3.c | 7 +- > >>> .../gcc.dg/Warray-bounds-flex-arrays-4.c | 5 +- > >>> .../gcc.dg/Warray-bounds-flex-arrays-5.c | 6 +- > >>> .../gcc.dg/Warray-bounds-flex-arrays-6.c | 7 +- > >>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c | 39 +++++++ > >>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c | 39 +++++++ > >>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c | 39 +++++++ > >>> gcc/tree-vrp.cc | 2 +- > >>> 15 files changed, 273 insertions(+), 34 deletions(-) > >>> create mode 100644 gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c > >>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > >>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > >>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > >>> > >>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt > >>> index 0d0ad0a6374..33edeefd285 100644 > >>> --- a/gcc/c-family/c.opt > >>> +++ b/gcc/c-family/c.opt > >>> @@ -976,6 +976,11 @@ Wstringop-truncation > >>> C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ LTO ObjC++, Wall) > >>> Warn about truncation in string manipulation functions like strncat and strncpy. > >>> > >>> +Wstrict-flex-arrays > >>> +C C++ Var(warn_strict_flex_arrays) Warning > >>> +Warn about inproper usages of flexible array members > >>> +according to the level of -fstrict-flex-arrays. > >>> + > >>> Wsuggest-attribute=format > >>> C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning > >>> Warn about functions which might be candidates for format attributes. > >>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > >>> index 726392409b6..4402b0427ef 100644 > >>> --- a/gcc/doc/invoke.texi > >>> +++ b/gcc/doc/invoke.texi > >>> @@ -398,7 +398,7 @@ Objective-C and Objective-C++ Dialects}. > >>> -Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol > >>> -Wstring-compare @gol > >>> -Wno-stringop-overflow -Wno-stringop-overread @gol > >>> --Wno-stringop-truncation @gol > >>> +-Wno-stringop-truncation -Wstrict-flex-arrays @gol > >>> -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol > >>> -Wswitch -Wno-switch-bool -Wswitch-default -Wswitch-enum @gol > >>> -Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand @gol > >>> @@ -7835,6 +7835,31 @@ however, are not suitable arguments to functions that expect > >>> such arrays GCC issues warnings unless it can prove that the use is > >>> safe. @xref{Common Variable Attributes}. > >>> > >>> +@item -Wstrict-flex-arrays > >>> +@opindex Wstrict-flex-arrays > >>> +@opindex Wno-strict-flex-arrays > >>> +Warn about inproper usages of flexible array members > >>> +according to the @var{level} of the @code{strict_flex_array (@var{level})} > >>> +attribute attached to the trailing array field of a structure if it's > >>> +available, otherwise according to the @var{level} of the option > >>> +@option{-fstrict-flex-arrays=@var{level}}. > >>> + > >>> +This option is effective only when @var{level} is bigger than 0. Otherwise, > >>> +it will be ignored with a warning. > >>> + > >>> +when @var{level}=1, warnings will be issued for a trailing array reference > >>> +of a structure that have 2 or more elements if the trailing array is referenced > >>> +as a flexible array member. > >>> + > >>> +when @var{level}=2, in addition to @var{level}=1, additional warnings will be > >>> +issued for a trailing one-element array reference of a structure > >>> +if the array is referenced as a flexible array member. > >>> + > >>> +when @var{level}=3, in addition to @var{level}=2, additional warnings will be > >>> +issued for a trailing zero-length array reference of a structure > >>> +if the array is referenced as a flexible array member. > >>> + > >>> + > >>> @item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]} > >>> @opindex Wsuggest-attribute= > >>> @opindex Wno-suggest-attribute= > >>> diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc > >>> index db3459af325..825f11331b5 100644 > >>> --- a/gcc/gimple-array-bounds.cc > >>> +++ b/gcc/gimple-array-bounds.cc > >>> @@ -252,25 +252,34 @@ get_up_bounds_for_array_ref (tree ref, tree *decl, > >>> > >>> /* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND > >>> and UP_BOUND_P1, check whether the array reference REF is out of bound. > >>> - Issue warnings if out of bound, return TRUE if warnings are issued. */ > >>> + When out of bounds, set OUT_OF_BOUND to true. > >>> + Issue warnings if FOR_ARRAY_BOUND is true. > >>> + return TRUE if warnings are issued. */ > >>> + > >>> > >>> static bool > >>> check_out_of_bounds_and_warn (location_t location, tree ref, > >>> tree low_sub_org, tree low_sub, tree up_sub, > >>> tree up_bound, tree up_bound_p1, > >>> const value_range *vr, > >>> - bool ignore_off_by_one) > >>> + bool ignore_off_by_one, bool for_array_bound, > >>> + bool *out_of_bound) > >>> { > >>> tree low_bound = array_ref_low_bound (ref); > >>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); > >>> > >>> bool warned = false; > >>> + *out_of_bound = false; > >>> > >>> /* Empty array. */ > >>> if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1)) > >>> - warned = warning_at (location, OPT_Warray_bounds_, > >>> - "array subscript %E is outside array bounds of %qT", > >>> - low_sub_org, artype); > >>> + { > >>> + *out_of_bound = true; > >>> + if (for_array_bound) > >>> + warned = warning_at (location, OPT_Warray_bounds_, > >>> + "array subscript %E is outside array" > >>> + " bounds of %qT", low_sub_org, artype); > >>> + } > >>> > >>> if (warned) > >>> ; /* Do nothing. */ > >>> @@ -283,24 +292,33 @@ check_out_of_bounds_and_warn (location_t location, tree ref, > >>> : tree_int_cst_le (up_bound, up_sub)) > >>> && TREE_CODE (low_sub) == INTEGER_CST > >>> && tree_int_cst_le (low_sub, low_bound)) > >>> - warned = warning_at (location, OPT_Warray_bounds_, > >>> - "array subscript [%E, %E] is outside " > >>> - "array bounds of %qT", > >>> - low_sub, up_sub, artype); > >>> + { > >>> + *out_of_bound = true; > >>> + warned = warning_at (location, OPT_Warray_bounds_, > >>> + "array subscript [%E, %E] is outside " > >>> + "array bounds of %qT", > >>> + low_sub, up_sub, artype); > >>> + } > >>> } > >>> else if (up_bound > >>> && TREE_CODE (up_sub) == INTEGER_CST > >>> && (ignore_off_by_one > >>> ? !tree_int_cst_le (up_sub, up_bound_p1) > >>> : !tree_int_cst_le (up_sub, up_bound))) > >>> - warned = warning_at (location, OPT_Warray_bounds_, > >>> - "array subscript %E is above array bounds of %qT", > >>> - up_sub, artype); > >>> + { > >>> + *out_of_bound = true; > >>> + warned = warning_at (location, OPT_Warray_bounds_, > >>> + "array subscript %E is above array bounds of %qT", > >>> + up_sub, artype); > >>> + } > >>> else if (TREE_CODE (low_sub) == INTEGER_CST > >>> && tree_int_cst_lt (low_sub, low_bound)) > >>> - warned = warning_at (location, OPT_Warray_bounds_, > >>> - "array subscript %E is below array bounds of %qT", > >>> - low_sub, artype); > >>> + { > >>> + *out_of_bound = true; > >>> + warned = warning_at (location, OPT_Warray_bounds_, > >>> + "array subscript %E is below array bounds of %qT", > >>> + low_sub, artype); > >>> + } > >>> return warned; > >>> } > >>> > >>> @@ -333,14 +351,21 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > >>> > >>> tree arg = TREE_OPERAND (ref, 0); > >>> const bool compref = TREE_CODE (arg) == COMPONENT_REF; > >>> + unsigned int strict_flex_array_level = flag_strict_flex_arrays; > >>> > >>> if (compref) > >>> - /* Try to determine special array member type for this COMPONENT_REF. */ > >>> - sam = component_ref_sam_type (arg); > >>> + { > >>> + /* Try to determine special array member type for this COMPONENT_REF. */ > >>> + sam = component_ref_sam_type (arg); > >>> + /* Get the level of strict_flex_array for this array field. */ > >>> + tree afield_decl = TREE_OPERAND (arg, 1); > >>> + strict_flex_array_level = strict_flex_array_level_of (afield_decl); > >>> + } > >>> > >>> get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); > >>> > >>> bool warned = false; > >>> + bool out_of_bound = false; > >>> > >>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); > >>> tree low_sub_org = TREE_OPERAND (ref, 1); > >>> @@ -361,7 +386,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > >>> warned = check_out_of_bounds_and_warn (location, ref, > >>> low_sub_org, low_sub, up_sub, > >>> up_bound, up_bound_p1, vr, > >>> - ignore_off_by_one); > >>> + ignore_off_by_one, warn_array_bounds, > >>> + &out_of_bound); > >>> > >>> > >>> if (!warned && sam == special_array_member::int_0) > >>> @@ -373,19 +399,56 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > >>> "of an interior zero-length array %qT")), > >>> low_sub, artype); > >>> > >>> - if (warned) > >>> + if (warned || out_of_bound) > >>> { > >>> - if (dump_file && (dump_flags & TDF_DETAILS)) > >>> + if (warned && dump_file && (dump_flags & TDF_DETAILS)) > >>> { > >>> fprintf (dump_file, "Array bound warning for "); > >>> dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); > >>> fprintf (dump_file, "\n"); > >>> } > >>> > >>> + /* issue warnings for -Wstrict-flex-arrays according to the level of > >>> + flag_strict_flex_arrays. */ > >>> + if (out_of_bound && warn_strict_flex_arrays) > >>> + switch (strict_flex_array_level) > >>> + { > >>> + case 3: > >>> + /* Issue additional warnings for trailing arrays [0]. */ > >>> + if (sam == special_array_member::trail_0) > >>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, > >>> + "trailing array %qT should not be used as " > >>> + "a flexible array member for level 3", > >>> + artype); > >>> + /* FALLTHROUGH. */ > >>> + case 2: > >>> + /* Issue additional warnings for trailing arrays [1]. */ > >>> + if (sam == special_array_member::trail_1) > >>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, > >>> + "trailing array %qT should not be used as " > >>> + "a flexible array member for level 2 and " > >>> + "above", artype); > >>> + /* FALLTHROUGH. */ > >>> + case 1: > >>> + /* Issue warnings for trailing arrays [n]. */ > >>> + if (sam == special_array_member::trail_n) > >>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, > >>> + "trailing array %qT should not be used as " > >>> + "a flexible array member for level 1 and " > >>> + "above", artype); > >>> + break; > >>> + case 0: > >>> + /* Do nothing. */ > >>> + break; > >>> + default: > >>> + gcc_unreachable (); > >>> + } > >>> + > >>> /* Avoid more warnings when checking more significant subscripts > >>> of the same expression. */ > >>> ref = TREE_OPERAND (ref, 0); > >>> suppress_warning (ref, OPT_Warray_bounds_); > >>> + suppress_warning (ref, OPT_Wstrict_flex_arrays); > >>> > >>> if (decl) > >>> ref = decl; > >>> diff --git a/gcc/opts.cc b/gcc/opts.cc > >>> index 73fc97756e4..8db53ad6c77 100644 > >>> --- a/gcc/opts.cc > >>> +++ b/gcc/opts.cc > >>> @@ -1411,6 +1411,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, > >>> opts->x_profile_flag = 0; > >>> } > >>> > >>> + if (opts->x_warn_strict_flex_arrays) > >>> + if (opts->x_flag_strict_flex_arrays == 0) > >>> + { > >>> + opts->x_warn_strict_flex_arrays = 0; > >>> + warning_at (UNKNOWN_LOCATION, 0, > >>> + "%<-Wstrict-flex-arrays%> is ignored when" > >>> + " %<-fstrict-flex-arrays%> does not present"); > >>> + } > >>> > >>> diagnose_options (opts, opts_set, loc); > >>> } > >>> diff --git a/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c > >>> new file mode 100644 > >>> index 00000000000..72b4b7c6406 > >>> --- /dev/null > >>> +++ b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c > >>> @@ -0,0 +1,9 @@ > >>> +/* Test the usage of option -Wstrict-flex-arrays. */ > >>> +/* { dg-do compile } */ > >>> +/* { dg-options "-O2 -Wstrict-flex-arrays" } */ > >>> + > >>> +int main(int argc, char *argv[]) > >>> +{ > >>> + return 0; > >>> +} > >>> +/* { dg-warning "is ignored when \'-fstrict-flex-arrays\' does not present" "" { target *-*-* } 0 } */ > >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > >>> index d36ba4d86cb..65c9fec43af 100644 > >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > >>> @@ -1,6 +1,6 @@ > >>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ > >>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ > >>> /* { dg-do compile} */ > >>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */ > >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds" } */ > >>> > >>> struct trailing_array_1 { > >>> int a; > >>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( > >>> struct trailing_array_4 *trailing_flex) > >>> { > >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > >>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ > >>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > >>> index f63206e1948..2b5a895c598 100644 > >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > >>> @@ -1,6 +1,6 @@ > >>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ > >>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ > >>> /* { dg-do compile } */ > >>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */ > >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds" } */ > >>> > >>> struct trailing_array_1 { > >>> int a; > >>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( > >>> struct trailing_array_4 *trailing_flex) > >>> { > >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > >>> trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ > >>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > >>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > >>> > >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > >>> index e3273714e8b..25b903f2615 100644 > >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > >>> @@ -1,6 +1,6 @@ > >>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ > >>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ > >>> /* { dg-do compile } */ > >>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */ > >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds" } */ > >>> > >>> struct trailing_array_1 { > >>> int a; > >>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( > >>> struct trailing_array_4 *trailing_flex) > >>> { > >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > >>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > >>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > >>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ > >>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ > >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */ > >>> > >>> } > >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > >>> index cabaea77dc2..5fc500a19ca 100644 > >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > >>> @@ -1,6 +1,6 @@ > >>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ > >>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ > >>> /* { dg-do compile } */ > >>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */ > >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds=2" } */ > >>> > >>> struct trailing_array_1 { > >>> int a; > >>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( > >>> struct trailing_array_4 *trailing_flex) > >>> { > >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > >>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ > >>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > >>> index 8b7db6e4f39..30bb4ca8832 100644 > >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > >>> @@ -1,6 +1,6 @@ > >>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ > >>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ > >>> /* { dg-do compile } */ > >>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */ > >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds=2" } */ > >>> > >>> struct trailing_array_1 { > >>> int a; > >>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( > >>> struct trailing_array_4 *trailing_flex) > >>> { > >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > >>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > >>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > >>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > >>> > >>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > >>> index 035bf481396..e847a44516e 100644 > >>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > >>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > >>> @@ -1,6 +1,6 @@ > >>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ > >>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ > >>> /* { dg-do compile } */ > >>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */ > >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds=2" } */ > >>> > >>> struct trailing_array_1 { > >>> int a; > >>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( > >>> struct trailing_array_4 *trailing_flex) > >>> { > >>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > >>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > >>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > >>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > >>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ > >>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ > >>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > >>> > >>> } > >>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > >>> new file mode 100644 > >>> index 00000000000..2e241f96208 > >>> --- /dev/null > >>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > >>> @@ -0,0 +1,39 @@ > >>> +/* Test -Wstrict-flex-arrays. */ > >>> +/* { dg-do compile } */ > >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2" } */ > >>> + > >>> +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) > >>> +{ > >>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > >>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ > >>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ > >>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ > >>> + > >>> +} > >>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > >>> new file mode 100644 > >>> index 00000000000..97eb65ba0a9 > >>> --- /dev/null > >>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > >>> @@ -0,0 +1,39 @@ > >>> +/* Test -Wstrict-flex-arrays. */ > >>> +/* { dg-do compile } */ > >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3" } */ > >>> + > >>> +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) > >>> +{ > >>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > >>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ > >>> + trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */ > >>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */ > >>> + > >>> +} > >>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > >>> new file mode 100644 > >>> index 00000000000..110fdc72778 > >>> --- /dev/null > >>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > >>> @@ -0,0 +1,39 @@ > >>> +/* Test -Wstrict-flex-arrays. */ > >>> +/* { dg-do compile } */ > >>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1" } */ > >>> + > >>> +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) > >>> +{ > >>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > >>> + trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > >>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > >>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > >>> + > >>> +} > >>> diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc > >>> index 3846dc1d849..e6c6c5a301d 100644 > >>> --- a/gcc/tree-vrp.cc > >>> +++ b/gcc/tree-vrp.cc > >>> @@ -1087,7 +1087,7 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p, > >>> if (dump_file && (dump_flags & TDF_DETAILS)) > >>> ranger->dump (dump_file); > >>> > >>> - if (warn_array_bounds && warn_array_bounds_p) > >>> + if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p) > >>> { > >>> // Set all edges as executable, except those ranger says aren't. > >>> int non_exec_flag = ranger->non_executable_edge_flag; > >>> -- > >>> 2.31.1 > >>> > >> > >> > > > > -- > > Richard Biener <rguenther@suse.de> > > SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, > > Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; > > HRB 36809 (AG Nuernberg) > >
> On Dec 15, 2022, at 2:47 AM, Richard Biener <rguenther@suse.de> wrote: > > On Wed, 14 Dec 2022, Qing Zhao wrote: > >> Hi, Richard, >> >> I guess that we now agreed on the following: >> >> “ the information that we ran into a trailing array but didn't consider >> it a flex array because of -fstrict-flex-arrays is always a useful information” >> >> The only thing we didn’t decide is: >> >> A. Amend such new information to -Warray-bounds when -fstrict-flex-arrays=N (N>0) specified. >> >> OR >> >> B. Issue such new information with a new warning option -Wstrict-flex-arrays when -fstrict-flex-arrays=N (N>0) specified. >> >> My current patch implemented B. > > Plus it implements it to specify a different flex-array variant for > the extra diagnostic. Could you clarify a little bit on this? (Don’t quite understand…) > >> If you think A is better, I will change the patch as A. > > I would tend to A since, as I said, it's useful information that > shouldn't be hidden and not adding an option removes odd combination > possibilities such as -Wno-array-bounds -Wstrict-flex-arrays. With current implementation, the above combination will ONLY report the misuse of trailing array as flex-array. No out-of-bounds warnings issued. > In particular I find, say, -fstrict-flex-arrays=2 -Wstrict-flex-arrays=1 > hardly useful. The above combination will NOT happen, because there is NO level argument for -Wstrict-flex-arrays. The only combination will be: -fstrict-flex-arrays=N -Wstrict-flex-arrays When N > 0, -Wstrict-flex-arrays will report any misuse of trailing arrays as flexible array per the value of N. > > But I'm interested in other opinions. Adding a separate -Wstrict-flex-arrays will provide users a choice to ONLY look at the mis-use of trailing arrays as flex-arrays. Without this new option, such information will be buried into tons of out-of-bounds messges. I think this is the major benefit to have one separate new warning -Wstrict-flex-arrays. Do we need to provide the users this choice? Thanks. Qing > > Thanks, > Richard. > >> Let me know your opinion. >> >> thanks. >> >> Qing >> >> >>> On Dec 14, 2022, at 4:03 AM, Richard Biener <rguenther@suse.de> wrote: >>> >>> On Tue, 13 Dec 2022, Qing Zhao wrote: >>> >>>> Richard, >>>> >>>> Do you have any decision on this one? >>>> Do we need this warning option For GCC? >>> >>> Looking at the testcases it seems that the diagnostic amends >>> -Warray-bounds diagnostics for trailing but not flexible arrays? >>> Wouldn't it be better to generally diagnose this, so have >>> -Warray-bounds, with -fstrict-flex-arrays, for >>> >>> struct X { int a[1]; }; >>> int foo (struct X *p) >>> { >>> return p->a[1]; >>> } >>> >>> emit >>> >>> warning: array subscript 1 is above array bounds ... >>> note: the trailing array is only a flexible array member with >>> -fno-strict-flex-arrays >>> >>> ? Having -Wstrict-flex-arrays=N and N not agree with the >>> -fstrict-flex-arrays level sounds hardly useful to me but the >>> information that we ran into a trailing array but didn't consider >>> it a flex array because of -fstrict-flex-arrays is always a >>> useful information? >>> >>> But maybe I misunderstood this new diagnostic? >>> >>> Thanks, >>> Richard. >>> >>> >>>> thanks. >>>> >>>> Qing >>>> >>>>> On Dec 6, 2022, at 11:18 AM, Qing Zhao <qing.zhao@oracle.com> wrote: >>>>> >>>>> '-Wstrict-flex-arrays' >>>>> Warn about inproper usages of flexible array members according to >>>>> the LEVEL of the 'strict_flex_array (LEVEL)' attribute attached to >>>>> the trailing array field of a structure if it's available, >>>>> otherwise according to the LEVEL of the option >>>>> '-fstrict-flex-arrays=LEVEL'. >>>>> >>>>> This option is effective only when LEVEL is bigger than 0. >>>>> Otherwise, it will be ignored with a warning. >>>>> >>>>> when LEVEL=1, warnings will be issued for a trailing array >>>>> reference of a structure that have 2 or more elements if the >>>>> trailing array is referenced as a flexible array member. >>>>> >>>>> when LEVEL=2, in addition to LEVEL=1, additional warnings will be >>>>> issued for a trailing one-element array reference of a structure if >>>>> the array is referenced as a flexible array member. >>>>> >>>>> when LEVEL=3, in addition to LEVEL=2, additional warnings will be >>>>> issued for a trailing zero-length array reference of a structure if >>>>> the array is referenced as a flexible array member. >>>>> >>>>> gcc/ChangeLog: >>>>> >>>>> * doc/invoke.texi: Document -Wstrict-flex-arrays option. >>>>> * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Add two more >>>>> arguments. >>>>> (array_bounds_checker::check_array_ref): Issue warnings for >>>>> -Wstrict-flex-arrays. >>>>> * opts.cc (finish_options): Issue warning for unsupported combination >>>>> of -Wstrict_flex_arrays and -fstrict-flex-array. >>>>> * tree-vrp.cc (execute_ranger_vrp): Enable the pass when >>>>> warn_strict_flex_array is true. >>>>> >>>>> gcc/c-family/ChangeLog: >>>>> >>>>> * c.opt (Wstrict-flex-arrays): New option. >>>>> >>>>> gcc/testsuite/ChangeLog: >>>>> >>>>> * gcc.dg/Warray-bounds-flex-arrays-1.c: Update testing case with >>>>> -Wstrict-flex-arrays. >>>>> * gcc.dg/Warray-bounds-flex-arrays-2.c: Likewise. >>>>> * gcc.dg/Warray-bounds-flex-arrays-3.c: Likewise. >>>>> * gcc.dg/Warray-bounds-flex-arrays-4.c: Likewise. >>>>> * gcc.dg/Warray-bounds-flex-arrays-5.c: Likewise. >>>>> * gcc.dg/Warray-bounds-flex-arrays-6.c: Likewise. >>>>> * c-c++-common/Wstrict-flex-arrays.c: New test. >>>>> * gcc.dg/Wstrict-flex-arrays-2.c: New test. >>>>> * gcc.dg/Wstrict-flex-arrays-3.c: New test. >>>>> * gcc.dg/Wstrict-flex-arrays.c: New test. >>>>> --- >>>>> gcc/c-family/c.opt | 5 + >>>>> gcc/doc/invoke.texi | 27 ++++- >>>>> gcc/gimple-array-bounds.cc | 103 ++++++++++++++---- >>>>> gcc/opts.cc | 8 ++ >>>>> .../c-c++-common/Wstrict-flex-arrays.c | 9 ++ >>>>> .../gcc.dg/Warray-bounds-flex-arrays-1.c | 5 +- >>>>> .../gcc.dg/Warray-bounds-flex-arrays-2.c | 6 +- >>>>> .../gcc.dg/Warray-bounds-flex-arrays-3.c | 7 +- >>>>> .../gcc.dg/Warray-bounds-flex-arrays-4.c | 5 +- >>>>> .../gcc.dg/Warray-bounds-flex-arrays-5.c | 6 +- >>>>> .../gcc.dg/Warray-bounds-flex-arrays-6.c | 7 +- >>>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c | 39 +++++++ >>>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c | 39 +++++++ >>>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c | 39 +++++++ >>>>> gcc/tree-vrp.cc | 2 +- >>>>> 15 files changed, 273 insertions(+), 34 deletions(-) >>>>> create mode 100644 gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>>>> >>>>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt >>>>> index 0d0ad0a6374..33edeefd285 100644 >>>>> --- a/gcc/c-family/c.opt >>>>> +++ b/gcc/c-family/c.opt >>>>> @@ -976,6 +976,11 @@ Wstringop-truncation >>>>> C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ LTO ObjC++, Wall) >>>>> Warn about truncation in string manipulation functions like strncat and strncpy. >>>>> >>>>> +Wstrict-flex-arrays >>>>> +C C++ Var(warn_strict_flex_arrays) Warning >>>>> +Warn about inproper usages of flexible array members >>>>> +according to the level of -fstrict-flex-arrays. >>>>> + >>>>> Wsuggest-attribute=format >>>>> C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning >>>>> Warn about functions which might be candidates for format attributes. >>>>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi >>>>> index 726392409b6..4402b0427ef 100644 >>>>> --- a/gcc/doc/invoke.texi >>>>> +++ b/gcc/doc/invoke.texi >>>>> @@ -398,7 +398,7 @@ Objective-C and Objective-C++ Dialects}. >>>>> -Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol >>>>> -Wstring-compare @gol >>>>> -Wno-stringop-overflow -Wno-stringop-overread @gol >>>>> --Wno-stringop-truncation @gol >>>>> +-Wno-stringop-truncation -Wstrict-flex-arrays @gol >>>>> -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol >>>>> -Wswitch -Wno-switch-bool -Wswitch-default -Wswitch-enum @gol >>>>> -Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand @gol >>>>> @@ -7835,6 +7835,31 @@ however, are not suitable arguments to functions that expect >>>>> such arrays GCC issues warnings unless it can prove that the use is >>>>> safe. @xref{Common Variable Attributes}. >>>>> >>>>> +@item -Wstrict-flex-arrays >>>>> +@opindex Wstrict-flex-arrays >>>>> +@opindex Wno-strict-flex-arrays >>>>> +Warn about inproper usages of flexible array members >>>>> +according to the @var{level} of the @code{strict_flex_array (@var{level})} >>>>> +attribute attached to the trailing array field of a structure if it's >>>>> +available, otherwise according to the @var{level} of the option >>>>> +@option{-fstrict-flex-arrays=@var{level}}. >>>>> + >>>>> +This option is effective only when @var{level} is bigger than 0. Otherwise, >>>>> +it will be ignored with a warning. >>>>> + >>>>> +when @var{level}=1, warnings will be issued for a trailing array reference >>>>> +of a structure that have 2 or more elements if the trailing array is referenced >>>>> +as a flexible array member. >>>>> + >>>>> +when @var{level}=2, in addition to @var{level}=1, additional warnings will be >>>>> +issued for a trailing one-element array reference of a structure >>>>> +if the array is referenced as a flexible array member. >>>>> + >>>>> +when @var{level}=3, in addition to @var{level}=2, additional warnings will be >>>>> +issued for a trailing zero-length array reference of a structure >>>>> +if the array is referenced as a flexible array member. >>>>> + >>>>> + >>>>> @item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]} >>>>> @opindex Wsuggest-attribute= >>>>> @opindex Wno-suggest-attribute= >>>>> diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc >>>>> index db3459af325..825f11331b5 100644 >>>>> --- a/gcc/gimple-array-bounds.cc >>>>> +++ b/gcc/gimple-array-bounds.cc >>>>> @@ -252,25 +252,34 @@ get_up_bounds_for_array_ref (tree ref, tree *decl, >>>>> >>>>> /* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND >>>>> and UP_BOUND_P1, check whether the array reference REF is out of bound. >>>>> - Issue warnings if out of bound, return TRUE if warnings are issued. */ >>>>> + When out of bounds, set OUT_OF_BOUND to true. >>>>> + Issue warnings if FOR_ARRAY_BOUND is true. >>>>> + return TRUE if warnings are issued. */ >>>>> + >>>>> >>>>> static bool >>>>> check_out_of_bounds_and_warn (location_t location, tree ref, >>>>> tree low_sub_org, tree low_sub, tree up_sub, >>>>> tree up_bound, tree up_bound_p1, >>>>> const value_range *vr, >>>>> - bool ignore_off_by_one) >>>>> + bool ignore_off_by_one, bool for_array_bound, >>>>> + bool *out_of_bound) >>>>> { >>>>> tree low_bound = array_ref_low_bound (ref); >>>>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); >>>>> >>>>> bool warned = false; >>>>> + *out_of_bound = false; >>>>> >>>>> /* Empty array. */ >>>>> if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1)) >>>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>>> - "array subscript %E is outside array bounds of %qT", >>>>> - low_sub_org, artype); >>>>> + { >>>>> + *out_of_bound = true; >>>>> + if (for_array_bound) >>>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>>> + "array subscript %E is outside array" >>>>> + " bounds of %qT", low_sub_org, artype); >>>>> + } >>>>> >>>>> if (warned) >>>>> ; /* Do nothing. */ >>>>> @@ -283,24 +292,33 @@ check_out_of_bounds_and_warn (location_t location, tree ref, >>>>> : tree_int_cst_le (up_bound, up_sub)) >>>>> && TREE_CODE (low_sub) == INTEGER_CST >>>>> && tree_int_cst_le (low_sub, low_bound)) >>>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>>> - "array subscript [%E, %E] is outside " >>>>> - "array bounds of %qT", >>>>> - low_sub, up_sub, artype); >>>>> + { >>>>> + *out_of_bound = true; >>>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>>> + "array subscript [%E, %E] is outside " >>>>> + "array bounds of %qT", >>>>> + low_sub, up_sub, artype); >>>>> + } >>>>> } >>>>> else if (up_bound >>>>> && TREE_CODE (up_sub) == INTEGER_CST >>>>> && (ignore_off_by_one >>>>> ? !tree_int_cst_le (up_sub, up_bound_p1) >>>>> : !tree_int_cst_le (up_sub, up_bound))) >>>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>>> - "array subscript %E is above array bounds of %qT", >>>>> - up_sub, artype); >>>>> + { >>>>> + *out_of_bound = true; >>>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>>> + "array subscript %E is above array bounds of %qT", >>>>> + up_sub, artype); >>>>> + } >>>>> else if (TREE_CODE (low_sub) == INTEGER_CST >>>>> && tree_int_cst_lt (low_sub, low_bound)) >>>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>>> - "array subscript %E is below array bounds of %qT", >>>>> - low_sub, artype); >>>>> + { >>>>> + *out_of_bound = true; >>>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>>> + "array subscript %E is below array bounds of %qT", >>>>> + low_sub, artype); >>>>> + } >>>>> return warned; >>>>> } >>>>> >>>>> @@ -333,14 +351,21 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>>>> >>>>> tree arg = TREE_OPERAND (ref, 0); >>>>> const bool compref = TREE_CODE (arg) == COMPONENT_REF; >>>>> + unsigned int strict_flex_array_level = flag_strict_flex_arrays; >>>>> >>>>> if (compref) >>>>> - /* Try to determine special array member type for this COMPONENT_REF. */ >>>>> - sam = component_ref_sam_type (arg); >>>>> + { >>>>> + /* Try to determine special array member type for this COMPONENT_REF. */ >>>>> + sam = component_ref_sam_type (arg); >>>>> + /* Get the level of strict_flex_array for this array field. */ >>>>> + tree afield_decl = TREE_OPERAND (arg, 1); >>>>> + strict_flex_array_level = strict_flex_array_level_of (afield_decl); >>>>> + } >>>>> >>>>> get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); >>>>> >>>>> bool warned = false; >>>>> + bool out_of_bound = false; >>>>> >>>>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); >>>>> tree low_sub_org = TREE_OPERAND (ref, 1); >>>>> @@ -361,7 +386,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>>>> warned = check_out_of_bounds_and_warn (location, ref, >>>>> low_sub_org, low_sub, up_sub, >>>>> up_bound, up_bound_p1, vr, >>>>> - ignore_off_by_one); >>>>> + ignore_off_by_one, warn_array_bounds, >>>>> + &out_of_bound); >>>>> >>>>> >>>>> if (!warned && sam == special_array_member::int_0) >>>>> @@ -373,19 +399,56 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>>>> "of an interior zero-length array %qT")), >>>>> low_sub, artype); >>>>> >>>>> - if (warned) >>>>> + if (warned || out_of_bound) >>>>> { >>>>> - if (dump_file && (dump_flags & TDF_DETAILS)) >>>>> + if (warned && dump_file && (dump_flags & TDF_DETAILS)) >>>>> { >>>>> fprintf (dump_file, "Array bound warning for "); >>>>> dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); >>>>> fprintf (dump_file, "\n"); >>>>> } >>>>> >>>>> + /* issue warnings for -Wstrict-flex-arrays according to the level of >>>>> + flag_strict_flex_arrays. */ >>>>> + if (out_of_bound && warn_strict_flex_arrays) >>>>> + switch (strict_flex_array_level) >>>>> + { >>>>> + case 3: >>>>> + /* Issue additional warnings for trailing arrays [0]. */ >>>>> + if (sam == special_array_member::trail_0) >>>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>>>> + "trailing array %qT should not be used as " >>>>> + "a flexible array member for level 3", >>>>> + artype); >>>>> + /* FALLTHROUGH. */ >>>>> + case 2: >>>>> + /* Issue additional warnings for trailing arrays [1]. */ >>>>> + if (sam == special_array_member::trail_1) >>>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>>>> + "trailing array %qT should not be used as " >>>>> + "a flexible array member for level 2 and " >>>>> + "above", artype); >>>>> + /* FALLTHROUGH. */ >>>>> + case 1: >>>>> + /* Issue warnings for trailing arrays [n]. */ >>>>> + if (sam == special_array_member::trail_n) >>>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>>>> + "trailing array %qT should not be used as " >>>>> + "a flexible array member for level 1 and " >>>>> + "above", artype); >>>>> + break; >>>>> + case 0: >>>>> + /* Do nothing. */ >>>>> + break; >>>>> + default: >>>>> + gcc_unreachable (); >>>>> + } >>>>> + >>>>> /* Avoid more warnings when checking more significant subscripts >>>>> of the same expression. */ >>>>> ref = TREE_OPERAND (ref, 0); >>>>> suppress_warning (ref, OPT_Warray_bounds_); >>>>> + suppress_warning (ref, OPT_Wstrict_flex_arrays); >>>>> >>>>> if (decl) >>>>> ref = decl; >>>>> diff --git a/gcc/opts.cc b/gcc/opts.cc >>>>> index 73fc97756e4..8db53ad6c77 100644 >>>>> --- a/gcc/opts.cc >>>>> +++ b/gcc/opts.cc >>>>> @@ -1411,6 +1411,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, >>>>> opts->x_profile_flag = 0; >>>>> } >>>>> >>>>> + if (opts->x_warn_strict_flex_arrays) >>>>> + if (opts->x_flag_strict_flex_arrays == 0) >>>>> + { >>>>> + opts->x_warn_strict_flex_arrays = 0; >>>>> + warning_at (UNKNOWN_LOCATION, 0, >>>>> + "%<-Wstrict-flex-arrays%> is ignored when" >>>>> + " %<-fstrict-flex-arrays%> does not present"); >>>>> + } >>>>> >>>>> diagnose_options (opts, opts_set, loc); >>>>> } >>>>> diff --git a/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>>>> new file mode 100644 >>>>> index 00000000000..72b4b7c6406 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>>>> @@ -0,0 +1,9 @@ >>>>> +/* Test the usage of option -Wstrict-flex-arrays. */ >>>>> +/* { dg-do compile } */ >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays" } */ >>>>> + >>>>> +int main(int argc, char *argv[]) >>>>> +{ >>>>> + return 0; >>>>> +} >>>>> +/* { dg-warning "is ignored when \'-fstrict-flex-arrays\' does not present" "" { target *-*-* } 0 } */ >>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>>>> index d36ba4d86cb..65c9fec43af 100644 >>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>>>> @@ -1,6 +1,6 @@ >>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>>>> /* { dg-do compile} */ >>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */ >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds" } */ >>>>> >>>>> struct trailing_array_1 { >>>>> int a; >>>>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( >>>>> struct trailing_array_4 *trailing_flex) >>>>> { >>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ >>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>>>> index f63206e1948..2b5a895c598 100644 >>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>>>> @@ -1,6 +1,6 @@ >>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>>>> /* { dg-do compile } */ >>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */ >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds" } */ >>>>> >>>>> struct trailing_array_1 { >>>>> int a; >>>>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( >>>>> struct trailing_array_4 *trailing_flex) >>>>> { >>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>> trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ >>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>> >>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>>>> index e3273714e8b..25b903f2615 100644 >>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>>>> @@ -1,6 +1,6 @@ >>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>>>> /* { dg-do compile } */ >>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */ >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds" } */ >>>>> >>>>> struct trailing_array_1 { >>>>> int a; >>>>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( >>>>> struct trailing_array_4 *trailing_flex) >>>>> { >>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ >>>>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ >>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */ >>>>> >>>>> } >>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>>>> index cabaea77dc2..5fc500a19ca 100644 >>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>>>> @@ -1,6 +1,6 @@ >>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>>>> /* { dg-do compile } */ >>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */ >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds=2" } */ >>>>> >>>>> struct trailing_array_1 { >>>>> int a; >>>>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( >>>>> struct trailing_array_4 *trailing_flex) >>>>> { >>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ >>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>>>> index 8b7db6e4f39..30bb4ca8832 100644 >>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>>>> @@ -1,6 +1,6 @@ >>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>>>> /* { dg-do compile } */ >>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */ >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds=2" } */ >>>>> >>>>> struct trailing_array_1 { >>>>> int a; >>>>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( >>>>> struct trailing_array_4 *trailing_flex) >>>>> { >>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>> >>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>>>> index 035bf481396..e847a44516e 100644 >>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>>>> @@ -1,6 +1,6 @@ >>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>>>> /* { dg-do compile } */ >>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */ >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds=2" } */ >>>>> >>>>> struct trailing_array_1 { >>>>> int a; >>>>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( >>>>> struct trailing_array_4 *trailing_flex) >>>>> { >>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ >>>>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ >>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>> >>>>> } >>>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>>>> new file mode 100644 >>>>> index 00000000000..2e241f96208 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>>>> @@ -0,0 +1,39 @@ >>>>> +/* Test -Wstrict-flex-arrays. */ >>>>> +/* { dg-do compile } */ >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2" } */ >>>>> + >>>>> +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) >>>>> +{ >>>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>>>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ >>>>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ >>>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ >>>>> + >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>>>> new file mode 100644 >>>>> index 00000000000..97eb65ba0a9 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>>>> @@ -0,0 +1,39 @@ >>>>> +/* Test -Wstrict-flex-arrays. */ >>>>> +/* { dg-do compile } */ >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3" } */ >>>>> + >>>>> +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) >>>>> +{ >>>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>>>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ >>>>> + trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */ >>>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */ >>>>> + >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>>>> new file mode 100644 >>>>> index 00000000000..110fdc72778 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>>>> @@ -0,0 +1,39 @@ >>>>> +/* Test -Wstrict-flex-arrays. */ >>>>> +/* { dg-do compile } */ >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1" } */ >>>>> + >>>>> +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) >>>>> +{ >>>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>>>> + trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>>>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>>>> + >>>>> +} >>>>> diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc >>>>> index 3846dc1d849..e6c6c5a301d 100644 >>>>> --- a/gcc/tree-vrp.cc >>>>> +++ b/gcc/tree-vrp.cc >>>>> @@ -1087,7 +1087,7 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p, >>>>> if (dump_file && (dump_flags & TDF_DETAILS)) >>>>> ranger->dump (dump_file); >>>>> >>>>> - if (warn_array_bounds && warn_array_bounds_p) >>>>> + if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p) >>>>> { >>>>> // Set all edges as executable, except those ranger says aren't. >>>>> int non_exec_flag = ranger->non_executable_edge_flag; >>>>> -- >>>>> 2.31.1 >>>>> >>>> >>>> >>> >>> -- >>> Richard Biener <rguenther@suse.de> >>> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, >>> Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; >>> HRB 36809 (AG Nuernberg) >> >> > > -- > Richard Biener <rguenther@suse.de> > SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, > Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; > HRB 36809 (AG Nuernberg)
On Thu, 15 Dec 2022, Qing Zhao wrote: > > > > On Dec 15, 2022, at 2:47 AM, Richard Biener <rguenther@suse.de> wrote: > > > > On Wed, 14 Dec 2022, Qing Zhao wrote: > > > >> Hi, Richard, > >> > >> I guess that we now agreed on the following: > >> > >> “ the information that we ran into a trailing array but didn't consider > >> it a flex array because of -fstrict-flex-arrays is always a useful information” > >> > >> The only thing we didn’t decide is: > >> > >> A. Amend such new information to -Warray-bounds when -fstrict-flex-arrays=N (N>0) specified. > >> > >> OR > >> > >> B. Issue such new information with a new warning option -Wstrict-flex-arrays when -fstrict-flex-arrays=N (N>0) specified. > >> > >> My current patch implemented B. > > > > Plus it implements it to specify a different flex-array variant for > > the extra diagnostic. > Could you clarify a little bit on this? (Don’t quite understand…) > > > >> If you think A is better, I will change the patch as A. > > > > I would tend to A since, as I said, it's useful information that > > shouldn't be hidden and not adding an option removes odd combination > > possibilities such as -Wno-array-bounds -Wstrict-flex-arrays. > > With current implementation, the above combination will ONLY report the > misuse of trailing array as flex-array. No out-of-bounds warnings > issued. > > > In particular I find, say, -fstrict-flex-arrays=2 -Wstrict-flex-arrays=1 > > hardly useful. > > The above combination will NOT happen, because there is NO level argument for -Wstrict-flex-arrays. > > The only combination will be: -fstrict-flex-arrays=N -Wstrict-flex-arrays > > When N > 0, -Wstrict-flex-arrays will report any misuse of trailing arrays as flexible array per the value of N. > > > > But I'm interested in other opinions. > > Adding a separate -Wstrict-flex-arrays will provide users a choice to ONLY look at the mis-use of trailing arrays as flex-arrays. Without this new option, such information will be buried into tons of out-of-bounds messges. > > I think this is the major benefit to have one separate new warning -Wstrict-flex-arrays. > > Do we need to provide the users this choice? Ah, OK - I can see the value of auditing code this way before enabling -fstrict-flex-arrays. > + if (opts->x_warn_strict_flex_arrays) > + if (opts->x_flag_strict_flex_arrays == 0) > + { > + opts->x_warn_strict_flex_arrays = 0; > + warning_at (UNKNOWN_LOCATION, 0, > + "%<-Wstrict-flex-arrays%> is ignored when" > + " %<-fstrict-flex-arrays%> does not present"); "is not present". The patch is OK with that change. Thanks and sorry for the slow process ... Richard. > Thanks. > > Qing > > > > Thanks, > > Richard. > > > >> Let me know your opinion. > >> > >> thanks. > >> > >> Qing > >> > >> > >>> On Dec 14, 2022, at 4:03 AM, Richard Biener <rguenther@suse.de> wrote: > >>> > >>> On Tue, 13 Dec 2022, Qing Zhao wrote: > >>> > >>>> Richard, > >>>> > >>>> Do you have any decision on this one? > >>>> Do we need this warning option For GCC? > >>> > >>> Looking at the testcases it seems that the diagnostic amends > >>> -Warray-bounds diagnostics for trailing but not flexible arrays? > >>> Wouldn't it be better to generally diagnose this, so have > >>> -Warray-bounds, with -fstrict-flex-arrays, for > >>> > >>> struct X { int a[1]; }; > >>> int foo (struct X *p) > >>> { > >>> return p->a[1]; > >>> } > >>> > >>> emit > >>> > >>> warning: array subscript 1 is above array bounds ... > >>> note: the trailing array is only a flexible array member with > >>> -fno-strict-flex-arrays > >>> > >>> ? Having -Wstrict-flex-arrays=N and N not agree with the > >>> -fstrict-flex-arrays level sounds hardly useful to me but the > >>> information that we ran into a trailing array but didn't consider > >>> it a flex array because of -fstrict-flex-arrays is always a > >>> useful information? > >>> > >>> But maybe I misunderstood this new diagnostic? > >>> > >>> Thanks, > >>> Richard. > >>> > >>> > >>>> thanks. > >>>> > >>>> Qing > >>>> > >>>>> On Dec 6, 2022, at 11:18 AM, Qing Zhao <qing.zhao@oracle.com> wrote: > >>>>> > >>>>> '-Wstrict-flex-arrays' > >>>>> Warn about inproper usages of flexible array members according to > >>>>> the LEVEL of the 'strict_flex_array (LEVEL)' attribute attached to > >>>>> the trailing array field of a structure if it's available, > >>>>> otherwise according to the LEVEL of the option > >>>>> '-fstrict-flex-arrays=LEVEL'. > >>>>> > >>>>> This option is effective only when LEVEL is bigger than 0. > >>>>> Otherwise, it will be ignored with a warning. > >>>>> > >>>>> when LEVEL=1, warnings will be issued for a trailing array > >>>>> reference of a structure that have 2 or more elements if the > >>>>> trailing array is referenced as a flexible array member. > >>>>> > >>>>> when LEVEL=2, in addition to LEVEL=1, additional warnings will be > >>>>> issued for a trailing one-element array reference of a structure if > >>>>> the array is referenced as a flexible array member. > >>>>> > >>>>> when LEVEL=3, in addition to LEVEL=2, additional warnings will be > >>>>> issued for a trailing zero-length array reference of a structure if > >>>>> the array is referenced as a flexible array member. > >>>>> > >>>>> gcc/ChangeLog: > >>>>> > >>>>> * doc/invoke.texi: Document -Wstrict-flex-arrays option. > >>>>> * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Add two more > >>>>> arguments. > >>>>> (array_bounds_checker::check_array_ref): Issue warnings for > >>>>> -Wstrict-flex-arrays. > >>>>> * opts.cc (finish_options): Issue warning for unsupported combination > >>>>> of -Wstrict_flex_arrays and -fstrict-flex-array. > >>>>> * tree-vrp.cc (execute_ranger_vrp): Enable the pass when > >>>>> warn_strict_flex_array is true. > >>>>> > >>>>> gcc/c-family/ChangeLog: > >>>>> > >>>>> * c.opt (Wstrict-flex-arrays): New option. > >>>>> > >>>>> gcc/testsuite/ChangeLog: > >>>>> > >>>>> * gcc.dg/Warray-bounds-flex-arrays-1.c: Update testing case with > >>>>> -Wstrict-flex-arrays. > >>>>> * gcc.dg/Warray-bounds-flex-arrays-2.c: Likewise. > >>>>> * gcc.dg/Warray-bounds-flex-arrays-3.c: Likewise. > >>>>> * gcc.dg/Warray-bounds-flex-arrays-4.c: Likewise. > >>>>> * gcc.dg/Warray-bounds-flex-arrays-5.c: Likewise. > >>>>> * gcc.dg/Warray-bounds-flex-arrays-6.c: Likewise. > >>>>> * c-c++-common/Wstrict-flex-arrays.c: New test. > >>>>> * gcc.dg/Wstrict-flex-arrays-2.c: New test. > >>>>> * gcc.dg/Wstrict-flex-arrays-3.c: New test. > >>>>> * gcc.dg/Wstrict-flex-arrays.c: New test. > >>>>> --- > >>>>> gcc/c-family/c.opt | 5 + > >>>>> gcc/doc/invoke.texi | 27 ++++- > >>>>> gcc/gimple-array-bounds.cc | 103 ++++++++++++++---- > >>>>> gcc/opts.cc | 8 ++ > >>>>> .../c-c++-common/Wstrict-flex-arrays.c | 9 ++ > >>>>> .../gcc.dg/Warray-bounds-flex-arrays-1.c | 5 +- > >>>>> .../gcc.dg/Warray-bounds-flex-arrays-2.c | 6 +- > >>>>> .../gcc.dg/Warray-bounds-flex-arrays-3.c | 7 +- > >>>>> .../gcc.dg/Warray-bounds-flex-arrays-4.c | 5 +- > >>>>> .../gcc.dg/Warray-bounds-flex-arrays-5.c | 6 +- > >>>>> .../gcc.dg/Warray-bounds-flex-arrays-6.c | 7 +- > >>>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c | 39 +++++++ > >>>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c | 39 +++++++ > >>>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c | 39 +++++++ > >>>>> gcc/tree-vrp.cc | 2 +- > >>>>> 15 files changed, 273 insertions(+), 34 deletions(-) > >>>>> create mode 100644 gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c > >>>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > >>>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > >>>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > >>>>> > >>>>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt > >>>>> index 0d0ad0a6374..33edeefd285 100644 > >>>>> --- a/gcc/c-family/c.opt > >>>>> +++ b/gcc/c-family/c.opt > >>>>> @@ -976,6 +976,11 @@ Wstringop-truncation > >>>>> C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ LTO ObjC++, Wall) > >>>>> Warn about truncation in string manipulation functions like strncat and strncpy. > >>>>> > >>>>> +Wstrict-flex-arrays > >>>>> +C C++ Var(warn_strict_flex_arrays) Warning > >>>>> +Warn about inproper usages of flexible array members > >>>>> +according to the level of -fstrict-flex-arrays. > >>>>> + > >>>>> Wsuggest-attribute=format > >>>>> C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning > >>>>> Warn about functions which might be candidates for format attributes. > >>>>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > >>>>> index 726392409b6..4402b0427ef 100644 > >>>>> --- a/gcc/doc/invoke.texi > >>>>> +++ b/gcc/doc/invoke.texi > >>>>> @@ -398,7 +398,7 @@ Objective-C and Objective-C++ Dialects}. > >>>>> -Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol > >>>>> -Wstring-compare @gol > >>>>> -Wno-stringop-overflow -Wno-stringop-overread @gol > >>>>> --Wno-stringop-truncation @gol > >>>>> +-Wno-stringop-truncation -Wstrict-flex-arrays @gol > >>>>> -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol > >>>>> -Wswitch -Wno-switch-bool -Wswitch-default -Wswitch-enum @gol > >>>>> -Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand @gol > >>>>> @@ -7835,6 +7835,31 @@ however, are not suitable arguments to functions that expect > >>>>> such arrays GCC issues warnings unless it can prove that the use is > >>>>> safe. @xref{Common Variable Attributes}. > >>>>> > >>>>> +@item -Wstrict-flex-arrays > >>>>> +@opindex Wstrict-flex-arrays > >>>>> +@opindex Wno-strict-flex-arrays > >>>>> +Warn about inproper usages of flexible array members > >>>>> +according to the @var{level} of the @code{strict_flex_array (@var{level})} > >>>>> +attribute attached to the trailing array field of a structure if it's > >>>>> +available, otherwise according to the @var{level} of the option > >>>>> +@option{-fstrict-flex-arrays=@var{level}}. > >>>>> + > >>>>> +This option is effective only when @var{level} is bigger than 0. Otherwise, > >>>>> +it will be ignored with a warning. > >>>>> + > >>>>> +when @var{level}=1, warnings will be issued for a trailing array reference > >>>>> +of a structure that have 2 or more elements if the trailing array is referenced > >>>>> +as a flexible array member. > >>>>> + > >>>>> +when @var{level}=2, in addition to @var{level}=1, additional warnings will be > >>>>> +issued for a trailing one-element array reference of a structure > >>>>> +if the array is referenced as a flexible array member. > >>>>> + > >>>>> +when @var{level}=3, in addition to @var{level}=2, additional warnings will be > >>>>> +issued for a trailing zero-length array reference of a structure > >>>>> +if the array is referenced as a flexible array member. > >>>>> + > >>>>> + > >>>>> @item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]} > >>>>> @opindex Wsuggest-attribute= > >>>>> @opindex Wno-suggest-attribute= > >>>>> diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc > >>>>> index db3459af325..825f11331b5 100644 > >>>>> --- a/gcc/gimple-array-bounds.cc > >>>>> +++ b/gcc/gimple-array-bounds.cc > >>>>> @@ -252,25 +252,34 @@ get_up_bounds_for_array_ref (tree ref, tree *decl, > >>>>> > >>>>> /* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND > >>>>> and UP_BOUND_P1, check whether the array reference REF is out of bound. > >>>>> - Issue warnings if out of bound, return TRUE if warnings are issued. */ > >>>>> + When out of bounds, set OUT_OF_BOUND to true. > >>>>> + Issue warnings if FOR_ARRAY_BOUND is true. > >>>>> + return TRUE if warnings are issued. */ > >>>>> + > >>>>> > >>>>> static bool > >>>>> check_out_of_bounds_and_warn (location_t location, tree ref, > >>>>> tree low_sub_org, tree low_sub, tree up_sub, > >>>>> tree up_bound, tree up_bound_p1, > >>>>> const value_range *vr, > >>>>> - bool ignore_off_by_one) > >>>>> + bool ignore_off_by_one, bool for_array_bound, > >>>>> + bool *out_of_bound) > >>>>> { > >>>>> tree low_bound = array_ref_low_bound (ref); > >>>>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); > >>>>> > >>>>> bool warned = false; > >>>>> + *out_of_bound = false; > >>>>> > >>>>> /* Empty array. */ > >>>>> if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1)) > >>>>> - warned = warning_at (location, OPT_Warray_bounds_, > >>>>> - "array subscript %E is outside array bounds of %qT", > >>>>> - low_sub_org, artype); > >>>>> + { > >>>>> + *out_of_bound = true; > >>>>> + if (for_array_bound) > >>>>> + warned = warning_at (location, OPT_Warray_bounds_, > >>>>> + "array subscript %E is outside array" > >>>>> + " bounds of %qT", low_sub_org, artype); > >>>>> + } > >>>>> > >>>>> if (warned) > >>>>> ; /* Do nothing. */ > >>>>> @@ -283,24 +292,33 @@ check_out_of_bounds_and_warn (location_t location, tree ref, > >>>>> : tree_int_cst_le (up_bound, up_sub)) > >>>>> && TREE_CODE (low_sub) == INTEGER_CST > >>>>> && tree_int_cst_le (low_sub, low_bound)) > >>>>> - warned = warning_at (location, OPT_Warray_bounds_, > >>>>> - "array subscript [%E, %E] is outside " > >>>>> - "array bounds of %qT", > >>>>> - low_sub, up_sub, artype); > >>>>> + { > >>>>> + *out_of_bound = true; > >>>>> + warned = warning_at (location, OPT_Warray_bounds_, > >>>>> + "array subscript [%E, %E] is outside " > >>>>> + "array bounds of %qT", > >>>>> + low_sub, up_sub, artype); > >>>>> + } > >>>>> } > >>>>> else if (up_bound > >>>>> && TREE_CODE (up_sub) == INTEGER_CST > >>>>> && (ignore_off_by_one > >>>>> ? !tree_int_cst_le (up_sub, up_bound_p1) > >>>>> : !tree_int_cst_le (up_sub, up_bound))) > >>>>> - warned = warning_at (location, OPT_Warray_bounds_, > >>>>> - "array subscript %E is above array bounds of %qT", > >>>>> - up_sub, artype); > >>>>> + { > >>>>> + *out_of_bound = true; > >>>>> + warned = warning_at (location, OPT_Warray_bounds_, > >>>>> + "array subscript %E is above array bounds of %qT", > >>>>> + up_sub, artype); > >>>>> + } > >>>>> else if (TREE_CODE (low_sub) == INTEGER_CST > >>>>> && tree_int_cst_lt (low_sub, low_bound)) > >>>>> - warned = warning_at (location, OPT_Warray_bounds_, > >>>>> - "array subscript %E is below array bounds of %qT", > >>>>> - low_sub, artype); > >>>>> + { > >>>>> + *out_of_bound = true; > >>>>> + warned = warning_at (location, OPT_Warray_bounds_, > >>>>> + "array subscript %E is below array bounds of %qT", > >>>>> + low_sub, artype); > >>>>> + } > >>>>> return warned; > >>>>> } > >>>>> > >>>>> @@ -333,14 +351,21 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > >>>>> > >>>>> tree arg = TREE_OPERAND (ref, 0); > >>>>> const bool compref = TREE_CODE (arg) == COMPONENT_REF; > >>>>> + unsigned int strict_flex_array_level = flag_strict_flex_arrays; > >>>>> > >>>>> if (compref) > >>>>> - /* Try to determine special array member type for this COMPONENT_REF. */ > >>>>> - sam = component_ref_sam_type (arg); > >>>>> + { > >>>>> + /* Try to determine special array member type for this COMPONENT_REF. */ > >>>>> + sam = component_ref_sam_type (arg); > >>>>> + /* Get the level of strict_flex_array for this array field. */ > >>>>> + tree afield_decl = TREE_OPERAND (arg, 1); > >>>>> + strict_flex_array_level = strict_flex_array_level_of (afield_decl); > >>>>> + } > >>>>> > >>>>> get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); > >>>>> > >>>>> bool warned = false; > >>>>> + bool out_of_bound = false; > >>>>> > >>>>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); > >>>>> tree low_sub_org = TREE_OPERAND (ref, 1); > >>>>> @@ -361,7 +386,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > >>>>> warned = check_out_of_bounds_and_warn (location, ref, > >>>>> low_sub_org, low_sub, up_sub, > >>>>> up_bound, up_bound_p1, vr, > >>>>> - ignore_off_by_one); > >>>>> + ignore_off_by_one, warn_array_bounds, > >>>>> + &out_of_bound); > >>>>> > >>>>> > >>>>> if (!warned && sam == special_array_member::int_0) > >>>>> @@ -373,19 +399,56 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, > >>>>> "of an interior zero-length array %qT")), > >>>>> low_sub, artype); > >>>>> > >>>>> - if (warned) > >>>>> + if (warned || out_of_bound) > >>>>> { > >>>>> - if (dump_file && (dump_flags & TDF_DETAILS)) > >>>>> + if (warned && dump_file && (dump_flags & TDF_DETAILS)) > >>>>> { > >>>>> fprintf (dump_file, "Array bound warning for "); > >>>>> dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); > >>>>> fprintf (dump_file, "\n"); > >>>>> } > >>>>> > >>>>> + /* issue warnings for -Wstrict-flex-arrays according to the level of > >>>>> + flag_strict_flex_arrays. */ > >>>>> + if (out_of_bound && warn_strict_flex_arrays) > >>>>> + switch (strict_flex_array_level) > >>>>> + { > >>>>> + case 3: > >>>>> + /* Issue additional warnings for trailing arrays [0]. */ > >>>>> + if (sam == special_array_member::trail_0) > >>>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, > >>>>> + "trailing array %qT should not be used as " > >>>>> + "a flexible array member for level 3", > >>>>> + artype); > >>>>> + /* FALLTHROUGH. */ > >>>>> + case 2: > >>>>> + /* Issue additional warnings for trailing arrays [1]. */ > >>>>> + if (sam == special_array_member::trail_1) > >>>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, > >>>>> + "trailing array %qT should not be used as " > >>>>> + "a flexible array member for level 2 and " > >>>>> + "above", artype); > >>>>> + /* FALLTHROUGH. */ > >>>>> + case 1: > >>>>> + /* Issue warnings for trailing arrays [n]. */ > >>>>> + if (sam == special_array_member::trail_n) > >>>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, > >>>>> + "trailing array %qT should not be used as " > >>>>> + "a flexible array member for level 1 and " > >>>>> + "above", artype); > >>>>> + break; > >>>>> + case 0: > >>>>> + /* Do nothing. */ > >>>>> + break; > >>>>> + default: > >>>>> + gcc_unreachable (); > >>>>> + } > >>>>> + > >>>>> /* Avoid more warnings when checking more significant subscripts > >>>>> of the same expression. */ > >>>>> ref = TREE_OPERAND (ref, 0); > >>>>> suppress_warning (ref, OPT_Warray_bounds_); > >>>>> + suppress_warning (ref, OPT_Wstrict_flex_arrays); > >>>>> > >>>>> if (decl) > >>>>> ref = decl; > >>>>> diff --git a/gcc/opts.cc b/gcc/opts.cc > >>>>> index 73fc97756e4..8db53ad6c77 100644 > >>>>> --- a/gcc/opts.cc > >>>>> +++ b/gcc/opts.cc > >>>>> @@ -1411,6 +1411,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, > >>>>> opts->x_profile_flag = 0; > >>>>> } > >>>>> > >>>>> + if (opts->x_warn_strict_flex_arrays) > >>>>> + if (opts->x_flag_strict_flex_arrays == 0) > >>>>> + { > >>>>> + opts->x_warn_strict_flex_arrays = 0; > >>>>> + warning_at (UNKNOWN_LOCATION, 0, > >>>>> + "%<-Wstrict-flex-arrays%> is ignored when" > >>>>> + " %<-fstrict-flex-arrays%> does not present"); > >>>>> + } > >>>>> > >>>>> diagnose_options (opts, opts_set, loc); > >>>>> } > >>>>> diff --git a/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c > >>>>> new file mode 100644 > >>>>> index 00000000000..72b4b7c6406 > >>>>> --- /dev/null > >>>>> +++ b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c > >>>>> @@ -0,0 +1,9 @@ > >>>>> +/* Test the usage of option -Wstrict-flex-arrays. */ > >>>>> +/* { dg-do compile } */ > >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays" } */ > >>>>> + > >>>>> +int main(int argc, char *argv[]) > >>>>> +{ > >>>>> + return 0; > >>>>> +} > >>>>> +/* { dg-warning "is ignored when \'-fstrict-flex-arrays\' does not present" "" { target *-*-* } 0 } */ > >>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > >>>>> index d36ba4d86cb..65c9fec43af 100644 > >>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > >>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c > >>>>> @@ -1,6 +1,6 @@ > >>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ > >>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ > >>>>> /* { dg-do compile} */ > >>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */ > >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds" } */ > >>>>> > >>>>> struct trailing_array_1 { > >>>>> int a; > >>>>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( > >>>>> struct trailing_array_4 *trailing_flex) > >>>>> { > >>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > >>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > >>>>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ > >>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > >>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > >>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > >>>>> index f63206e1948..2b5a895c598 100644 > >>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > >>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c > >>>>> @@ -1,6 +1,6 @@ > >>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ > >>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ > >>>>> /* { dg-do compile } */ > >>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */ > >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds" } */ > >>>>> > >>>>> struct trailing_array_1 { > >>>>> int a; > >>>>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( > >>>>> struct trailing_array_4 *trailing_flex) > >>>>> { > >>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > >>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > >>>>> trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ > >>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > >>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > >>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > >>>>> > >>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > >>>>> index e3273714e8b..25b903f2615 100644 > >>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > >>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c > >>>>> @@ -1,6 +1,6 @@ > >>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ > >>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ > >>>>> /* { dg-do compile } */ > >>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */ > >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds" } */ > >>>>> > >>>>> struct trailing_array_1 { > >>>>> int a; > >>>>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( > >>>>> struct trailing_array_4 *trailing_flex) > >>>>> { > >>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > >>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > >>>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > >>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > >>>>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ > >>>>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ > >>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */ > >>>>> > >>>>> } > >>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > >>>>> index cabaea77dc2..5fc500a19ca 100644 > >>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > >>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c > >>>>> @@ -1,6 +1,6 @@ > >>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ > >>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ > >>>>> /* { dg-do compile } */ > >>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */ > >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds=2" } */ > >>>>> > >>>>> struct trailing_array_1 { > >>>>> int a; > >>>>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( > >>>>> struct trailing_array_4 *trailing_flex) > >>>>> { > >>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > >>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > >>>>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ > >>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > >>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > >>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > >>>>> index 8b7db6e4f39..30bb4ca8832 100644 > >>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > >>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c > >>>>> @@ -1,6 +1,6 @@ > >>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ > >>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ > >>>>> /* { dg-do compile } */ > >>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */ > >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds=2" } */ > >>>>> > >>>>> struct trailing_array_1 { > >>>>> int a; > >>>>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( > >>>>> struct trailing_array_4 *trailing_flex) > >>>>> { > >>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > >>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > >>>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > >>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > >>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ > >>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > >>>>> > >>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > >>>>> index 035bf481396..e847a44516e 100644 > >>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > >>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c > >>>>> @@ -1,6 +1,6 @@ > >>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ > >>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ > >>>>> /* { dg-do compile } */ > >>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */ > >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds=2" } */ > >>>>> > >>>>> struct trailing_array_1 { > >>>>> int a; > >>>>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( > >>>>> struct trailing_array_4 *trailing_flex) > >>>>> { > >>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ > >>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ > >>>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ > >>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ > >>>>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ > >>>>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ > >>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ > >>>>> > >>>>> } > >>>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > >>>>> new file mode 100644 > >>>>> index 00000000000..2e241f96208 > >>>>> --- /dev/null > >>>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c > >>>>> @@ -0,0 +1,39 @@ > >>>>> +/* Test -Wstrict-flex-arrays. */ > >>>>> +/* { dg-do compile } */ > >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2" } */ > >>>>> + > >>>>> +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) > >>>>> +{ > >>>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > >>>>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ > >>>>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ > >>>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ > >>>>> + > >>>>> +} > >>>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > >>>>> new file mode 100644 > >>>>> index 00000000000..97eb65ba0a9 > >>>>> --- /dev/null > >>>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c > >>>>> @@ -0,0 +1,39 @@ > >>>>> +/* Test -Wstrict-flex-arrays. */ > >>>>> +/* { dg-do compile } */ > >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3" } */ > >>>>> + > >>>>> +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) > >>>>> +{ > >>>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > >>>>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ > >>>>> + trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */ > >>>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */ > >>>>> + > >>>>> +} > >>>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > >>>>> new file mode 100644 > >>>>> index 00000000000..110fdc72778 > >>>>> --- /dev/null > >>>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c > >>>>> @@ -0,0 +1,39 @@ > >>>>> +/* Test -Wstrict-flex-arrays. */ > >>>>> +/* { dg-do compile } */ > >>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1" } */ > >>>>> + > >>>>> +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) > >>>>> +{ > >>>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ > >>>>> + trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > >>>>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > >>>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ > >>>>> + > >>>>> +} > >>>>> diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc > >>>>> index 3846dc1d849..e6c6c5a301d 100644 > >>>>> --- a/gcc/tree-vrp.cc > >>>>> +++ b/gcc/tree-vrp.cc > >>>>> @@ -1087,7 +1087,7 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p, > >>>>> if (dump_file && (dump_flags & TDF_DETAILS)) > >>>>> ranger->dump (dump_file); > >>>>> > >>>>> - if (warn_array_bounds && warn_array_bounds_p) > >>>>> + if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p) > >>>>> { > >>>>> // Set all edges as executable, except those ranger says aren't. > >>>>> int non_exec_flag = ranger->non_executable_edge_flag; > >>>>> -- > >>>>> 2.31.1 > >>>>> > >>>> > >>>> > >>> > >>> -- > >>> Richard Biener <rguenther@suse.de> > >>> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, > >>> Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; > >>> HRB 36809 (AG Nuernberg) > >> > >> > > > > -- > > Richard Biener <rguenther@suse.de> > > SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, > > Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; > > HRB 36809 (AG Nuernberg) > >
> On Dec 16, 2022, at 4:17 AM, Richard Biener <rguenther@suse.de> wrote: > > On Thu, 15 Dec 2022, Qing Zhao wrote: > >> >> >>> On Dec 15, 2022, at 2:47 AM, Richard Biener <rguenther@suse.de> wrote: >>> >>> On Wed, 14 Dec 2022, Qing Zhao wrote: >>> >>>> Hi, Richard, >>>> >>>> I guess that we now agreed on the following: >>>> >>>> “ the information that we ran into a trailing array but didn't consider >>>> it a flex array because of -fstrict-flex-arrays is always a useful information” >>>> >>>> The only thing we didn’t decide is: >>>> >>>> A. Amend such new information to -Warray-bounds when -fstrict-flex-arrays=N (N>0) specified. >>>> >>>> OR >>>> >>>> B. Issue such new information with a new warning option -Wstrict-flex-arrays when -fstrict-flex-arrays=N (N>0) specified. >>>> >>>> My current patch implemented B. >>> >>> Plus it implements it to specify a different flex-array variant for >>> the extra diagnostic. >> Could you clarify a little bit on this? (Don’t quite understand…) >>> >>>> If you think A is better, I will change the patch as A. >>> >>> I would tend to A since, as I said, it's useful information that >>> shouldn't be hidden and not adding an option removes odd combination >>> possibilities such as -Wno-array-bounds -Wstrict-flex-arrays. >> >> With current implementation, the above combination will ONLY report the >> misuse of trailing array as flex-array. No out-of-bounds warnings >> issued. >> >>> In particular I find, say, -fstrict-flex-arrays=2 -Wstrict-flex-arrays=1 >>> hardly useful. >> >> The above combination will NOT happen, because there is NO level argument for -Wstrict-flex-arrays. >> >> The only combination will be: -fstrict-flex-arrays=N -Wstrict-flex-arrays >> >> When N > 0, -Wstrict-flex-arrays will report any misuse of trailing arrays as flexible array per the value of N. >>> >>> But I'm interested in other opinions. >> >> Adding a separate -Wstrict-flex-arrays will provide users a choice to ONLY look at the mis-use of trailing arrays as flex-arrays. Without this new option, such information will be buried into tons of out-of-bounds messges. >> >> I think this is the major benefit to have one separate new warning -Wstrict-flex-arrays. >> >> Do we need to provide the users this choice? > > Ah, OK - I can see the value of auditing code this way before > enabling -fstrict-flex-arrays. Yes, I think the major benefit of this option is to help users to identify all the places where the trailing arrays are misused as flex-arrays at different level of -fstrict-flex-arrays=N, then update their source code accordingly. And finally can enable -fstrict-flex-arrays by default. > >> + if (opts->x_warn_strict_flex_arrays) >> + if (opts->x_flag_strict_flex_arrays == 0) >> + { >> + opts->x_warn_strict_flex_arrays = 0; >> + warning_at (UNKNOWN_LOCATION, 0, >> + "%<-Wstrict-flex-arrays%> is ignored when" >> + " %<-fstrict-flex-arrays%> does not present"); > > "is not present”. Okay. > > The patch is OK with that change. Thanks! Will commit the patch after the change. > > Thanks and sorry for the slow process ... Thank you for your patience and questions. The discussion is very helpful since I was not 100% sure whether this new warning is necessary or not in the beginning, but now after this discussion I feel confident that it’s a necessary option to be added. Qing > > Richard. > >> Thanks. >> >> Qing >>> >>> Thanks, >>> Richard. >>> >>>> Let me know your opinion. >>>> >>>> thanks. >>>> >>>> Qing >>>> >>>> >>>>> On Dec 14, 2022, at 4:03 AM, Richard Biener <rguenther@suse.de> wrote: >>>>> >>>>> On Tue, 13 Dec 2022, Qing Zhao wrote: >>>>> >>>>>> Richard, >>>>>> >>>>>> Do you have any decision on this one? >>>>>> Do we need this warning option For GCC? >>>>> >>>>> Looking at the testcases it seems that the diagnostic amends >>>>> -Warray-bounds diagnostics for trailing but not flexible arrays? >>>>> Wouldn't it be better to generally diagnose this, so have >>>>> -Warray-bounds, with -fstrict-flex-arrays, for >>>>> >>>>> struct X { int a[1]; }; >>>>> int foo (struct X *p) >>>>> { >>>>> return p->a[1]; >>>>> } >>>>> >>>>> emit >>>>> >>>>> warning: array subscript 1 is above array bounds ... >>>>> note: the trailing array is only a flexible array member with >>>>> -fno-strict-flex-arrays >>>>> >>>>> ? Having -Wstrict-flex-arrays=N and N not agree with the >>>>> -fstrict-flex-arrays level sounds hardly useful to me but the >>>>> information that we ran into a trailing array but didn't consider >>>>> it a flex array because of -fstrict-flex-arrays is always a >>>>> useful information? >>>>> >>>>> But maybe I misunderstood this new diagnostic? >>>>> >>>>> Thanks, >>>>> Richard. >>>>> >>>>> >>>>>> thanks. >>>>>> >>>>>> Qing >>>>>> >>>>>>> On Dec 6, 2022, at 11:18 AM, Qing Zhao <qing.zhao@oracle.com> wrote: >>>>>>> >>>>>>> '-Wstrict-flex-arrays' >>>>>>> Warn about inproper usages of flexible array members according to >>>>>>> the LEVEL of the 'strict_flex_array (LEVEL)' attribute attached to >>>>>>> the trailing array field of a structure if it's available, >>>>>>> otherwise according to the LEVEL of the option >>>>>>> '-fstrict-flex-arrays=LEVEL'. >>>>>>> >>>>>>> This option is effective only when LEVEL is bigger than 0. >>>>>>> Otherwise, it will be ignored with a warning. >>>>>>> >>>>>>> when LEVEL=1, warnings will be issued for a trailing array >>>>>>> reference of a structure that have 2 or more elements if the >>>>>>> trailing array is referenced as a flexible array member. >>>>>>> >>>>>>> when LEVEL=2, in addition to LEVEL=1, additional warnings will be >>>>>>> issued for a trailing one-element array reference of a structure if >>>>>>> the array is referenced as a flexible array member. >>>>>>> >>>>>>> when LEVEL=3, in addition to LEVEL=2, additional warnings will be >>>>>>> issued for a trailing zero-length array reference of a structure if >>>>>>> the array is referenced as a flexible array member. >>>>>>> >>>>>>> gcc/ChangeLog: >>>>>>> >>>>>>> * doc/invoke.texi: Document -Wstrict-flex-arrays option. >>>>>>> * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Add two more >>>>>>> arguments. >>>>>>> (array_bounds_checker::check_array_ref): Issue warnings for >>>>>>> -Wstrict-flex-arrays. >>>>>>> * opts.cc (finish_options): Issue warning for unsupported combination >>>>>>> of -Wstrict_flex_arrays and -fstrict-flex-array. >>>>>>> * tree-vrp.cc (execute_ranger_vrp): Enable the pass when >>>>>>> warn_strict_flex_array is true. >>>>>>> >>>>>>> gcc/c-family/ChangeLog: >>>>>>> >>>>>>> * c.opt (Wstrict-flex-arrays): New option. >>>>>>> >>>>>>> gcc/testsuite/ChangeLog: >>>>>>> >>>>>>> * gcc.dg/Warray-bounds-flex-arrays-1.c: Update testing case with >>>>>>> -Wstrict-flex-arrays. >>>>>>> * gcc.dg/Warray-bounds-flex-arrays-2.c: Likewise. >>>>>>> * gcc.dg/Warray-bounds-flex-arrays-3.c: Likewise. >>>>>>> * gcc.dg/Warray-bounds-flex-arrays-4.c: Likewise. >>>>>>> * gcc.dg/Warray-bounds-flex-arrays-5.c: Likewise. >>>>>>> * gcc.dg/Warray-bounds-flex-arrays-6.c: Likewise. >>>>>>> * c-c++-common/Wstrict-flex-arrays.c: New test. >>>>>>> * gcc.dg/Wstrict-flex-arrays-2.c: New test. >>>>>>> * gcc.dg/Wstrict-flex-arrays-3.c: New test. >>>>>>> * gcc.dg/Wstrict-flex-arrays.c: New test. >>>>>>> --- >>>>>>> gcc/c-family/c.opt | 5 + >>>>>>> gcc/doc/invoke.texi | 27 ++++- >>>>>>> gcc/gimple-array-bounds.cc | 103 ++++++++++++++---- >>>>>>> gcc/opts.cc | 8 ++ >>>>>>> .../c-c++-common/Wstrict-flex-arrays.c | 9 ++ >>>>>>> .../gcc.dg/Warray-bounds-flex-arrays-1.c | 5 +- >>>>>>> .../gcc.dg/Warray-bounds-flex-arrays-2.c | 6 +- >>>>>>> .../gcc.dg/Warray-bounds-flex-arrays-3.c | 7 +- >>>>>>> .../gcc.dg/Warray-bounds-flex-arrays-4.c | 5 +- >>>>>>> .../gcc.dg/Warray-bounds-flex-arrays-5.c | 6 +- >>>>>>> .../gcc.dg/Warray-bounds-flex-arrays-6.c | 7 +- >>>>>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c | 39 +++++++ >>>>>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c | 39 +++++++ >>>>>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c | 39 +++++++ >>>>>>> gcc/tree-vrp.cc | 2 +- >>>>>>> 15 files changed, 273 insertions(+), 34 deletions(-) >>>>>>> create mode 100644 gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>>>>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>>>>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>>>>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>>>>>> >>>>>>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt >>>>>>> index 0d0ad0a6374..33edeefd285 100644 >>>>>>> --- a/gcc/c-family/c.opt >>>>>>> +++ b/gcc/c-family/c.opt >>>>>>> @@ -976,6 +976,11 @@ Wstringop-truncation >>>>>>> C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ LTO ObjC++, Wall) >>>>>>> Warn about truncation in string manipulation functions like strncat and strncpy. >>>>>>> >>>>>>> +Wstrict-flex-arrays >>>>>>> +C C++ Var(warn_strict_flex_arrays) Warning >>>>>>> +Warn about inproper usages of flexible array members >>>>>>> +according to the level of -fstrict-flex-arrays. >>>>>>> + >>>>>>> Wsuggest-attribute=format >>>>>>> C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning >>>>>>> Warn about functions which might be candidates for format attributes. >>>>>>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi >>>>>>> index 726392409b6..4402b0427ef 100644 >>>>>>> --- a/gcc/doc/invoke.texi >>>>>>> +++ b/gcc/doc/invoke.texi >>>>>>> @@ -398,7 +398,7 @@ Objective-C and Objective-C++ Dialects}. >>>>>>> -Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol >>>>>>> -Wstring-compare @gol >>>>>>> -Wno-stringop-overflow -Wno-stringop-overread @gol >>>>>>> --Wno-stringop-truncation @gol >>>>>>> +-Wno-stringop-truncation -Wstrict-flex-arrays @gol >>>>>>> -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol >>>>>>> -Wswitch -Wno-switch-bool -Wswitch-default -Wswitch-enum @gol >>>>>>> -Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand @gol >>>>>>> @@ -7835,6 +7835,31 @@ however, are not suitable arguments to functions that expect >>>>>>> such arrays GCC issues warnings unless it can prove that the use is >>>>>>> safe. @xref{Common Variable Attributes}. >>>>>>> >>>>>>> +@item -Wstrict-flex-arrays >>>>>>> +@opindex Wstrict-flex-arrays >>>>>>> +@opindex Wno-strict-flex-arrays >>>>>>> +Warn about inproper usages of flexible array members >>>>>>> +according to the @var{level} of the @code{strict_flex_array (@var{level})} >>>>>>> +attribute attached to the trailing array field of a structure if it's >>>>>>> +available, otherwise according to the @var{level} of the option >>>>>>> +@option{-fstrict-flex-arrays=@var{level}}. >>>>>>> + >>>>>>> +This option is effective only when @var{level} is bigger than 0. Otherwise, >>>>>>> +it will be ignored with a warning. >>>>>>> + >>>>>>> +when @var{level}=1, warnings will be issued for a trailing array reference >>>>>>> +of a structure that have 2 or more elements if the trailing array is referenced >>>>>>> +as a flexible array member. >>>>>>> + >>>>>>> +when @var{level}=2, in addition to @var{level}=1, additional warnings will be >>>>>>> +issued for a trailing one-element array reference of a structure >>>>>>> +if the array is referenced as a flexible array member. >>>>>>> + >>>>>>> +when @var{level}=3, in addition to @var{level}=2, additional warnings will be >>>>>>> +issued for a trailing zero-length array reference of a structure >>>>>>> +if the array is referenced as a flexible array member. >>>>>>> + >>>>>>> + >>>>>>> @item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]} >>>>>>> @opindex Wsuggest-attribute= >>>>>>> @opindex Wno-suggest-attribute= >>>>>>> diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc >>>>>>> index db3459af325..825f11331b5 100644 >>>>>>> --- a/gcc/gimple-array-bounds.cc >>>>>>> +++ b/gcc/gimple-array-bounds.cc >>>>>>> @@ -252,25 +252,34 @@ get_up_bounds_for_array_ref (tree ref, tree *decl, >>>>>>> >>>>>>> /* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND >>>>>>> and UP_BOUND_P1, check whether the array reference REF is out of bound. >>>>>>> - Issue warnings if out of bound, return TRUE if warnings are issued. */ >>>>>>> + When out of bounds, set OUT_OF_BOUND to true. >>>>>>> + Issue warnings if FOR_ARRAY_BOUND is true. >>>>>>> + return TRUE if warnings are issued. */ >>>>>>> + >>>>>>> >>>>>>> static bool >>>>>>> check_out_of_bounds_and_warn (location_t location, tree ref, >>>>>>> tree low_sub_org, tree low_sub, tree up_sub, >>>>>>> tree up_bound, tree up_bound_p1, >>>>>>> const value_range *vr, >>>>>>> - bool ignore_off_by_one) >>>>>>> + bool ignore_off_by_one, bool for_array_bound, >>>>>>> + bool *out_of_bound) >>>>>>> { >>>>>>> tree low_bound = array_ref_low_bound (ref); >>>>>>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); >>>>>>> >>>>>>> bool warned = false; >>>>>>> + *out_of_bound = false; >>>>>>> >>>>>>> /* Empty array. */ >>>>>>> if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1)) >>>>>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>>>>> - "array subscript %E is outside array bounds of %qT", >>>>>>> - low_sub_org, artype); >>>>>>> + { >>>>>>> + *out_of_bound = true; >>>>>>> + if (for_array_bound) >>>>>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>>>>> + "array subscript %E is outside array" >>>>>>> + " bounds of %qT", low_sub_org, artype); >>>>>>> + } >>>>>>> >>>>>>> if (warned) >>>>>>> ; /* Do nothing. */ >>>>>>> @@ -283,24 +292,33 @@ check_out_of_bounds_and_warn (location_t location, tree ref, >>>>>>> : tree_int_cst_le (up_bound, up_sub)) >>>>>>> && TREE_CODE (low_sub) == INTEGER_CST >>>>>>> && tree_int_cst_le (low_sub, low_bound)) >>>>>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>>>>> - "array subscript [%E, %E] is outside " >>>>>>> - "array bounds of %qT", >>>>>>> - low_sub, up_sub, artype); >>>>>>> + { >>>>>>> + *out_of_bound = true; >>>>>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>>>>> + "array subscript [%E, %E] is outside " >>>>>>> + "array bounds of %qT", >>>>>>> + low_sub, up_sub, artype); >>>>>>> + } >>>>>>> } >>>>>>> else if (up_bound >>>>>>> && TREE_CODE (up_sub) == INTEGER_CST >>>>>>> && (ignore_off_by_one >>>>>>> ? !tree_int_cst_le (up_sub, up_bound_p1) >>>>>>> : !tree_int_cst_le (up_sub, up_bound))) >>>>>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>>>>> - "array subscript %E is above array bounds of %qT", >>>>>>> - up_sub, artype); >>>>>>> + { >>>>>>> + *out_of_bound = true; >>>>>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>>>>> + "array subscript %E is above array bounds of %qT", >>>>>>> + up_sub, artype); >>>>>>> + } >>>>>>> else if (TREE_CODE (low_sub) == INTEGER_CST >>>>>>> && tree_int_cst_lt (low_sub, low_bound)) >>>>>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>>>>> - "array subscript %E is below array bounds of %qT", >>>>>>> - low_sub, artype); >>>>>>> + { >>>>>>> + *out_of_bound = true; >>>>>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>>>>> + "array subscript %E is below array bounds of %qT", >>>>>>> + low_sub, artype); >>>>>>> + } >>>>>>> return warned; >>>>>>> } >>>>>>> >>>>>>> @@ -333,14 +351,21 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>>>>>> >>>>>>> tree arg = TREE_OPERAND (ref, 0); >>>>>>> const bool compref = TREE_CODE (arg) == COMPONENT_REF; >>>>>>> + unsigned int strict_flex_array_level = flag_strict_flex_arrays; >>>>>>> >>>>>>> if (compref) >>>>>>> - /* Try to determine special array member type for this COMPONENT_REF. */ >>>>>>> - sam = component_ref_sam_type (arg); >>>>>>> + { >>>>>>> + /* Try to determine special array member type for this COMPONENT_REF. */ >>>>>>> + sam = component_ref_sam_type (arg); >>>>>>> + /* Get the level of strict_flex_array for this array field. */ >>>>>>> + tree afield_decl = TREE_OPERAND (arg, 1); >>>>>>> + strict_flex_array_level = strict_flex_array_level_of (afield_decl); >>>>>>> + } >>>>>>> >>>>>>> get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); >>>>>>> >>>>>>> bool warned = false; >>>>>>> + bool out_of_bound = false; >>>>>>> >>>>>>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); >>>>>>> tree low_sub_org = TREE_OPERAND (ref, 1); >>>>>>> @@ -361,7 +386,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>>>>>> warned = check_out_of_bounds_and_warn (location, ref, >>>>>>> low_sub_org, low_sub, up_sub, >>>>>>> up_bound, up_bound_p1, vr, >>>>>>> - ignore_off_by_one); >>>>>>> + ignore_off_by_one, warn_array_bounds, >>>>>>> + &out_of_bound); >>>>>>> >>>>>>> >>>>>>> if (!warned && sam == special_array_member::int_0) >>>>>>> @@ -373,19 +399,56 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>>>>>> "of an interior zero-length array %qT")), >>>>>>> low_sub, artype); >>>>>>> >>>>>>> - if (warned) >>>>>>> + if (warned || out_of_bound) >>>>>>> { >>>>>>> - if (dump_file && (dump_flags & TDF_DETAILS)) >>>>>>> + if (warned && dump_file && (dump_flags & TDF_DETAILS)) >>>>>>> { >>>>>>> fprintf (dump_file, "Array bound warning for "); >>>>>>> dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); >>>>>>> fprintf (dump_file, "\n"); >>>>>>> } >>>>>>> >>>>>>> + /* issue warnings for -Wstrict-flex-arrays according to the level of >>>>>>> + flag_strict_flex_arrays. */ >>>>>>> + if (out_of_bound && warn_strict_flex_arrays) >>>>>>> + switch (strict_flex_array_level) >>>>>>> + { >>>>>>> + case 3: >>>>>>> + /* Issue additional warnings for trailing arrays [0]. */ >>>>>>> + if (sam == special_array_member::trail_0) >>>>>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>>>>>> + "trailing array %qT should not be used as " >>>>>>> + "a flexible array member for level 3", >>>>>>> + artype); >>>>>>> + /* FALLTHROUGH. */ >>>>>>> + case 2: >>>>>>> + /* Issue additional warnings for trailing arrays [1]. */ >>>>>>> + if (sam == special_array_member::trail_1) >>>>>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>>>>>> + "trailing array %qT should not be used as " >>>>>>> + "a flexible array member for level 2 and " >>>>>>> + "above", artype); >>>>>>> + /* FALLTHROUGH. */ >>>>>>> + case 1: >>>>>>> + /* Issue warnings for trailing arrays [n]. */ >>>>>>> + if (sam == special_array_member::trail_n) >>>>>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>>>>>> + "trailing array %qT should not be used as " >>>>>>> + "a flexible array member for level 1 and " >>>>>>> + "above", artype); >>>>>>> + break; >>>>>>> + case 0: >>>>>>> + /* Do nothing. */ >>>>>>> + break; >>>>>>> + default: >>>>>>> + gcc_unreachable (); >>>>>>> + } >>>>>>> + >>>>>>> /* Avoid more warnings when checking more significant subscripts >>>>>>> of the same expression. */ >>>>>>> ref = TREE_OPERAND (ref, 0); >>>>>>> suppress_warning (ref, OPT_Warray_bounds_); >>>>>>> + suppress_warning (ref, OPT_Wstrict_flex_arrays); >>>>>>> >>>>>>> if (decl) >>>>>>> ref = decl; >>>>>>> diff --git a/gcc/opts.cc b/gcc/opts.cc >>>>>>> index 73fc97756e4..8db53ad6c77 100644 >>>>>>> --- a/gcc/opts.cc >>>>>>> +++ b/gcc/opts.cc >>>>>>> @@ -1411,6 +1411,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, >>>>>>> opts->x_profile_flag = 0; >>>>>>> } >>>>>>> >>>>>>> + if (opts->x_warn_strict_flex_arrays) >>>>>>> + if (opts->x_flag_strict_flex_arrays == 0) >>>>>>> + { >>>>>>> + opts->x_warn_strict_flex_arrays = 0; >>>>>>> + warning_at (UNKNOWN_LOCATION, 0, >>>>>>> + "%<-Wstrict-flex-arrays%> is ignored when" >>>>>>> + " %<-fstrict-flex-arrays%> does not present"); >>>>>>> + } >>>>>>> >>>>>>> diagnose_options (opts, opts_set, loc); >>>>>>> } >>>>>>> diff --git a/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>>>>>> new file mode 100644 >>>>>>> index 00000000000..72b4b7c6406 >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>>>>>> @@ -0,0 +1,9 @@ >>>>>>> +/* Test the usage of option -Wstrict-flex-arrays. */ >>>>>>> +/* { dg-do compile } */ >>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays" } */ >>>>>>> + >>>>>>> +int main(int argc, char *argv[]) >>>>>>> +{ >>>>>>> + return 0; >>>>>>> +} >>>>>>> +/* { dg-warning "is ignored when \'-fstrict-flex-arrays\' does not present" "" { target *-*-* } 0 } */ >>>>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>>>>>> index d36ba4d86cb..65c9fec43af 100644 >>>>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>>>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>>>>>> @@ -1,6 +1,6 @@ >>>>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>>>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>>>>>> /* { dg-do compile} */ >>>>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */ >>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds" } */ >>>>>>> >>>>>>> struct trailing_array_1 { >>>>>>> int a; >>>>>>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( >>>>>>> struct trailing_array_4 *trailing_flex) >>>>>>> { >>>>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>>>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ >>>>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>>>>>> index f63206e1948..2b5a895c598 100644 >>>>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>>>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>>>>>> @@ -1,6 +1,6 @@ >>>>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>>>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>>>>>> /* { dg-do compile } */ >>>>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */ >>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds" } */ >>>>>>> >>>>>>> struct trailing_array_1 { >>>>>>> int a; >>>>>>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( >>>>>>> struct trailing_array_4 *trailing_flex) >>>>>>> { >>>>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>>>> trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ >>>>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>>>> >>>>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>>>>>> index e3273714e8b..25b903f2615 100644 >>>>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>>>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>>>>>> @@ -1,6 +1,6 @@ >>>>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>>>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>>>>>> /* { dg-do compile } */ >>>>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */ >>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds" } */ >>>>>>> >>>>>>> struct trailing_array_1 { >>>>>>> int a; >>>>>>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( >>>>>>> struct trailing_array_4 *trailing_flex) >>>>>>> { >>>>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>>>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>>>>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ >>>>>>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ >>>>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */ >>>>>>> >>>>>>> } >>>>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>>>>>> index cabaea77dc2..5fc500a19ca 100644 >>>>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>>>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>>>>>> @@ -1,6 +1,6 @@ >>>>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>>>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>>>>>> /* { dg-do compile } */ >>>>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */ >>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds=2" } */ >>>>>>> >>>>>>> struct trailing_array_1 { >>>>>>> int a; >>>>>>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( >>>>>>> struct trailing_array_4 *trailing_flex) >>>>>>> { >>>>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>>>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ >>>>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>>>>>> index 8b7db6e4f39..30bb4ca8832 100644 >>>>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>>>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>>>>>> @@ -1,6 +1,6 @@ >>>>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>>>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>>>>>> /* { dg-do compile } */ >>>>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */ >>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds=2" } */ >>>>>>> >>>>>>> struct trailing_array_1 { >>>>>>> int a; >>>>>>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( >>>>>>> struct trailing_array_4 *trailing_flex) >>>>>>> { >>>>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>>>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>>>> >>>>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>>>>>> index 035bf481396..e847a44516e 100644 >>>>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>>>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>>>>>> @@ -1,6 +1,6 @@ >>>>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>>>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>>>>>> /* { dg-do compile } */ >>>>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */ >>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds=2" } */ >>>>>>> >>>>>>> struct trailing_array_1 { >>>>>>> int a; >>>>>>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( >>>>>>> struct trailing_array_4 *trailing_flex) >>>>>>> { >>>>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>>>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>>>>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ >>>>>>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ >>>>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>>>> >>>>>>> } >>>>>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>>>>>> new file mode 100644 >>>>>>> index 00000000000..2e241f96208 >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>>>>>> @@ -0,0 +1,39 @@ >>>>>>> +/* Test -Wstrict-flex-arrays. */ >>>>>>> +/* { dg-do compile } */ >>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2" } */ >>>>>>> + >>>>>>> +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) >>>>>>> +{ >>>>>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>>>>>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ >>>>>>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ >>>>>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ >>>>>>> + >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>>>>>> new file mode 100644 >>>>>>> index 00000000000..97eb65ba0a9 >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>>>>>> @@ -0,0 +1,39 @@ >>>>>>> +/* Test -Wstrict-flex-arrays. */ >>>>>>> +/* { dg-do compile } */ >>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3" } */ >>>>>>> + >>>>>>> +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) >>>>>>> +{ >>>>>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>>>>>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ >>>>>>> + trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */ >>>>>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */ >>>>>>> + >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>>>>>> new file mode 100644 >>>>>>> index 00000000000..110fdc72778 >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>>>>>> @@ -0,0 +1,39 @@ >>>>>>> +/* Test -Wstrict-flex-arrays. */ >>>>>>> +/* { dg-do compile } */ >>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1" } */ >>>>>>> + >>>>>>> +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) >>>>>>> +{ >>>>>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>>>>>> + trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>>>>>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>>>>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>>>>>> + >>>>>>> +} >>>>>>> diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc >>>>>>> index 3846dc1d849..e6c6c5a301d 100644 >>>>>>> --- a/gcc/tree-vrp.cc >>>>>>> +++ b/gcc/tree-vrp.cc >>>>>>> @@ -1087,7 +1087,7 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p, >>>>>>> if (dump_file && (dump_flags & TDF_DETAILS)) >>>>>>> ranger->dump (dump_file); >>>>>>> >>>>>>> - if (warn_array_bounds && warn_array_bounds_p) >>>>>>> + if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p) >>>>>>> { >>>>>>> // Set all edges as executable, except those ranger says aren't. >>>>>>> int non_exec_flag = ranger->non_executable_edge_flag; >>>>>>> -- >>>>>>> 2.31.1 >>>>>>> >>>>>> >>>>>> >>>>> >>>>> -- >>>>> Richard Biener <rguenther@suse.de> >>>>> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, >>>>> Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; >>>>> HRB 36809 (AG Nuernberg) >>>> >>>> >>> >>> -- >>> Richard Biener <rguenther@suse.de> >>> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, >>> Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; >>> HRB 36809 (AG Nuernberg) >> >> > > -- > Richard Biener <rguenther@suse.de> > SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, > Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; > HRB 36809 (AG Nuernberg)
FYI. Committed this last patch as: https://jira.oci.oraclecorp.com/browse/OLDIS-21095 I will come up with the update to gcc-13/changes.html for -fstrict-flex-arrays very soon. Thanks. Qing > On Dec 16, 2022, at 9:49 AM, Qing Zhao via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > >> On Dec 16, 2022, at 4:17 AM, Richard Biener <rguenther@suse.de> wrote: >> >> On Thu, 15 Dec 2022, Qing Zhao wrote: >> >>> >>> >>>> On Dec 15, 2022, at 2:47 AM, Richard Biener <rguenther@suse.de> wrote: >>>> >>>> On Wed, 14 Dec 2022, Qing Zhao wrote: >>>> >>>>> Hi, Richard, >>>>> >>>>> I guess that we now agreed on the following: >>>>> >>>>> “ the information that we ran into a trailing array but didn't consider >>>>> it a flex array because of -fstrict-flex-arrays is always a useful information” >>>>> >>>>> The only thing we didn’t decide is: >>>>> >>>>> A. Amend such new information to -Warray-bounds when -fstrict-flex-arrays=N (N>0) specified. >>>>> >>>>> OR >>>>> >>>>> B. Issue such new information with a new warning option -Wstrict-flex-arrays when -fstrict-flex-arrays=N (N>0) specified. >>>>> >>>>> My current patch implemented B. >>>> >>>> Plus it implements it to specify a different flex-array variant for >>>> the extra diagnostic. >>> Could you clarify a little bit on this? (Don’t quite understand…) >>>> >>>>> If you think A is better, I will change the patch as A. >>>> >>>> I would tend to A since, as I said, it's useful information that >>>> shouldn't be hidden and not adding an option removes odd combination >>>> possibilities such as -Wno-array-bounds -Wstrict-flex-arrays. >>> >>> With current implementation, the above combination will ONLY report the >>> misuse of trailing array as flex-array. No out-of-bounds warnings >>> issued. >>> >>>> In particular I find, say, -fstrict-flex-arrays=2 -Wstrict-flex-arrays=1 >>>> hardly useful. >>> >>> The above combination will NOT happen, because there is NO level argument for -Wstrict-flex-arrays. >>> >>> The only combination will be: -fstrict-flex-arrays=N -Wstrict-flex-arrays >>> >>> When N > 0, -Wstrict-flex-arrays will report any misuse of trailing arrays as flexible array per the value of N. >>>> >>>> But I'm interested in other opinions. >>> >>> Adding a separate -Wstrict-flex-arrays will provide users a choice to ONLY look at the mis-use of trailing arrays as flex-arrays. Without this new option, such information will be buried into tons of out-of-bounds messges. >>> >>> I think this is the major benefit to have one separate new warning -Wstrict-flex-arrays. >>> >>> Do we need to provide the users this choice? >> >> Ah, OK - I can see the value of auditing code this way before >> enabling -fstrict-flex-arrays. > Yes, I think the major benefit of this option is to help users to identify all the places where the trailing arrays are misused as flex-arrays at different level of -fstrict-flex-arrays=N, then update their source code accordingly. And finally can enable -fstrict-flex-arrays by default. >> >>> + if (opts->x_warn_strict_flex_arrays) >>> + if (opts->x_flag_strict_flex_arrays == 0) >>> + { >>> + opts->x_warn_strict_flex_arrays = 0; >>> + warning_at (UNKNOWN_LOCATION, 0, >>> + "%<-Wstrict-flex-arrays%> is ignored when" >>> + " %<-fstrict-flex-arrays%> does not present"); >> >> "is not present”. > Okay. >> >> The patch is OK with that change. > Thanks! Will commit the patch after the change. >> >> Thanks and sorry for the slow process ... > > Thank you for your patience and questions. > The discussion is very helpful since I was not 100% sure whether this new warning is necessary or not in the beginning, but now after this discussion I feel confident that it’s a necessary option to be added. > > Qing > >> >> Richard. >> >>> Thanks. >>> >>> Qing >>>> >>>> Thanks, >>>> Richard. >>>> >>>>> Let me know your opinion. >>>>> >>>>> thanks. >>>>> >>>>> Qing >>>>> >>>>> >>>>>> On Dec 14, 2022, at 4:03 AM, Richard Biener <rguenther@suse.de> wrote: >>>>>> >>>>>> On Tue, 13 Dec 2022, Qing Zhao wrote: >>>>>> >>>>>>> Richard, >>>>>>> >>>>>>> Do you have any decision on this one? >>>>>>> Do we need this warning option For GCC? >>>>>> >>>>>> Looking at the testcases it seems that the diagnostic amends >>>>>> -Warray-bounds diagnostics for trailing but not flexible arrays? >>>>>> Wouldn't it be better to generally diagnose this, so have >>>>>> -Warray-bounds, with -fstrict-flex-arrays, for >>>>>> >>>>>> struct X { int a[1]; }; >>>>>> int foo (struct X *p) >>>>>> { >>>>>> return p->a[1]; >>>>>> } >>>>>> >>>>>> emit >>>>>> >>>>>> warning: array subscript 1 is above array bounds ... >>>>>> note: the trailing array is only a flexible array member with >>>>>> -fno-strict-flex-arrays >>>>>> >>>>>> ? Having -Wstrict-flex-arrays=N and N not agree with the >>>>>> -fstrict-flex-arrays level sounds hardly useful to me but the >>>>>> information that we ran into a trailing array but didn't consider >>>>>> it a flex array because of -fstrict-flex-arrays is always a >>>>>> useful information? >>>>>> >>>>>> But maybe I misunderstood this new diagnostic? >>>>>> >>>>>> Thanks, >>>>>> Richard. >>>>>> >>>>>> >>>>>>> thanks. >>>>>>> >>>>>>> Qing >>>>>>> >>>>>>>> On Dec 6, 2022, at 11:18 AM, Qing Zhao <qing.zhao@oracle.com> wrote: >>>>>>>> >>>>>>>> '-Wstrict-flex-arrays' >>>>>>>> Warn about inproper usages of flexible array members according to >>>>>>>> the LEVEL of the 'strict_flex_array (LEVEL)' attribute attached to >>>>>>>> the trailing array field of a structure if it's available, >>>>>>>> otherwise according to the LEVEL of the option >>>>>>>> '-fstrict-flex-arrays=LEVEL'. >>>>>>>> >>>>>>>> This option is effective only when LEVEL is bigger than 0. >>>>>>>> Otherwise, it will be ignored with a warning. >>>>>>>> >>>>>>>> when LEVEL=1, warnings will be issued for a trailing array >>>>>>>> reference of a structure that have 2 or more elements if the >>>>>>>> trailing array is referenced as a flexible array member. >>>>>>>> >>>>>>>> when LEVEL=2, in addition to LEVEL=1, additional warnings will be >>>>>>>> issued for a trailing one-element array reference of a structure if >>>>>>>> the array is referenced as a flexible array member. >>>>>>>> >>>>>>>> when LEVEL=3, in addition to LEVEL=2, additional warnings will be >>>>>>>> issued for a trailing zero-length array reference of a structure if >>>>>>>> the array is referenced as a flexible array member. >>>>>>>> >>>>>>>> gcc/ChangeLog: >>>>>>>> >>>>>>>> * doc/invoke.texi: Document -Wstrict-flex-arrays option. >>>>>>>> * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Add two more >>>>>>>> arguments. >>>>>>>> (array_bounds_checker::check_array_ref): Issue warnings for >>>>>>>> -Wstrict-flex-arrays. >>>>>>>> * opts.cc (finish_options): Issue warning for unsupported combination >>>>>>>> of -Wstrict_flex_arrays and -fstrict-flex-array. >>>>>>>> * tree-vrp.cc (execute_ranger_vrp): Enable the pass when >>>>>>>> warn_strict_flex_array is true. >>>>>>>> >>>>>>>> gcc/c-family/ChangeLog: >>>>>>>> >>>>>>>> * c.opt (Wstrict-flex-arrays): New option. >>>>>>>> >>>>>>>> gcc/testsuite/ChangeLog: >>>>>>>> >>>>>>>> * gcc.dg/Warray-bounds-flex-arrays-1.c: Update testing case with >>>>>>>> -Wstrict-flex-arrays. >>>>>>>> * gcc.dg/Warray-bounds-flex-arrays-2.c: Likewise. >>>>>>>> * gcc.dg/Warray-bounds-flex-arrays-3.c: Likewise. >>>>>>>> * gcc.dg/Warray-bounds-flex-arrays-4.c: Likewise. >>>>>>>> * gcc.dg/Warray-bounds-flex-arrays-5.c: Likewise. >>>>>>>> * gcc.dg/Warray-bounds-flex-arrays-6.c: Likewise. >>>>>>>> * c-c++-common/Wstrict-flex-arrays.c: New test. >>>>>>>> * gcc.dg/Wstrict-flex-arrays-2.c: New test. >>>>>>>> * gcc.dg/Wstrict-flex-arrays-3.c: New test. >>>>>>>> * gcc.dg/Wstrict-flex-arrays.c: New test. >>>>>>>> --- >>>>>>>> gcc/c-family/c.opt | 5 + >>>>>>>> gcc/doc/invoke.texi | 27 ++++- >>>>>>>> gcc/gimple-array-bounds.cc | 103 ++++++++++++++---- >>>>>>>> gcc/opts.cc | 8 ++ >>>>>>>> .../c-c++-common/Wstrict-flex-arrays.c | 9 ++ >>>>>>>> .../gcc.dg/Warray-bounds-flex-arrays-1.c | 5 +- >>>>>>>> .../gcc.dg/Warray-bounds-flex-arrays-2.c | 6 +- >>>>>>>> .../gcc.dg/Warray-bounds-flex-arrays-3.c | 7 +- >>>>>>>> .../gcc.dg/Warray-bounds-flex-arrays-4.c | 5 +- >>>>>>>> .../gcc.dg/Warray-bounds-flex-arrays-5.c | 6 +- >>>>>>>> .../gcc.dg/Warray-bounds-flex-arrays-6.c | 7 +- >>>>>>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c | 39 +++++++ >>>>>>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c | 39 +++++++ >>>>>>>> gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c | 39 +++++++ >>>>>>>> gcc/tree-vrp.cc | 2 +- >>>>>>>> 15 files changed, 273 insertions(+), 34 deletions(-) >>>>>>>> create mode 100644 gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>>>>>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>>>>>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>>>>>>> create mode 100644 gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>>>>>>> >>>>>>>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt >>>>>>>> index 0d0ad0a6374..33edeefd285 100644 >>>>>>>> --- a/gcc/c-family/c.opt >>>>>>>> +++ b/gcc/c-family/c.opt >>>>>>>> @@ -976,6 +976,11 @@ Wstringop-truncation >>>>>>>> C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ LTO ObjC++, Wall) >>>>>>>> Warn about truncation in string manipulation functions like strncat and strncpy. >>>>>>>> >>>>>>>> +Wstrict-flex-arrays >>>>>>>> +C C++ Var(warn_strict_flex_arrays) Warning >>>>>>>> +Warn about inproper usages of flexible array members >>>>>>>> +according to the level of -fstrict-flex-arrays. >>>>>>>> + >>>>>>>> Wsuggest-attribute=format >>>>>>>> C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning >>>>>>>> Warn about functions which might be candidates for format attributes. >>>>>>>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi >>>>>>>> index 726392409b6..4402b0427ef 100644 >>>>>>>> --- a/gcc/doc/invoke.texi >>>>>>>> +++ b/gcc/doc/invoke.texi >>>>>>>> @@ -398,7 +398,7 @@ Objective-C and Objective-C++ Dialects}. >>>>>>>> -Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol >>>>>>>> -Wstring-compare @gol >>>>>>>> -Wno-stringop-overflow -Wno-stringop-overread @gol >>>>>>>> --Wno-stringop-truncation @gol >>>>>>>> +-Wno-stringop-truncation -Wstrict-flex-arrays @gol >>>>>>>> -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol >>>>>>>> -Wswitch -Wno-switch-bool -Wswitch-default -Wswitch-enum @gol >>>>>>>> -Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand @gol >>>>>>>> @@ -7835,6 +7835,31 @@ however, are not suitable arguments to functions that expect >>>>>>>> such arrays GCC issues warnings unless it can prove that the use is >>>>>>>> safe. @xref{Common Variable Attributes}. >>>>>>>> >>>>>>>> +@item -Wstrict-flex-arrays >>>>>>>> +@opindex Wstrict-flex-arrays >>>>>>>> +@opindex Wno-strict-flex-arrays >>>>>>>> +Warn about inproper usages of flexible array members >>>>>>>> +according to the @var{level} of the @code{strict_flex_array (@var{level})} >>>>>>>> +attribute attached to the trailing array field of a structure if it's >>>>>>>> +available, otherwise according to the @var{level} of the option >>>>>>>> +@option{-fstrict-flex-arrays=@var{level}}. >>>>>>>> + >>>>>>>> +This option is effective only when @var{level} is bigger than 0. Otherwise, >>>>>>>> +it will be ignored with a warning. >>>>>>>> + >>>>>>>> +when @var{level}=1, warnings will be issued for a trailing array reference >>>>>>>> +of a structure that have 2 or more elements if the trailing array is referenced >>>>>>>> +as a flexible array member. >>>>>>>> + >>>>>>>> +when @var{level}=2, in addition to @var{level}=1, additional warnings will be >>>>>>>> +issued for a trailing one-element array reference of a structure >>>>>>>> +if the array is referenced as a flexible array member. >>>>>>>> + >>>>>>>> +when @var{level}=3, in addition to @var{level}=2, additional warnings will be >>>>>>>> +issued for a trailing zero-length array reference of a structure >>>>>>>> +if the array is referenced as a flexible array member. >>>>>>>> + >>>>>>>> + >>>>>>>> @item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]} >>>>>>>> @opindex Wsuggest-attribute= >>>>>>>> @opindex Wno-suggest-attribute= >>>>>>>> diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc >>>>>>>> index db3459af325..825f11331b5 100644 >>>>>>>> --- a/gcc/gimple-array-bounds.cc >>>>>>>> +++ b/gcc/gimple-array-bounds.cc >>>>>>>> @@ -252,25 +252,34 @@ get_up_bounds_for_array_ref (tree ref, tree *decl, >>>>>>>> >>>>>>>> /* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND >>>>>>>> and UP_BOUND_P1, check whether the array reference REF is out of bound. >>>>>>>> - Issue warnings if out of bound, return TRUE if warnings are issued. */ >>>>>>>> + When out of bounds, set OUT_OF_BOUND to true. >>>>>>>> + Issue warnings if FOR_ARRAY_BOUND is true. >>>>>>>> + return TRUE if warnings are issued. */ >>>>>>>> + >>>>>>>> >>>>>>>> static bool >>>>>>>> check_out_of_bounds_and_warn (location_t location, tree ref, >>>>>>>> tree low_sub_org, tree low_sub, tree up_sub, >>>>>>>> tree up_bound, tree up_bound_p1, >>>>>>>> const value_range *vr, >>>>>>>> - bool ignore_off_by_one) >>>>>>>> + bool ignore_off_by_one, bool for_array_bound, >>>>>>>> + bool *out_of_bound) >>>>>>>> { >>>>>>>> tree low_bound = array_ref_low_bound (ref); >>>>>>>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); >>>>>>>> >>>>>>>> bool warned = false; >>>>>>>> + *out_of_bound = false; >>>>>>>> >>>>>>>> /* Empty array. */ >>>>>>>> if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1)) >>>>>>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>>>>>> - "array subscript %E is outside array bounds of %qT", >>>>>>>> - low_sub_org, artype); >>>>>>>> + { >>>>>>>> + *out_of_bound = true; >>>>>>>> + if (for_array_bound) >>>>>>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>>>>>> + "array subscript %E is outside array" >>>>>>>> + " bounds of %qT", low_sub_org, artype); >>>>>>>> + } >>>>>>>> >>>>>>>> if (warned) >>>>>>>> ; /* Do nothing. */ >>>>>>>> @@ -283,24 +292,33 @@ check_out_of_bounds_and_warn (location_t location, tree ref, >>>>>>>> : tree_int_cst_le (up_bound, up_sub)) >>>>>>>> && TREE_CODE (low_sub) == INTEGER_CST >>>>>>>> && tree_int_cst_le (low_sub, low_bound)) >>>>>>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>>>>>> - "array subscript [%E, %E] is outside " >>>>>>>> - "array bounds of %qT", >>>>>>>> - low_sub, up_sub, artype); >>>>>>>> + { >>>>>>>> + *out_of_bound = true; >>>>>>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>>>>>> + "array subscript [%E, %E] is outside " >>>>>>>> + "array bounds of %qT", >>>>>>>> + low_sub, up_sub, artype); >>>>>>>> + } >>>>>>>> } >>>>>>>> else if (up_bound >>>>>>>> && TREE_CODE (up_sub) == INTEGER_CST >>>>>>>> && (ignore_off_by_one >>>>>>>> ? !tree_int_cst_le (up_sub, up_bound_p1) >>>>>>>> : !tree_int_cst_le (up_sub, up_bound))) >>>>>>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>>>>>> - "array subscript %E is above array bounds of %qT", >>>>>>>> - up_sub, artype); >>>>>>>> + { >>>>>>>> + *out_of_bound = true; >>>>>>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>>>>>> + "array subscript %E is above array bounds of %qT", >>>>>>>> + up_sub, artype); >>>>>>>> + } >>>>>>>> else if (TREE_CODE (low_sub) == INTEGER_CST >>>>>>>> && tree_int_cst_lt (low_sub, low_bound)) >>>>>>>> - warned = warning_at (location, OPT_Warray_bounds_, >>>>>>>> - "array subscript %E is below array bounds of %qT", >>>>>>>> - low_sub, artype); >>>>>>>> + { >>>>>>>> + *out_of_bound = true; >>>>>>>> + warned = warning_at (location, OPT_Warray_bounds_, >>>>>>>> + "array subscript %E is below array bounds of %qT", >>>>>>>> + low_sub, artype); >>>>>>>> + } >>>>>>>> return warned; >>>>>>>> } >>>>>>>> >>>>>>>> @@ -333,14 +351,21 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>>>>>>> >>>>>>>> tree arg = TREE_OPERAND (ref, 0); >>>>>>>> const bool compref = TREE_CODE (arg) == COMPONENT_REF; >>>>>>>> + unsigned int strict_flex_array_level = flag_strict_flex_arrays; >>>>>>>> >>>>>>>> if (compref) >>>>>>>> - /* Try to determine special array member type for this COMPONENT_REF. */ >>>>>>>> - sam = component_ref_sam_type (arg); >>>>>>>> + { >>>>>>>> + /* Try to determine special array member type for this COMPONENT_REF. */ >>>>>>>> + sam = component_ref_sam_type (arg); >>>>>>>> + /* Get the level of strict_flex_array for this array field. */ >>>>>>>> + tree afield_decl = TREE_OPERAND (arg, 1); >>>>>>>> + strict_flex_array_level = strict_flex_array_level_of (afield_decl); >>>>>>>> + } >>>>>>>> >>>>>>>> get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); >>>>>>>> >>>>>>>> bool warned = false; >>>>>>>> + bool out_of_bound = false; >>>>>>>> >>>>>>>> tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); >>>>>>>> tree low_sub_org = TREE_OPERAND (ref, 1); >>>>>>>> @@ -361,7 +386,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>>>>>>> warned = check_out_of_bounds_and_warn (location, ref, >>>>>>>> low_sub_org, low_sub, up_sub, >>>>>>>> up_bound, up_bound_p1, vr, >>>>>>>> - ignore_off_by_one); >>>>>>>> + ignore_off_by_one, warn_array_bounds, >>>>>>>> + &out_of_bound); >>>>>>>> >>>>>>>> >>>>>>>> if (!warned && sam == special_array_member::int_0) >>>>>>>> @@ -373,19 +399,56 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, >>>>>>>> "of an interior zero-length array %qT")), >>>>>>>> low_sub, artype); >>>>>>>> >>>>>>>> - if (warned) >>>>>>>> + if (warned || out_of_bound) >>>>>>>> { >>>>>>>> - if (dump_file && (dump_flags & TDF_DETAILS)) >>>>>>>> + if (warned && dump_file && (dump_flags & TDF_DETAILS)) >>>>>>>> { >>>>>>>> fprintf (dump_file, "Array bound warning for "); >>>>>>>> dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); >>>>>>>> fprintf (dump_file, "\n"); >>>>>>>> } >>>>>>>> >>>>>>>> + /* issue warnings for -Wstrict-flex-arrays according to the level of >>>>>>>> + flag_strict_flex_arrays. */ >>>>>>>> + if (out_of_bound && warn_strict_flex_arrays) >>>>>>>> + switch (strict_flex_array_level) >>>>>>>> + { >>>>>>>> + case 3: >>>>>>>> + /* Issue additional warnings for trailing arrays [0]. */ >>>>>>>> + if (sam == special_array_member::trail_0) >>>>>>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>>>>>>> + "trailing array %qT should not be used as " >>>>>>>> + "a flexible array member for level 3", >>>>>>>> + artype); >>>>>>>> + /* FALLTHROUGH. */ >>>>>>>> + case 2: >>>>>>>> + /* Issue additional warnings for trailing arrays [1]. */ >>>>>>>> + if (sam == special_array_member::trail_1) >>>>>>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>>>>>>> + "trailing array %qT should not be used as " >>>>>>>> + "a flexible array member for level 2 and " >>>>>>>> + "above", artype); >>>>>>>> + /* FALLTHROUGH. */ >>>>>>>> + case 1: >>>>>>>> + /* Issue warnings for trailing arrays [n]. */ >>>>>>>> + if (sam == special_array_member::trail_n) >>>>>>>> + warned = warning_at (location, OPT_Wstrict_flex_arrays, >>>>>>>> + "trailing array %qT should not be used as " >>>>>>>> + "a flexible array member for level 1 and " >>>>>>>> + "above", artype); >>>>>>>> + break; >>>>>>>> + case 0: >>>>>>>> + /* Do nothing. */ >>>>>>>> + break; >>>>>>>> + default: >>>>>>>> + gcc_unreachable (); >>>>>>>> + } >>>>>>>> + >>>>>>>> /* Avoid more warnings when checking more significant subscripts >>>>>>>> of the same expression. */ >>>>>>>> ref = TREE_OPERAND (ref, 0); >>>>>>>> suppress_warning (ref, OPT_Warray_bounds_); >>>>>>>> + suppress_warning (ref, OPT_Wstrict_flex_arrays); >>>>>>>> >>>>>>>> if (decl) >>>>>>>> ref = decl; >>>>>>>> diff --git a/gcc/opts.cc b/gcc/opts.cc >>>>>>>> index 73fc97756e4..8db53ad6c77 100644 >>>>>>>> --- a/gcc/opts.cc >>>>>>>> +++ b/gcc/opts.cc >>>>>>>> @@ -1411,6 +1411,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, >>>>>>>> opts->x_profile_flag = 0; >>>>>>>> } >>>>>>>> >>>>>>>> + if (opts->x_warn_strict_flex_arrays) >>>>>>>> + if (opts->x_flag_strict_flex_arrays == 0) >>>>>>>> + { >>>>>>>> + opts->x_warn_strict_flex_arrays = 0; >>>>>>>> + warning_at (UNKNOWN_LOCATION, 0, >>>>>>>> + "%<-Wstrict-flex-arrays%> is ignored when" >>>>>>>> + " %<-fstrict-flex-arrays%> does not present"); >>>>>>>> + } >>>>>>>> >>>>>>>> diagnose_options (opts, opts_set, loc); >>>>>>>> } >>>>>>>> diff --git a/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>>>>>>> new file mode 100644 >>>>>>>> index 00000000000..72b4b7c6406 >>>>>>>> --- /dev/null >>>>>>>> +++ b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c >>>>>>>> @@ -0,0 +1,9 @@ >>>>>>>> +/* Test the usage of option -Wstrict-flex-arrays. */ >>>>>>>> +/* { dg-do compile } */ >>>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays" } */ >>>>>>>> + >>>>>>>> +int main(int argc, char *argv[]) >>>>>>>> +{ >>>>>>>> + return 0; >>>>>>>> +} >>>>>>>> +/* { dg-warning "is ignored when \'-fstrict-flex-arrays\' does not present" "" { target *-*-* } 0 } */ >>>>>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>>>>>>> index d36ba4d86cb..65c9fec43af 100644 >>>>>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>>>>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c >>>>>>>> @@ -1,6 +1,6 @@ >>>>>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>>>>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>>>>>>> /* { dg-do compile} */ >>>>>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */ >>>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds" } */ >>>>>>>> >>>>>>>> struct trailing_array_1 { >>>>>>>> int a; >>>>>>>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( >>>>>>>> struct trailing_array_4 *trailing_flex) >>>>>>>> { >>>>>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>>>>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ >>>>>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>>>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>>>>>>> index f63206e1948..2b5a895c598 100644 >>>>>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>>>>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c >>>>>>>> @@ -1,6 +1,6 @@ >>>>>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>>>>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>>>>>>> /* { dg-do compile } */ >>>>>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */ >>>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds" } */ >>>>>>>> >>>>>>>> struct trailing_array_1 { >>>>>>>> int a; >>>>>>>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( >>>>>>>> struct trailing_array_4 *trailing_flex) >>>>>>>> { >>>>>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>>>>> trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ >>>>>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>>>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>>>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>>>>> >>>>>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>>>>>>> index e3273714e8b..25b903f2615 100644 >>>>>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>>>>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c >>>>>>>> @@ -1,6 +1,6 @@ >>>>>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds. */ >>>>>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ >>>>>>>> /* { dg-do compile } */ >>>>>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */ >>>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds" } */ >>>>>>>> >>>>>>>> struct trailing_array_1 { >>>>>>>> int a; >>>>>>>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( >>>>>>>> struct trailing_array_4 *trailing_flex) >>>>>>>> { >>>>>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>>>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>>>>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>>>>>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ >>>>>>>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ >>>>>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */ >>>>>>>> >>>>>>>> } >>>>>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>>>>>>> index cabaea77dc2..5fc500a19ca 100644 >>>>>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>>>>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c >>>>>>>> @@ -1,6 +1,6 @@ >>>>>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>>>>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>>>>>>> /* { dg-do compile } */ >>>>>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */ >>>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds=2" } */ >>>>>>>> >>>>>>>> struct trailing_array_1 { >>>>>>>> int a; >>>>>>>> @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( >>>>>>>> struct trailing_array_4 *trailing_flex) >>>>>>>> { >>>>>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>>>>> trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ >>>>>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>>>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>>>>>>> index 8b7db6e4f39..30bb4ca8832 100644 >>>>>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>>>>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c >>>>>>>> @@ -1,6 +1,6 @@ >>>>>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>>>>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>>>>>>> /* { dg-do compile } */ >>>>>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */ >>>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds=2" } */ >>>>>>>> >>>>>>>> struct trailing_array_1 { >>>>>>>> int a; >>>>>>>> @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( >>>>>>>> struct trailing_array_4 *trailing_flex) >>>>>>>> { >>>>>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>>>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>>>>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>>>>>> trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ >>>>>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>>>>> >>>>>>>> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>>>>>>> index 035bf481396..e847a44516e 100644 >>>>>>>> --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>>>>>>> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c >>>>>>>> @@ -1,6 +1,6 @@ >>>>>>>> -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ >>>>>>>> +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ >>>>>>>> /* { dg-do compile } */ >>>>>>>> -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */ >>>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds=2" } */ >>>>>>>> >>>>>>>> struct trailing_array_1 { >>>>>>>> int a; >>>>>>>> @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( >>>>>>>> struct trailing_array_4 *trailing_flex) >>>>>>>> { >>>>>>>> normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ >>>>>>>> + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ >>>>>>>> trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ >>>>>>>> + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ >>>>>>>> trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ >>>>>>>> + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ >>>>>>>> trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ >>>>>>>> >>>>>>>> } >>>>>>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>>>>>>> new file mode 100644 >>>>>>>> index 00000000000..2e241f96208 >>>>>>>> --- /dev/null >>>>>>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c >>>>>>>> @@ -0,0 +1,39 @@ >>>>>>>> +/* Test -Wstrict-flex-arrays. */ >>>>>>>> +/* { dg-do compile } */ >>>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2" } */ >>>>>>>> + >>>>>>>> +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) >>>>>>>> +{ >>>>>>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>>>>>>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ >>>>>>>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ >>>>>>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ >>>>>>>> + >>>>>>>> +} >>>>>>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>>>>>>> new file mode 100644 >>>>>>>> index 00000000000..97eb65ba0a9 >>>>>>>> --- /dev/null >>>>>>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c >>>>>>>> @@ -0,0 +1,39 @@ >>>>>>>> +/* Test -Wstrict-flex-arrays. */ >>>>>>>> +/* { dg-do compile } */ >>>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3" } */ >>>>>>>> + >>>>>>>> +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) >>>>>>>> +{ >>>>>>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>>>>>>> + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ >>>>>>>> + trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */ >>>>>>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */ >>>>>>>> + >>>>>>>> +} >>>>>>>> diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>>>>>>> new file mode 100644 >>>>>>>> index 00000000000..110fdc72778 >>>>>>>> --- /dev/null >>>>>>>> +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c >>>>>>>> @@ -0,0 +1,39 @@ >>>>>>>> +/* Test -Wstrict-flex-arrays. */ >>>>>>>> +/* { dg-do compile } */ >>>>>>>> +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1" } */ >>>>>>>> + >>>>>>>> +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) >>>>>>>> +{ >>>>>>>> + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ >>>>>>>> + trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>>>>>>> + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>>>>>>> + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ >>>>>>>> + >>>>>>>> +} >>>>>>>> diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc >>>>>>>> index 3846dc1d849..e6c6c5a301d 100644 >>>>>>>> --- a/gcc/tree-vrp.cc >>>>>>>> +++ b/gcc/tree-vrp.cc >>>>>>>> @@ -1087,7 +1087,7 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p, >>>>>>>> if (dump_file && (dump_flags & TDF_DETAILS)) >>>>>>>> ranger->dump (dump_file); >>>>>>>> >>>>>>>> - if (warn_array_bounds && warn_array_bounds_p) >>>>>>>> + if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p) >>>>>>>> { >>>>>>>> // Set all edges as executable, except those ranger says aren't. >>>>>>>> int non_exec_flag = ranger->non_executable_edge_flag; >>>>>>>> -- >>>>>>>> 2.31.1 >>>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> Richard Biener <rguenther@suse.de> >>>>>> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, >>>>>> Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; >>>>>> HRB 36809 (AG Nuernberg) >>>>> >>>>> >>>> >>>> -- >>>> Richard Biener <rguenther@suse.de> >>>> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, >>>> Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; >>>> HRB 36809 (AG Nuernberg) >>> >>> >> >> -- >> Richard Biener <rguenther@suse.de> >> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, >> Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; >> HRB 36809 (AG Nuernberg)
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 0d0ad0a6374..33edeefd285 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -976,6 +976,11 @@ Wstringop-truncation C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ LTO ObjC++, Wall) Warn about truncation in string manipulation functions like strncat and strncpy. +Wstrict-flex-arrays +C C++ Var(warn_strict_flex_arrays) Warning +Warn about inproper usages of flexible array members +according to the level of -fstrict-flex-arrays. + Wsuggest-attribute=format C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning Warn about functions which might be candidates for format attributes. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 726392409b6..4402b0427ef 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -398,7 +398,7 @@ Objective-C and Objective-C++ Dialects}. -Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol -Wstring-compare @gol -Wno-stringop-overflow -Wno-stringop-overread @gol --Wno-stringop-truncation @gol +-Wno-stringop-truncation -Wstrict-flex-arrays @gol -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol -Wswitch -Wno-switch-bool -Wswitch-default -Wswitch-enum @gol -Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand @gol @@ -7835,6 +7835,31 @@ however, are not suitable arguments to functions that expect such arrays GCC issues warnings unless it can prove that the use is safe. @xref{Common Variable Attributes}. +@item -Wstrict-flex-arrays +@opindex Wstrict-flex-arrays +@opindex Wno-strict-flex-arrays +Warn about inproper usages of flexible array members +according to the @var{level} of the @code{strict_flex_array (@var{level})} +attribute attached to the trailing array field of a structure if it's +available, otherwise according to the @var{level} of the option +@option{-fstrict-flex-arrays=@var{level}}. + +This option is effective only when @var{level} is bigger than 0. Otherwise, +it will be ignored with a warning. + +when @var{level}=1, warnings will be issued for a trailing array reference +of a structure that have 2 or more elements if the trailing array is referenced +as a flexible array member. + +when @var{level}=2, in addition to @var{level}=1, additional warnings will be +issued for a trailing one-element array reference of a structure +if the array is referenced as a flexible array member. + +when @var{level}=3, in addition to @var{level}=2, additional warnings will be +issued for a trailing zero-length array reference of a structure +if the array is referenced as a flexible array member. + + @item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}cold@r{|}malloc@r{]} @opindex Wsuggest-attribute= @opindex Wno-suggest-attribute= diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc index db3459af325..825f11331b5 100644 --- a/gcc/gimple-array-bounds.cc +++ b/gcc/gimple-array-bounds.cc @@ -252,25 +252,34 @@ get_up_bounds_for_array_ref (tree ref, tree *decl, /* Given the LOW_SUB_ORG, LOW_SUB and UP_SUB, and the computed UP_BOUND and UP_BOUND_P1, check whether the array reference REF is out of bound. - Issue warnings if out of bound, return TRUE if warnings are issued. */ + When out of bounds, set OUT_OF_BOUND to true. + Issue warnings if FOR_ARRAY_BOUND is true. + return TRUE if warnings are issued. */ + static bool check_out_of_bounds_and_warn (location_t location, tree ref, tree low_sub_org, tree low_sub, tree up_sub, tree up_bound, tree up_bound_p1, const value_range *vr, - bool ignore_off_by_one) + bool ignore_off_by_one, bool for_array_bound, + bool *out_of_bound) { tree low_bound = array_ref_low_bound (ref); tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); bool warned = false; + *out_of_bound = false; /* Empty array. */ if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1)) - warned = warning_at (location, OPT_Warray_bounds_, - "array subscript %E is outside array bounds of %qT", - low_sub_org, artype); + { + *out_of_bound = true; + if (for_array_bound) + warned = warning_at (location, OPT_Warray_bounds_, + "array subscript %E is outside array" + " bounds of %qT", low_sub_org, artype); + } if (warned) ; /* Do nothing. */ @@ -283,24 +292,33 @@ check_out_of_bounds_and_warn (location_t location, tree ref, : tree_int_cst_le (up_bound, up_sub)) && TREE_CODE (low_sub) == INTEGER_CST && tree_int_cst_le (low_sub, low_bound)) - warned = warning_at (location, OPT_Warray_bounds_, - "array subscript [%E, %E] is outside " - "array bounds of %qT", - low_sub, up_sub, artype); + { + *out_of_bound = true; + warned = warning_at (location, OPT_Warray_bounds_, + "array subscript [%E, %E] is outside " + "array bounds of %qT", + low_sub, up_sub, artype); + } } else if (up_bound && TREE_CODE (up_sub) == INTEGER_CST && (ignore_off_by_one ? !tree_int_cst_le (up_sub, up_bound_p1) : !tree_int_cst_le (up_sub, up_bound))) - warned = warning_at (location, OPT_Warray_bounds_, - "array subscript %E is above array bounds of %qT", - up_sub, artype); + { + *out_of_bound = true; + warned = warning_at (location, OPT_Warray_bounds_, + "array subscript %E is above array bounds of %qT", + up_sub, artype); + } else if (TREE_CODE (low_sub) == INTEGER_CST && tree_int_cst_lt (low_sub, low_bound)) - warned = warning_at (location, OPT_Warray_bounds_, - "array subscript %E is below array bounds of %qT", - low_sub, artype); + { + *out_of_bound = true; + warned = warning_at (location, OPT_Warray_bounds_, + "array subscript %E is below array bounds of %qT", + low_sub, artype); + } return warned; } @@ -333,14 +351,21 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, tree arg = TREE_OPERAND (ref, 0); const bool compref = TREE_CODE (arg) == COMPONENT_REF; + unsigned int strict_flex_array_level = flag_strict_flex_arrays; if (compref) - /* Try to determine special array member type for this COMPONENT_REF. */ - sam = component_ref_sam_type (arg); + { + /* Try to determine special array member type for this COMPONENT_REF. */ + sam = component_ref_sam_type (arg); + /* Get the level of strict_flex_array for this array field. */ + tree afield_decl = TREE_OPERAND (arg, 1); + strict_flex_array_level = strict_flex_array_level_of (afield_decl); + } get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); bool warned = false; + bool out_of_bound = false; tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); tree low_sub_org = TREE_OPERAND (ref, 1); @@ -361,7 +386,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, warned = check_out_of_bounds_and_warn (location, ref, low_sub_org, low_sub, up_sub, up_bound, up_bound_p1, vr, - ignore_off_by_one); + ignore_off_by_one, warn_array_bounds, + &out_of_bound); if (!warned && sam == special_array_member::int_0) @@ -373,19 +399,56 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, "of an interior zero-length array %qT")), low_sub, artype); - if (warned) + if (warned || out_of_bound) { - if (dump_file && (dump_flags & TDF_DETAILS)) + if (warned && dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Array bound warning for "); dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); fprintf (dump_file, "\n"); } + /* issue warnings for -Wstrict-flex-arrays according to the level of + flag_strict_flex_arrays. */ + if (out_of_bound && warn_strict_flex_arrays) + switch (strict_flex_array_level) + { + case 3: + /* Issue additional warnings for trailing arrays [0]. */ + if (sam == special_array_member::trail_0) + warned = warning_at (location, OPT_Wstrict_flex_arrays, + "trailing array %qT should not be used as " + "a flexible array member for level 3", + artype); + /* FALLTHROUGH. */ + case 2: + /* Issue additional warnings for trailing arrays [1]. */ + if (sam == special_array_member::trail_1) + warned = warning_at (location, OPT_Wstrict_flex_arrays, + "trailing array %qT should not be used as " + "a flexible array member for level 2 and " + "above", artype); + /* FALLTHROUGH. */ + case 1: + /* Issue warnings for trailing arrays [n]. */ + if (sam == special_array_member::trail_n) + warned = warning_at (location, OPT_Wstrict_flex_arrays, + "trailing array %qT should not be used as " + "a flexible array member for level 1 and " + "above", artype); + break; + case 0: + /* Do nothing. */ + break; + default: + gcc_unreachable (); + } + /* Avoid more warnings when checking more significant subscripts of the same expression. */ ref = TREE_OPERAND (ref, 0); suppress_warning (ref, OPT_Warray_bounds_); + suppress_warning (ref, OPT_Wstrict_flex_arrays); if (decl) ref = decl; diff --git a/gcc/opts.cc b/gcc/opts.cc index 73fc97756e4..8db53ad6c77 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -1411,6 +1411,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, opts->x_profile_flag = 0; } + if (opts->x_warn_strict_flex_arrays) + if (opts->x_flag_strict_flex_arrays == 0) + { + opts->x_warn_strict_flex_arrays = 0; + warning_at (UNKNOWN_LOCATION, 0, + "%<-Wstrict-flex-arrays%> is ignored when" + " %<-fstrict-flex-arrays%> does not present"); + } diagnose_options (opts, opts_set, loc); } diff --git a/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c new file mode 100644 index 00000000000..72b4b7c6406 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wstrict-flex-arrays.c @@ -0,0 +1,9 @@ +/* Test the usage of option -Wstrict-flex-arrays. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wstrict-flex-arrays" } */ + +int main(int argc, char *argv[]) +{ + return 0; +} +/* { dg-warning "is ignored when \'-fstrict-flex-arrays\' does not present" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c index d36ba4d86cb..65c9fec43af 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c @@ -1,6 +1,6 @@ -/* Test -fstrict-flex-arrays + -Warray-bounds. */ +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ /* { dg-do compile} */ -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */ +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds" } */ struct trailing_array_1 { int a; @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_4 *trailing_flex) { normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c index f63206e1948..2b5a895c598 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c @@ -1,6 +1,6 @@ -/* Test -fstrict-flex-arrays + -Warray-bounds. */ +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ /* { dg-do compile } */ -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */ +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds" } */ struct trailing_array_1 { int a; @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_4 *trailing_flex) { normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c index e3273714e8b..25b903f2615 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c @@ -1,6 +1,6 @@ -/* Test -fstrict-flex-arrays + -Warray-bounds. */ +/* Test -fstrict-flex-arrays + -Warray-bounds + -Wstrict-flex-arrays. */ /* { dg-do compile } */ -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */ +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds" } */ struct trailing_array_1 { int a; @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_4 *trailing_flex) { normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript" } */ } diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c index cabaea77dc2..5fc500a19ca 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c @@ -1,6 +1,6 @@ -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ /* { dg-do compile } */ -/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=2" } */ +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1 -Warray-bounds=2" } */ struct trailing_array_1 { int a; @@ -32,6 +32,7 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_4 *trailing_flex) { normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ trailing_1->c[2] = 2; /* { dg-bogus "array subscript " } */ trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c index 8b7db6e4f39..30bb4ca8832 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c @@ -1,6 +1,6 @@ -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ /* { dg-do compile } */ -/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=2" } */ +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2 -Warray-bounds=2" } */ struct trailing_array_1 { int a; @@ -32,7 +32,9 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_4 *trailing_flex) { normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ trailing_0->c[1] = 1; /* { dg-bogus "array subscript " } */ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c index 035bf481396..e847a44516e 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c @@ -1,6 +1,6 @@ -/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ +/* Test -fstrict-flex-arrays + -Warray-bounds=2 + -Wstrict-flex-arrays. */ /* { dg-do compile } */ -/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=2" } */ +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3 -Warray-bounds=2" } */ struct trailing_array_1 { int a; @@ -32,8 +32,11 @@ void __attribute__((__noinline__)) stuff( struct trailing_array_4 *trailing_flex) { normal->c[5] = 5; /*{ dg-warning "array subscript 5 is above array bounds of" } */ + /*{ dg-warning "should not be used as a flexible array member for level 1 and above" "" { target *-*-* } .-1 } */ trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ + /* { dg-warning "should not be used as a flexible array member for level 2 and above" "" { target *-*-* } .-1 } */ trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ + /* { dg-warning "should not be used as a flexible array member for level 3" "" { target *-*-* } .-1 } */ trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ } diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c new file mode 100644 index 00000000000..2e241f96208 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-2.c @@ -0,0 +1,39 @@ +/* Test -Wstrict-flex-arrays. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=2" } */ + +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) +{ + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 2 and above" } */ + +} diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c new file mode 100644 index 00000000000..97eb65ba0a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays-3.c @@ -0,0 +1,39 @@ +/* Test -Wstrict-flex-arrays. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=3" } */ + +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) +{ + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ + trailing_1->c[2] = 2; /* { dg-warning "should not be used as a flexible array member for level 2 and above" } */ + trailing_0->c[1] = 1; /* { dg-warning "should not be used as a flexible array member for level 3" } */ + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 3" } */ + +} diff --git a/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c new file mode 100644 index 00000000000..110fdc72778 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstrict-flex-arrays.c @@ -0,0 +1,39 @@ +/* Test -Wstrict-flex-arrays. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wstrict-flex-arrays -fstrict-flex-arrays=1" } */ + +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) +{ + normal->c[5] = 5; /*{ dg-warning "should not be used as a flexible array member for level 1 and above" } */ + trailing_1->c[2] = 2; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ + trailing_0->c[1] = 1; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ + trailing_flex->c[10] = 10; /* { dg-bogus "should not be used as a flexible array member for level 1 and above" } */ + +} diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc index 3846dc1d849..e6c6c5a301d 100644 --- a/gcc/tree-vrp.cc +++ b/gcc/tree-vrp.cc @@ -1087,7 +1087,7 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p, if (dump_file && (dump_flags & TDF_DETAILS)) ranger->dump (dump_file); - if (warn_array_bounds && warn_array_bounds_p) + if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p) { // Set all edges as executable, except those ranger says aren't. int non_exec_flag = ranger->non_executable_edge_flag;