From patchwork Tue Nov 5 03:26:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 1189299 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-512386-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="bPVAymyu"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="tpp/x9fB"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 476ZpY3bmWz9sNx for ; Tue, 5 Nov 2019 14:26:59 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; q=dns; s= default; b=xliMTky1ziXQwEQUcHglRjS7RmWwEryD6jEgLWydesP3OpwR2VV8a oL5xcmDr+1eCnCUKSHeEwbAq7eoTduL61RZw1ZujjQ9eKQCCd3Hx9F967bA4x2d1 MUtWW7+O8t5Y2/iwolApXo+nzGqG9PEsUXaWSeBF0vzJLb0IlciDbc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; s= default; bh=wSwyCNz3bjwss/3qZYHEmPf01eE=; b=bPVAymyuhIIw3Y4Yn/VE +UshscUEnI9kDWux7CUwwJtkI4hL+vABYSypqDn+nmAHTLDKfp0Nx/Yewn0CuU4r 5b/8zxnKtpVXHnCccsm9Q1Lm7w678rM6nhG1r9TLswUQKtz7f8jcMx1sVZabx27o BLzcwoWluGT2eeTrSmOD2a8= Received: (qmail 11156 invoked by alias); 5 Nov 2019 03:26:51 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 11147 invoked by uid 89); 5 Nov 2019 03:26:51 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-14.1 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=43007 X-HELO: mail-yb1-f176.google.com Received: from mail-yb1-f176.google.com (HELO mail-yb1-f176.google.com) (209.85.219.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 05 Nov 2019 03:26:49 +0000 Received: by mail-yb1-f176.google.com with SMTP id v17so1889600ybs.3 for ; Mon, 04 Nov 2019 19:26:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:subject:to:message-id:date:user-agent:mime-version :content-language; bh=uxkR3L04b/BglWjXuXxru39Zi/TiGeU7Pn268BsOllU=; b=tpp/x9fBIl/yEmPJZMM5ieASmDyk82Hs//ngYVnYnDPwkVmtlg1aAO4zuSNGf2VQyB aV8tN9ZNJTji8eXEOFyVHDXGzIW7keJxwQzQy6extu1EjYwJdLPYDPP6l5UkvDmTYSaA 1NSrDN0jW4t9HF1nX++j4eXZgBzJe3XB50omAoJrvhp6BYl/9ZTxyYd8Mz31ZqrQx+7+ j7qwgujMCXz1kb5yDcsK3vWJ4ARMD3R4SG+eh1meo1/GPOqX0hQb+fgQhMDHwY4Jdnkt EXeJRNdendFEmPEwNgYjpSmsuS8D0JtvXftSd8oYHoOBvDEKhUR3yKZV0yJcY1ga+zfn Z2Ag== Received: from [192.168.0.41] (97-118-98-145.hlrn.qwest.net. [97.118.98.145]) by smtp.gmail.com with ESMTPSA id q124sm21603703ywq.8.2019.11.04.19.26.46 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 04 Nov 2019 19:26:46 -0800 (PST) From: Martin Sebor Subject: [PATCH] handle constant size VLAs in -Warray-bounds (PR 82608, 92333) To: gcc-patches Message-ID: Date: Mon, 4 Nov 2019 20:26:45 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 X-IsSubscribed: yes -Warray-bounds doesn't yet have the logic to detect out-of-bounds indices into dynamically allocated arrays like VLAs because it doesn't track allocation calls. But the warning could detect such errors in accesses to VLAs with constant sizes even without such tracking. The attached patch adds this capability. Testing the warning revealed that the names and locations of VLAs with constant sizes are unavailable, making the warnings less useful than they could be otherwise. So the other part of the patch also arranges for the arrays backing the constant size VLAs to have names that reflect those of the VLAs, and the same location. Tested on x86_64-linux. Martin PR middle-end/92333 - missing variable name referencing VLA in warnings PR middle-end/82608 - missing -Warray-bounds on an out-of-bounds VLA index gcc/testsuite/ChangeLog: PR middle-end/92333 PR middle-end/82608 * gcc.dg/Warray-bounds-53.c: New test. gcc/ChangeLog: PR middle-end/92333 PR middle-end/82608 * tree-vrp.c (vrp_prop::check_array_ref): Handle VLAs with constant size. * tree-ssa-ccp.c (fold_builtin_alloca_with_align): Use a meaninful name and location for a temporary variable. Index: gcc/tree-vrp.c =================================================================== --- gcc/tree-vrp.c (revision 277806) +++ gcc/tree-vrp.c (working copy) @@ -4154,6 +4154,9 @@ vrp_prop::check_array_ref (location_t location, tr low_sub = up_sub = TREE_OPERAND (ref, 1); 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. */ bool interior_zero_len = false; @@ -4182,7 +4185,8 @@ vrp_prop::check_array_ref (location_t location, tr tree arg = TREE_OPERAND (ref, 0); poly_int64 off; - if (TREE_CODE (arg) == COMPONENT_REF) + const bool compref = TREE_CODE (arg) == COMPONENT_REF; + if (compref) { /* Try to determine the size of the trailing array from its initializer (if it has one). */ @@ -4191,12 +4195,27 @@ vrp_prop::check_array_ref (location_t location, tr maxbound = refsize; } - if (maxbound == ptrdiff_max - && get_addr_base_and_unit_offset (arg, &off) - && known_gt (off, 0)) - maxbound = wide_int_to_tree (sizetype, - wi::sub (wi::to_wide (maxbound), - off)); + if (maxbound == ptrdiff_max) + { + /* Try to determine the size of the base object. Avoid + COMPONENT_REF already tried above. Using its DECL_SIZE + size wouldn't necessarily be correct if the reference is + to its flexible array member initialized in a different + translation unit. */ + tree base = get_addr_base_and_unit_offset (arg, &off); + if (!compref && base && DECL_P (base)) + if (tree basesize = DECL_SIZE_UNIT (base)) + if (TREE_CODE (basesize) == INTEGER_CST) + { + maxbound = basesize; + decl = base; + } + + if (known_gt (off, 0)) + maxbound = wide_int_to_tree (sizetype, + wi::sub (wi::to_wide (maxbound), + off)); + } else maxbound = fold_convert (sizetype, maxbound); @@ -4281,7 +4300,7 @@ vrp_prop::check_array_ref (location_t location, tr fprintf (dump_file, "\n"); } - ref = TREE_OPERAND (ref, 0); + ref = decl ? decl : TREE_OPERAND (ref, 0); tree rec = NULL_TREE; if (TREE_CODE (ref) == COMPONENT_REF) Index: gcc/tree-ssa-ccp.c =================================================================== --- gcc/tree-ssa-ccp.c (revision 277806) +++ gcc/tree-ssa-ccp.c (working copy) @@ -2222,7 +2222,25 @@ fold_builtin_alloca_with_align (gimple *stmt) elem_type = build_nonstandard_integer_type (BITS_PER_UNIT, 1); n_elem = size * 8 / BITS_PER_UNIT; array_type = build_array_type_nelts (elem_type, n_elem); - var = create_tmp_var (array_type); + + if (tree ssa_name = SSA_NAME_IDENTIFIER (lhs)) + { + /* Give the temporary a name derived from the name of the VLA + declaration so it can be referenced in diagnostics. */ + const char *name = IDENTIFIER_POINTER (ssa_name); + var = create_tmp_var (array_type, name); + } + else + var = create_tmp_var (array_type); + + if (gimple *lhsdef = SSA_NAME_DEF_STMT (lhs)) + { + /* Set the temporary's location to that of the VLA declaration + so it can be pointed to in diagnostics. */ + location_t loc = gimple_location (lhsdef); + DECL_SOURCE_LOCATION (var) = loc; + } + SET_DECL_ALIGN (var, TREE_INT_CST_LOW (gimple_call_arg (stmt, 1))); if (uid != 0) SET_DECL_PT_UID (var, uid); Index: gcc/testsuite/gcc.dg/Warray-bounds-53.c =================================================================== --- gcc/testsuite/gcc.dg/Warray-bounds-53.c (nonexistent) +++ gcc/testsuite/gcc.dg/Warray-bounds-53.c (working copy) @@ -0,0 +1,50 @@ +/* PR middle-end/92333 - missing variable name referencing VLA in warnings + PR middle-end/82608 - missing -Warray-bounds on an out-of-bounds VLA index + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +void sink (void*); + +void test_char_vla_location (void) +{ + unsigned nelts = 7; + + char vla[nelts]; // { dg-message "declared here" } + + vla[0] = __LINE__; + vla[nelts] = 0; // { dg-warning "\\\[-Warray-bounds" } + + sink (vla); +} + +void test_int_vla_location (void) +{ + unsigned nelts = 7; + + int vla[nelts]; // { dg-message "declared here" } + + vla[0] = __LINE__; + vla[nelts] = 1; // { dg-warning "\\\[-Warray-bounds" } + + sink (vla); +} + +void test_struct_vla_location (void) +{ + unsigned nelts = 7; + + struct { + char cvla[nelts]; // { dg-message "declared here" } + int ivla[nelts]; // { dg-message "declared here" } + } s; + + s.cvla[0] = __LINE__; + s.cvla[nelts - 1] = 0; + s.cvla[nelts] = 0; // { dg-warning "\\\[-Warray-bounds" } + + s.ivla[0] = __LINE__; + s.ivla[nelts - 1] = 0; + s.ivla[nelts] = 0; // { dg-warning "\\\[-Warray-bounds" } + + sink (&s); +}