From patchwork Tue Dec 6 16:14:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qing Zhao X-Patchwork-Id: 61594 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E91FB38469AF for ; Tue, 6 Dec 2022 16:16:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E91FB38469AF DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1670343382; bh=p2GzBbUL98ZvplYWt76z9OzFkrAr2DrimF8G1Xbd2IE=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=R3obzLR0f1WN4TzVL9NsSe7J+qiNRfyQq4EFTQHt+K2pKiHjERNwTTgfbaQ6lIQkj g8+mkUCBAawXGscMks0IBi5+xNQTZFerLozDT1BJZqWb/UzXjnv8Cc2n/NeXrgsrms nL39rPN/sJ1jLLshihi/caq/stVZE+w0ciI8saRI= 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 3DD71384230E; Tue, 6 Dec 2022 16:14:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3DD71384230E Received: from pps.filterd (m0246631.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2B6EfWsh030710; Tue, 6 Dec 2022 16:14:52 GMT Received: from iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta02.appoci.oracle.com [147.154.18.20]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3m7yeqqq5u-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 06 Dec 2022 16:14:52 +0000 Received: from pps.filterd (iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.5/8.17.1.5) with ESMTP id 2B6Ft9xR021273; Tue, 6 Dec 2022 16:14:51 GMT Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2104.outbound.protection.outlook.com [104.47.58.104]) by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3m8uab40dj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 06 Dec 2022 16:14:51 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=PMOWaG4ZqMAmClGkXxHzK71Mhe6hy9ReCiXlyNzlv4k70RxQFd/ANtFLo/k5sWpd4iw/8nN6IAVV5ItYal8C02Lt64NpZcGPpq1NVL9SVXvMXn5Nhgvo6Ba20RLQBxWpTXP4Qo3tBhghGAZsaOge4y1cqfHeE7yBjKTcnV6t8kG/Dq5JMqnqQroDP4shoPRwq/Epmp0CP89L1wnpUfXOEm4JqyIwUPra5SQlLfhocy2lduIhYDrwXZZGjawqCzZYDLbM/HBdHDIFjRJLKgm96SQg+wJCCuja0YPB0OyFVfVBy9+BbwS4M4D3aG0PcjirXmuMwVL6bfUYI1qUas1XCQ== 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=p2GzBbUL98ZvplYWt76z9OzFkrAr2DrimF8G1Xbd2IE=; b=EY6H2jEW/IyA7rqHqrGy5iMuC60Yv/uUCxyhlSS/GP6gW1UemOChCsKFIRuvrjHG4+GwI04F97Palk+Zy0r8Ka2JGVbSVAKwa9+uv3xXUSGsX788Gc+S3HUz9a4UYRwbM60BBGaUyKOpp9EbT/gxt68Feru7CltBFuD2Ke9wkoEIZSkTAecx5xNDx9LPyVsvcanuL8HOKESqzSoAmhYsW+GrUUcUs8A98FxDDhPIGu1btEmsK0gAL5Up0xcYLLFDKrDi7Cg8C7cROjkTGOCpReI8w2UFz9bEcDwbXcZKT1yiWChGpiOLcSi31BkfuyMIybk28tiAKbfNlTOGTd1adA== 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 CH2PR10MB4197.namprd10.prod.outlook.com (2603:10b6:610:7d::18) 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:14:48 +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:14:48 +0000 To: rguenther@suse.de, joseph@codesourcery.com Cc: gcc-patches@gcc.gnu.org, keescook@chromium.org, siddhesh@gcc.gnu.org, Qing Zhao Subject: [V3][PATCH 1/2] Update -Warray-bounds with -fstrict-flex-arrays. Date: Tue, 6 Dec 2022 16:14:37 +0000 Message-Id: <20221206161438.2396168-3-qing.zhao@oracle.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20221206161438.2396168-1-qing.zhao@oracle.com> References: <20221206161438.2396168-1-qing.zhao@oracle.com> X-ClientProxiedBy: BLAPR05CA0047.namprd05.prod.outlook.com (2603:10b6:208:335::28) To CH2PR10MB4344.namprd10.prod.outlook.com (2603:10b6:610:af::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PR10MB4344:EE_|CH2PR10MB4197:EE_ X-MS-Office365-Filtering-Correlation-Id: 6e7ef83c-9836-4185-98d7-08dad7a4ff54 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: DXdtl58ILlyNdMa9HGOB6OCFD6vuPU50UPgCc+db0TCic5RVaqgPGMH1B9w9GM+CXcFKTLt47v73I447u6jHiSKFRVxa7CPWqbQju3xo+SELK9nt/caKqfci37lBmoToBRWJ0hkBq64Z+hb/CPvdQrlAIkBwPW7fAkXNzsuDw/qpB2dvcttLoLZqWH/aQEM1lIWAjK2shlAgyLEDwnzfIhJQk1MMxdcZGAALO9oB+0tLz5pxm3PND4MmPvSI8dgp311IH0YYSDMSsheR1j+/EwntwCHeo4vWgflsUvU69e3ece+Y4TvoOrwhgV5Tnpd7UMTpcJsnSrm693wJlp7iNxNHxPubJ4UkU+ZUcn7a5jkBF9a3GtjbX2rBlwAiRnK+KlRe00P1mODhy6i6lBk9ezN4hF/Z1778mEC/EWisM6vvaWGsD7jOK8BZXsFl2fy4sMGOaWGUBVLHsQQidZlz+clgadk+2TKn4ZXuOsnqcU6X+pzw4D7IhGOyn7bEd7HG1cuiA79ttZCwIAJfeb/xOVJxiALe/MUUwZWpQ8tBSXA7lA7aDFD13/gBfehilW5M0+QNR3dvE2nnoH0H0S59XTqBRALlY0RenHffJOljTVn3DgEFuh5QGLiNR/aqIcnMtUTSQ2egB7MikSt0hq9WIpAC3/aLd2vg0MfnCDsiVYSx9ZcSC+Iq1yMw5PJZ8+WclAdG3mpqfs8gI6vwwdsq2w== 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)(136003)(39860400002)(376002)(366004)(396003)(346002)(451199015)(186003)(2616005)(6512007)(6506007)(26005)(316002)(84970400001)(107886003)(8676002)(4326008)(6666004)(478600001)(6486002)(66476007)(66946007)(66556008)(30864003)(8936002)(5660300002)(15650500001)(83380400001)(2906002)(41300700001)(1076003)(36756003)(44832011)(38100700002)(86362001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: s8a2tgEPg46Cyeft0arZMA/Y+saT9O84oZGf31RV8hYmkzA/VI/YwaZI5wVcS4BI8NIzWYAjKfGlINQlgaQxQCKqrFnhtUFk6OU4fk9ZjB2fsylI9cDcsTPVccjWkoCPldDEwZfNYZ4wGskebYpwC97k2T3w1bahqqnY+7xJ14Kq2Qdbk7NcgW6cltP1qt+p6/UY08tPT1v8YIW//GgjeQVpKqG9JvratdiLtXNPzpiFsuNIbfrOMs4HmnHv8IThxvy05CE0GnVm4rFvDugogg9SdbubR2dll9Zk/hjgJcL65L6DCVDyagmrG49S+pgpATCbR7u41231Di+EQEiF0HoZI7kjJBG4tJOeDB5eh5gBkSLwBibICBBXWO9y3ZGMjzXpiDamWwf9zMNB3W/gl5XYERlRq4LvSmQWTBQRpMAaP5/AihcCVtWM9+UkoyBYjkBa1wSqB4QSWpx+ELFtJF9mrQDuxjJro/WmmpAIcq4TfCRLTwX0wyPUVE7s4v9PVPpFGsR/QJch/FG4myZE0S9SN+dFvROYjY01W7zmMGnofy869GaT1Ypi/HMUskt/BjULRf7QrRlDhAxIeO/e31EOhP0CawJe73t8hq8+Ra+PvUIMwv4V2BD3EYHJqGysGfPOKoP5TkgM3WXNYflFBYmSvVm3SB3MStJkiTtdDszT7FwjV4bVKct1ZS9V8x7OjU7sq+UwKJ0Xt8pjnb2Al7d0Ia5FwrZogLHJ3ZZcrhnYXWY/DhX8uFZ224FraIL1QXPzwPCFZJBPNR+Eg58woDwLnpVvJ2nSTcsy6ZsVwBPIocse3mxL0vZN63mewCrLKWhZAefnkjGVXKqKKMm0vZMn8CuPs8eq7u5uNvPsSuKsLMjsmzI8jhGQ0xrT8GxgZAHG2sqcwZq44YOsZaDyjmrkTKnp6ipLI9GOBuf/zmLFl/AzpfiQ1/WuWLwpEmESPcpUEAOZy53GxbeXLaJNY4gyMfDeJjiVDULTYlq9KNE5FbKIa4BvFtYT8i4/NQP44cGA3kSPTWwaMwyDD/AyYederV/Y5MFje6rTHwcxXKAlXXJch8kBpDt11UIUxJmhFQxxLt876BtSXqu6XPUhPlLXk0+tvz5iojsd6b82UePXtPitzIFSXnImb5Dy6LGTR5b+2pwJGnQkY4L8h9xYJmZhvawT8D5IxsMBUDBfY66P6lwDgvFMeT+OhAyiutnp+kRjl+4gMczjXpLtHaRDw9B9eWVXwru3a5vcqdFeWqE5QYH7EkcPR9QA85LrMF9Re3ADzXUUpDo5BJJfCRBaL+6cTLIs93/3aPQacJfK5tjgQSPGFQZBidq/lIGUzJMjWTsrvrTjqYjWU4xbx86bqo4Hbqg9PPB3VSSINmU6eBgf7JUinPi1dVb6wx7YmzKdAghvo1c8WTIb91M1zSdT+hPZ0n8QKRnQkqjrlbAG+sXxW/qbSh1hem9oYiSe/2qAz3nSqoAPsfy84zKyvxuMkCJaAF2GB0XY2GQR11PY84jA21TDoOBzCtkW4le3/svR0ws+ZvIBzKCE5RAMwMwGo/jmeShXx4Ir7VtWFyw5GTABzrIFl6hB+ATdMFW03gei X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: CceWhKG5xFYtnQ7BoVb+TcFrF+SCprsqmWDZPyUS192BWm9bkoQndOGE+zwclxFpLec1Dr08T9NxiUmq3cH2DTCvVqjT+PH31H/Miew1gBJ3kaDjn3SdLg996BY1Ut0hYpjEUqy065qEKnufN4KmYFVydrwouu5cNceiHbIG+1w4/AmmfXxf4GoFXJveTaF4lep1THrGgWPBqFEGI7JI7K3w6s6310WXgo/R+UrXV+ShmoclA7NdL0wW7bvK9a0YHLNJ3BJ5GtHKegV02+EmU47L5GrTyTMJcHnqqXib/exswk2zJxaFLaMjY3V50eNnNci2gb0+25cCbCx8nUzeyrsE5TPLbPbDQB4vyfLCXC3HbAzhrjX+0L0WB8V1nQuphWIo10S1JT1kD1uQLjua7PeaB7GnK/O1ZlmK9sJLpcay0qlyloWzBezB4IqCgQkIu6czgy7eaGU6Oz3nrPrCWKiQEK2tFBAUThWCu59aJgXXi7TEwpCN2CZgTf06r6AJgiVZnQWLGfEs62G8dlRfBpyjSbi2UpYYQCxLzfEQl022ErxAJbk641rc5FgzSJdeUyZCpd4KAla2uwAHusUI4wT+6NC9xaLE1bu98VWTDJYFBwxt+GVSj0v8X8Cq1/VTO5e67W63BUFTfiRb7I+Z7hGpewj+Rg0R3nZ8QkSkZY8/XptiIBTaCwwzpyRe7jEh6/QXH/0+mB0mQUZmE3gtspm5arawihdztcrwzaJOE+cTR1POC9usnJMpRxA1LCPN9xSEVuCiBAc+GODZvEHKqV2mZBpJ5w3T6mazkY7ygxhSYWhQ6co5zLqln1mIZWJ0zxvLmfya27WVgKQeRHga/ZrpJxN3emE5CQgJGbwLjHTG6vnOvtbAaYGDgFvvp2qO X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6e7ef83c-9836-4185-98d7-08dad7a4ff54 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:14:48.6251 (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: gcu64qLJ+/I4/koL6bSCfjyzNZhEgT2FjapiKloI3UQwV1oFW96Y1Fo+Baqkn1VX1m8/ZGSF4dYgNsin/tkG9Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH2PR10MB4197 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 suspectscore=0 adultscore=0 malwarescore=0 bulkscore=0 mlxscore=0 spamscore=0 phishscore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2210170000 definitions=main-2212060135 X-Proofpoint-GUID: TQ9lIHRNzTyf8tHiIaQHpQpVQm88vng9 X-Proofpoint-ORIG-GUID: TQ9lIHRNzTyf8tHiIaQHpQpVQm88vng9 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Qing Zhao via Gcc-patches From: Qing Zhao Reply-To: Qing Zhao Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" A. add the following to clarify the relationship between -Warray-bounds and the LEVEL of -fstrict-flex-array: By default, the trailing array of a structure will be treated as a flexible array member by '-Warray-bounds' or '-Warray-bounds=N' if it is declared as either a flexible array member per C99 standard onwards ('[]'), a GCC zero-length array extension ('[0]'), or an one-element array ('[1]'). As a result, out of bounds subscripts or offsets into zero-length arrays or one-element arrays are not warned by default. You can add the option '-fstrict-flex-arrays' or '-fstrict-flex-arrays=LEVEL' to control how this option treat trailing array of a structure as a flexible array member. when LEVEL<=1, no change to the default behavior. when LEVEL=2, additional warnings will be issued for out of bounds subscripts or offsets into one-element arrays; when LEVEL=3, in addition to LEVEL=2, additional warnings will be issued for out of bounds subscripts or offsets into zero-length arrays. B. change -Warray-bounds=2 to exclude its control on how to treat trailing arrays as flexible array members: '-Warray-bounds=2' This warning level also warns about the intermediate results of pointer arithmetic that may yield out of bounds values. This warning level may give a larger number of false positives and is deactivated by default. gcc/ChangeLog: * attribs.cc (strict_flex_array_level_of): New function. * attribs.h (strict_flex_array_level_of): Prototype for new function. * doc/invoke.texi: Update -Warray-bounds by specifying the impact from -fstrict-flex-arrays. Also update -Warray-bounds=2 by eliminating its impact on treating trailing arrays as flexible array members. * gimple-array-bounds.cc (get_up_bounds_for_array_ref): New function. (check_out_of_bounds_and_warn): New function. (array_bounds_checker::check_array_ref): Update with calls to the above new functions. * tree.cc (array_ref_flexible_size_p): Add one new argument. (component_ref_sam_type): New function. (component_ref_size): Control with level of strict-flex-array. * tree.h (array_ref_flexible_size_p): Update prototype. (enum struct special_array_member): Add two new enum values. (component_ref_sam_type): New prototype. gcc/c/ChangeLog: * c-decl.cc (is_flexible_array_member_p): Call new function strict_flex_array_level_of. gcc/testsuite/ChangeLog: * gcc.dg/Warray-bounds-11.c: Update warnings for -Warray-bounds=2. * gcc.dg/Warray-bounds-flex-arrays-1.c: New test. * gcc.dg/Warray-bounds-flex-arrays-2.c: New test. * gcc.dg/Warray-bounds-flex-arrays-3.c: New test. * gcc.dg/Warray-bounds-flex-arrays-4.c: New test. * gcc.dg/Warray-bounds-flex-arrays-5.c: New test. * gcc.dg/Warray-bounds-flex-arrays-6.c: New test. --- gcc/attribs.cc | 30 ++++ gcc/attribs.h | 2 + gcc/c/c-decl.cc | 21 +-- gcc/doc/invoke.texi | 27 ++- gcc/gimple-array-bounds.cc | 150 +++++++++++------ gcc/testsuite/gcc.dg/Warray-bounds-11.c | 2 +- .../gcc.dg/Warray-bounds-flex-arrays-1.c | 39 +++++ .../gcc.dg/Warray-bounds-flex-arrays-2.c | 39 +++++ .../gcc.dg/Warray-bounds-flex-arrays-3.c | 39 +++++ .../gcc.dg/Warray-bounds-flex-arrays-4.c | 39 +++++ .../gcc.dg/Warray-bounds-flex-arrays-5.c | 39 +++++ .../gcc.dg/Warray-bounds-flex-arrays-6.c | 39 +++++ gcc/tree.cc | 159 +++++++++++++----- gcc/tree.h | 12 +- 14 files changed, 512 insertions(+), 125 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c diff --git a/gcc/attribs.cc b/gcc/attribs.cc index 27dea748561..095def4d6b0 100644 --- a/gcc/attribs.cc +++ b/gcc/attribs.cc @@ -2456,6 +2456,36 @@ init_attr_rdwr_indices (rdwr_map *rwm, tree attrs) } } +/* Get the LEVEL of the strict_flex_array for the ARRAY_FIELD based on the + values of attribute strict_flex_array and the flag_strict_flex_arrays. */ +unsigned int +strict_flex_array_level_of (tree array_field) +{ + gcc_assert (TREE_CODE (array_field) == FIELD_DECL); + unsigned int strict_flex_array_level = flag_strict_flex_arrays; + + tree attr_strict_flex_array + = lookup_attribute ("strict_flex_array", DECL_ATTRIBUTES (array_field)); + /* If there is a strict_flex_array attribute attached to the field, + override the flag_strict_flex_arrays. */ + if (attr_strict_flex_array) + { + /* Get the value of the level first from the attribute. */ + unsigned HOST_WIDE_INT attr_strict_flex_array_level = 0; + gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); + attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); + gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); + attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); + gcc_assert (tree_fits_uhwi_p (attr_strict_flex_array)); + attr_strict_flex_array_level = tree_to_uhwi (attr_strict_flex_array); + + /* The attribute has higher priority than flag_struct_flex_array. */ + strict_flex_array_level = attr_strict_flex_array_level; + } + return strict_flex_array_level; +} + + /* Return the access specification for a function parameter PARM or null if the current function has no such specification. */ diff --git a/gcc/attribs.h b/gcc/attribs.h index 1dc16e4bc4e..742811e6fda 100644 --- a/gcc/attribs.h +++ b/gcc/attribs.h @@ -398,4 +398,6 @@ extern void init_attr_rdwr_indices (rdwr_map *, tree); extern attr_access *get_parm_access (rdwr_map &, tree, tree = current_function_decl); +extern unsigned int strict_flex_array_level_of (tree); + #endif // GCC_ATTRIBS_H diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 4adb89e4aaf..111f05e2a40 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -9067,26 +9067,7 @@ is_flexible_array_member_p (bool is_last_field, bool is_one_element_array = one_element_array_type_p (TREE_TYPE (x)); bool is_flexible_array = flexible_array_member_type_p (TREE_TYPE (x)); - unsigned int strict_flex_array_level = flag_strict_flex_arrays; - - tree attr_strict_flex_array = lookup_attribute ("strict_flex_array", - DECL_ATTRIBUTES (x)); - /* If there is a strict_flex_array attribute attached to the field, - override the flag_strict_flex_arrays. */ - if (attr_strict_flex_array) - { - /* Get the value of the level first from the attribute. */ - unsigned HOST_WIDE_INT attr_strict_flex_array_level = 0; - gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); - attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); - gcc_assert (TREE_VALUE (attr_strict_flex_array) != NULL_TREE); - attr_strict_flex_array = TREE_VALUE (attr_strict_flex_array); - gcc_assert (tree_fits_uhwi_p (attr_strict_flex_array)); - attr_strict_flex_array_level = tree_to_uhwi (attr_strict_flex_array); - - /* The attribute has higher priority than flag_struct_flex_array. */ - strict_flex_array_level = attr_strict_flex_array_level; - } + unsigned int strict_flex_array_level = strict_flex_array_level_of (x); switch (strict_flex_array_level) { diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 277ac35ad16..726392409b6 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -8040,17 +8040,34 @@ is enabled by @option{-Wall}. It is more effective when @option{-ftree-vrp} is active (the default for @option{-O2} and above) but a subset of instances are issued even without optimization. +By default, the trailing array of a structure will be treated as a flexible +array member by @option{-Warray-bounds} or @option{-Warray-bounds=@var{n}} +if it is declared as either a flexible array member per C99 standard onwards +(@samp{[]}), a GCC zero-length array extension (@samp{[0]}), or an one-element +array (@samp{[1]}). As a result, out of bounds subscripts or offsets into +zero-length arrays or one-element arrays are not warned by default. + +You can add the option @option{-fstrict-flex-arrays} or +@option{-fstrict-flex-arrays=@var{level}} to control how this +option treat trailing array of a structure as a flexible array member: + +when @var{level}<=1, no change to the default behavior. + +when @var{level}=2, additional warnings will be issued for out of bounds +subscripts or offsets into one-element arrays; + +when @var{level}=3, in addition to @var{level}=2, additional warnings will be +issued for out of bounds subscripts or offsets into zero-length arrays. + @table @gcctabopt @item -Warray-bounds=1 This is the default warning level of @option{-Warray-bounds} and is enabled by @option{-Wall}; higher levels are not, and must be explicitly requested. @item -Warray-bounds=2 -This warning level also warns about out of bounds accesses to trailing -struct members of one-element array types (@pxref{Zero Length}) and about -the intermediate results of pointer arithmetic that may yield out of bounds -values. This warning level may give a larger number of false positives and -is deactivated by default. +This warning level also warns about the intermediate results of pointer +arithmetic that may yield out of bounds values. This warning level may +give a larger number of false positives and is deactivated by default. @end table @item -Warray-compare diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc index 972e25fdb31..db3459af325 100644 --- a/gcc/gimple-array-bounds.cc +++ b/gcc/gimple-array-bounds.cc @@ -160,38 +160,17 @@ trailing_array (tree arg, tree *pref) return array_ref_flexible_size_p (arg); } -/* Checks one ARRAY_REF in REF, located at LOCUS. Ignores flexible - arrays and "struct" hacks. If VRP can determine that the array - subscript is a constant, check if it is outside valid range. If - the array subscript is a RANGE, warn if it is non-overlapping with - valid range. IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside - a ADDR_EXPR. Return true if a warning has been issued or if - no-warning is set. */ +/* Acquire the upper bound and upper bound plus one for the array + reference REF and record them into UP_BOUND and UP_BOUND_P1. + Set *DECL to the decl or expresssion REF refers to. */ -bool -array_bounds_checker::check_array_ref (location_t location, tree ref, - gimple *stmt, bool ignore_off_by_one) +static void +get_up_bounds_for_array_ref (tree ref, tree *decl, + tree *up_bound, tree *up_bound_p1) { - if (warning_suppressed_p (ref, OPT_Warray_bounds_)) - /* Return true to have the caller prevent warnings for enclosing - refs. */ - return true; - - tree low_sub = TREE_OPERAND (ref, 1); - tree up_sub = low_sub; - tree up_bound = array_ref_up_bound (ref); - - /* Referenced decl if one can be determined. */ - tree decl = NULL_TREE; - - /* Set for accesses to interior zero-length arrays. */ - special_array_member sam{ }; - - tree up_bound_p1; - - if (!up_bound - || TREE_CODE (up_bound) != INTEGER_CST - || (warn_array_bounds < 2 && trailing_array (ref, &decl))) + if (!(*up_bound) + || TREE_CODE (*up_bound) != INTEGER_CST + || trailing_array (ref, decl)) { /* Accesses to trailing arrays via pointers may access storage beyond the types array bounds. For such arrays, or for flexible @@ -203,8 +182,8 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, if (TREE_CODE (eltsize) != INTEGER_CST || integer_zerop (eltsize)) { - up_bound = NULL_TREE; - up_bound_p1 = NULL_TREE; + *up_bound = NULL_TREE; + *up_bound_p1 = NULL_TREE; } else { @@ -217,7 +196,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, { /* Try to determine the size of the trailing array from its initializer (if it has one). */ - if (tree refsize = component_ref_size (arg, &sam)) + if (tree refsize = component_ref_size (arg)) if (TREE_CODE (refsize) == INTEGER_CST) maxbound = refsize; } @@ -236,7 +215,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, { /* Try to determine the size from a pointer to an array if BASE is one. */ - if (tree size = get_ref_size (base, &decl)) + if (tree size = get_ref_size (base, decl)) maxbound = size; } else if (!compref && DECL_P (base)) @@ -244,7 +223,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, if (TREE_CODE (basesize) == INTEGER_CST) { maxbound = basesize; - decl = base; + *decl = base; } if (known_gt (off, 0)) @@ -256,21 +235,33 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, else maxbound = fold_convert (sizetype, maxbound); - up_bound_p1 = int_const_binop (TRUNC_DIV_EXPR, maxbound, eltsize); + *up_bound_p1 = int_const_binop (TRUNC_DIV_EXPR, maxbound, eltsize); - if (up_bound_p1 != NULL_TREE) - up_bound = int_const_binop (MINUS_EXPR, up_bound_p1, + if (*up_bound_p1 != NULL_TREE) + *up_bound = int_const_binop (MINUS_EXPR, *up_bound_p1, build_int_cst (ptrdiff_type_node, 1)); else - up_bound = NULL_TREE; + *up_bound = NULL_TREE; } } else - up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound, - build_int_cst (TREE_TYPE (up_bound), 1)); + *up_bound_p1 = int_const_binop (PLUS_EXPR, *up_bound, + build_int_cst (TREE_TYPE (*up_bound), 1)); + return; +} - tree low_bound = array_ref_low_bound (ref); +/* 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. */ +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) +{ + tree low_bound = array_ref_low_bound (ref); tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); bool warned = false; @@ -279,18 +270,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, 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, artype); - - const value_range *vr = NULL; - if (TREE_CODE (low_sub) == SSA_NAME) - { - vr = get_value_range (low_sub, stmt); - if (!vr->undefined_p () && !vr->varying_p ()) - { - low_sub = vr->kind () == VR_RANGE ? vr->max () : vr->min (); - up_sub = vr->kind () == VR_RANGE ? vr->min () : vr->max (); - } - } + low_sub_org, artype); if (warned) ; /* Do nothing. */ @@ -321,6 +301,68 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, warned = warning_at (location, OPT_Warray_bounds_, "array subscript %E is below array bounds of %qT", low_sub, artype); + return warned; +} + +/* Checks one ARRAY_REF in REF, located at LOCUS. Ignores flexible + arrays and "struct" hacks. If VRP can determine that the array + subscript is a constant, check if it is outside valid range. If + the array subscript is a RANGE, warn if it is non-overlapping with + valid range. IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside + a ADDR_EXPR. Return true if a warning has been issued or if + no-warning is set. */ + +bool +array_bounds_checker::check_array_ref (location_t location, tree ref, + gimple *stmt, bool ignore_off_by_one) +{ + if (warning_suppressed_p (ref, OPT_Warray_bounds_)) + /* Return true to have the caller prevent warnings for enclosing + refs. */ + return true; + + /* Upper bound and Upper bound plus one for -Warray-bounds. */ + tree up_bound = array_ref_up_bound (ref); + tree up_bound_p1 = NULL_TREE; + + /* Referenced decl if one can be determined. */ + tree decl = NULL_TREE; + + /* Set to the type of the special array member for a COMPONENT_REF. */ + special_array_member sam{ }; + + tree arg = TREE_OPERAND (ref, 0); + const bool compref = TREE_CODE (arg) == COMPONENT_REF; + + if (compref) + /* Try to determine special array member type for this COMPONENT_REF. */ + sam = component_ref_sam_type (arg); + + get_up_bounds_for_array_ref (ref, &decl, &up_bound, &up_bound_p1); + + bool warned = false; + + tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); + tree low_sub_org = TREE_OPERAND (ref, 1); + tree up_sub = low_sub_org; + tree low_sub = low_sub_org; + + const value_range *vr = NULL; + if (TREE_CODE (low_sub_org) == SSA_NAME) + { + vr = get_value_range (low_sub_org, stmt); + if (!vr->undefined_p () && !vr->varying_p ()) + { + low_sub = vr->kind () == VR_RANGE ? vr->max () : vr->min (); + up_sub = vr->kind () == VR_RANGE ? vr->min () : vr->max (); + } + } + + 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); + if (!warned && sam == special_array_member::int_0) warned = warning_at (location, OPT_Wzero_length_bounds, diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-11.c b/gcc/testsuite/gcc.dg/Warray-bounds-11.c index c9fc461942f..3ba2bb67fa0 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-11.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-11.c @@ -78,7 +78,7 @@ void foo(int (*a)[3]) h->j[4] = 1; // flexible array member h0->j[4] = 1; // zero-sized array extension - h1->j[4] = 1; /* { dg-warning "subscript 4 is above array bound" } */ + h1->j[4] = 1; /* { dg-bogus "subscript 4 is above array bound" } */ h3->j[4] = 1; /* { dg-warning "subscript 4 is above array bound" } */ struct h0b* h0b = malloc(sizeof(struct h) + 3 * sizeof(int)); diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c new file mode 100644 index 00000000000..d36ba4d86cb --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-1.c @@ -0,0 +1,39 @@ +/* Test -fstrict-flex-arrays + -Warray-bounds. */ +/* { dg-do compile} */ +/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds" } */ + +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 "array subscript 5 is above array bounds of" } */ + 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 new file mode 100644 index 00000000000..f63206e1948 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-2.c @@ -0,0 +1,39 @@ +/* Test -fstrict-flex-arrays + -Warray-bounds. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds" } */ + +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 "array subscript 5 is above array bounds of" } */ + trailing_1->c[2] = 2; /* { dg-warning "array subscript 2 is above array bounds of" } */ + 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 new file mode 100644 index 00000000000..e3273714e8b --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-3.c @@ -0,0 +1,39 @@ +/* Test -fstrict-flex-arrays + -Warray-bounds. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds" } */ + +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 "array subscript 5 is above array bounds of" } */ + trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ + trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ + 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 new file mode 100644 index 00000000000..cabaea77dc2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-4.c @@ -0,0 +1,39 @@ +/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fstrict-flex-arrays=1 -Warray-bounds=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 "array subscript 5 is above array bounds of" } */ + 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 new file mode 100644 index 00000000000..8b7db6e4f39 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-5.c @@ -0,0 +1,39 @@ +/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fstrict-flex-arrays=2 -Warray-bounds=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 "array subscript 5 is above array bounds of" } */ + trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ + 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 new file mode 100644 index 00000000000..035bf481396 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-flex-arrays-6.c @@ -0,0 +1,39 @@ +/* Test -fstrict-flex-arrays + -Warray-bounds=2. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fstrict-flex-arrays=3 -Warray-bounds=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 "array subscript 5 is above array bounds of" } */ + trailing_1->c[2] = 2; /*{ dg-warning "array subscript 2 is above array bounds of" } */ + trailing_0->c[1] = 1; /*{ dg-warning "array subscript 1 is outside array bounds of" } */ + trailing_flex->c[10] = 10; /* { dg-bogus "array subscript " } */ + +} diff --git a/gcc/tree.cc b/gcc/tree.cc index 254b2373dcf..b40c95ae8c4 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -12719,15 +12719,21 @@ array_ref_up_bound (tree exp) int test (uint8_t *p, uint32_t t[1][1], int n) { for (int i = 0; i < 4; i++, p++) t[i][0] = ...; + + If non-null, set IS_TRAILING_ARRAY to true if the ref is the above case A. */ bool -array_ref_flexible_size_p (tree ref) +array_ref_flexible_size_p (tree ref, bool *is_trailing_array /* = NULL */) { - /* the TYPE for this array referece. */ + /* The TYPE for this array referece. */ tree atype = NULL_TREE; - /* the FIELD_DECL for the array field in the containing structure. */ + /* The FIELD_DECL for the array field in the containing structure. */ tree afield_decl = NULL_TREE; + /* Whether this array is the trailing array of a structure. */ + bool is_trailing_array_tmp = false; + if (!is_trailing_array) + is_trailing_array = &is_trailing_array_tmp; if (TREE_CODE (ref) == ARRAY_REF || TREE_CODE (ref) == ARRAY_RANGE_REF) @@ -12815,7 +12821,10 @@ array_ref_flexible_size_p (tree ref) if (! TYPE_SIZE (atype) || ! TYPE_DOMAIN (atype) || ! TYPE_MAX_VALUE (TYPE_DOMAIN (atype))) - return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; + { + *is_trailing_array = afield_decl && TREE_CODE (afield_decl) == FIELD_DECL; + return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; + } /* If the reference is based on a declared entity, the size of the array is constrained by its given domain. (Do not trust commons PR/69368). */ @@ -12837,9 +12846,17 @@ array_ref_flexible_size_p (tree ref) if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (atype))) != INTEGER_CST || TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (atype))) != INTEGER_CST || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (atype))) != INTEGER_CST) - return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; + { + *is_trailing_array + = afield_decl && TREE_CODE (afield_decl) == FIELD_DECL; + return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; + } if (! get_addr_base_and_unit_offset (ref_to_array, &offset)) - return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; + { + *is_trailing_array + = afield_decl && TREE_CODE (afield_decl) == FIELD_DECL; + return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; + } /* If at least one extra element fits it is a flexarray. */ if (known_le ((wi::to_offset (TYPE_MAX_VALUE (TYPE_DOMAIN (atype))) @@ -12847,11 +12864,16 @@ array_ref_flexible_size_p (tree ref) + 2) * wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (atype))), wi::to_offset (DECL_SIZE_UNIT (ref)) - offset)) - return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; + { + *is_trailing_array + = afield_decl && TREE_CODE (afield_decl) == FIELD_DECL; + return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; + } return false; } + *is_trailing_array = afield_decl && TREE_CODE (afield_decl) == FIELD_DECL; return afield_decl ? !DECL_NOT_FLEXARRAY (afield_decl) : true; } @@ -12913,11 +12935,63 @@ get_initializer_for (tree init, tree decl) return NULL_TREE; } +/* Determines the special array member type for the array reference REF. */ +special_array_member +component_ref_sam_type (tree ref) +{ + special_array_member sam_type = special_array_member::none; + + tree member = TREE_OPERAND (ref, 1); + tree memsize = DECL_SIZE_UNIT (member); + if (memsize) + { + tree memtype = TREE_TYPE (member); + if (TREE_CODE (memtype) != ARRAY_TYPE) + return sam_type; + + bool trailing = false; + (void)array_ref_flexible_size_p (ref, &trailing); + bool zero_length = integer_zerop (memsize); + if (!trailing && !zero_length) + /* MEMBER is an interior array with + more than one element. */ + return special_array_member::int_n; + + if (zero_length) + { + if (trailing) + return special_array_member::trail_0; + else + return special_array_member::int_0; + } + + if (!zero_length) + if (tree dom = TYPE_DOMAIN (memtype)) + if (tree min = TYPE_MIN_VALUE (dom)) + if (tree max = TYPE_MAX_VALUE (dom)) + if (TREE_CODE (min) == INTEGER_CST + && TREE_CODE (max) == INTEGER_CST) + { + offset_int minidx = wi::to_offset (min); + offset_int maxidx = wi::to_offset (max); + offset_int neltsm1 = maxidx - minidx; + if (neltsm1 > 0) + /* MEMBER is a trailing array with more than + one elements. */ + return special_array_member::trail_n; + + if (neltsm1 == 0) + return special_array_member::trail_1; + } + } + + return sam_type; +} + /* Determines the size of the member referenced by the COMPONENT_REF REF, using its initializer expression if necessary in order to determine the size of an initialized flexible array member. - If non-null, set *ARK when REF refers to an interior zero-length - array or a trailing one-element array. + If non-null, set *SAM to the type of special array member. Returns the size as sizetype (which might be zero for an object with an uninitialized flexible array member) or null if the size cannot be determined. */ @@ -12930,7 +13004,7 @@ component_ref_size (tree ref, special_array_member *sam /* = NULL */) special_array_member sambuf; if (!sam) sam = &sambuf; - *sam = special_array_member::none; + *sam = component_ref_sam_type (ref); /* The object/argument referenced by the COMPONENT_REF and its type. */ tree arg = TREE_OPERAND (ref, 0); @@ -12951,43 +13025,46 @@ component_ref_size (tree ref, special_array_member *sam /* = NULL */) return (tree_int_cst_equal (memsize, TYPE_SIZE_UNIT (memtype)) ? memsize : NULL_TREE); - bool trailing = array_ref_flexible_size_p (ref); - bool zero_length = integer_zerop (memsize); - if (!trailing && !zero_length) - /* MEMBER is either an interior array or is an array with - more than one element. */ + /* 2-or-more elements arrays are treated as normal arrays by default. */ + if (*sam == special_array_member::int_n + || *sam == special_array_member::trail_n) return memsize; - if (zero_length) + /* flag_strict_flex_arrays will control how to treat + the trailing arrays as flexiable array members. */ + + tree afield_decl = TREE_OPERAND (ref, 1); + unsigned int strict_flex_array_level + = strict_flex_array_level_of (afield_decl); + + switch (strict_flex_array_level) { - if (trailing) - *sam = special_array_member::trail_0; - else - { - *sam = special_array_member::int_0; - memsize = NULL_TREE; - } + case 3: + /* Treaing 0-length trailing arrays as normal array. */ + if (*sam == special_array_member::trail_0) + return size_zero_node; + /* FALLTHROUGH. */ + case 2: + /* Treating 1-element trailing arrays as normal array. */ + if (*sam == special_array_member::trail_1) + return memsize; + /* FALLTHROUGH. */ + case 1: + /* Treating 2-or-more elements trailing arrays as normal + array. */ + if (*sam == special_array_member::trail_n) + return memsize; + /* FALLTHROUGH. */ + case 0: + break; + default: + gcc_unreachable (); } - if (!zero_length) - if (tree dom = TYPE_DOMAIN (memtype)) - if (tree min = TYPE_MIN_VALUE (dom)) - if (tree max = TYPE_MAX_VALUE (dom)) - if (TREE_CODE (min) == INTEGER_CST - && TREE_CODE (max) == INTEGER_CST) - { - offset_int minidx = wi::to_offset (min); - offset_int maxidx = wi::to_offset (max); - offset_int neltsm1 = maxidx - minidx; - if (neltsm1 > 0) - /* MEMBER is an array with more than one element. */ - return memsize; - - if (neltsm1 == 0) - *sam = special_array_member::trail_1; - } + if (*sam == special_array_member::int_0) + memsize = NULL_TREE; - /* For a reference to a zero- or one-element array member of a union + /* For a reference to a flexible array member of a union use the size of the union instead of the size of the member. */ if (TREE_CODE (argtype) == UNION_TYPE) memsize = TYPE_SIZE_UNIT (argtype); diff --git a/gcc/tree.h b/gcc/tree.h index 4a19de1c94d..23223ca0c87 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5553,22 +5553,26 @@ extern tree array_ref_low_bound (tree); /* Returns true if REF is an array reference, a component reference, or a memory reference to an array whose actual size might be larger than its upper bound implies. */ -extern bool array_ref_flexible_size_p (tree); +extern bool array_ref_flexible_size_p (tree, bool * = NULL); /* Return a tree representing the offset, in bytes, of the field referenced by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */ extern tree component_ref_field_offset (tree); -/* Describes a "special" array member due to which component_ref_size - returns null. */ +/* Describes a "special" array member for a COMPONENT_REF. */ enum struct special_array_member { none, /* Not a special array member. */ int_0, /* Interior array member with size zero. */ trail_0, /* Trailing array member with size zero. */ - trail_1 /* Trailing array member with one element. */ + trail_1, /* Trailing array member with one element. */ + trail_n, /* Trailing array member with two or more elements. */ + int_n /* Interior array member with one or more elements. */ }; +/* Determines the special array member type for a COMPONENT_REF. */ +extern special_array_member component_ref_sam_type (tree); + /* Return the size of the member referenced by the COMPONENT_REF, using its initializer expression if necessary in order to determine the size of an initialized flexible array member. The size might be zero for From patchwork Tue Dec 6 16:18:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qing Zhao X-Patchwork-Id: 61596 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id ACCD23842309 for ; 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 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 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Qing Zhao via Gcc-patches From: Qing Zhao Reply-To: Qing Zhao Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" '-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;