From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 110437 invoked by alias); 20 Feb 2020 00:27:04 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 110420 invoked by uid 89); 20 Feb 2020 00:27:03 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.9 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mail-qv1-f46.google.com Received: from mail-qv1-f46.google.com (HELO mail-qv1-f46.google.com) (209.85.219.46) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 20 Feb 2020 00:27:01 +0000 Received: by mail-qv1-f46.google.com with SMTP id q9so1093774qvu.7 for ; Wed, 19 Feb 2020 16:27:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=wgEYjnV1uWXUggzZWI+MWqtVbNL2x7kgPsDg0CYFOwQ=; b=u+Aa5mePO07caDddZZ55E9BdUzJnnTKsYijv/YX9KKIZpa2/cvB1GVsQlkX7mja5ja +fkykI/qmRnTQzhzJvXLNfOdE/JqrMrfeiZbOw3ls/HLgZWnhnmOdS8veXRfz+LhR6zQ YMGVZ2y8p9BCJ1qHyEC3Zc1ZZlnd1SSyFHHireUiwH0i0VHUin4ZcXPl5jNMgHMnrKpA vUBXmv3gaX9VWnRuBPdBbCCKV8eKkQJxaBA7l8q7q4wVb8cgqLJFhKcyIKUH8k0408mU dfy2VjGCFvth0kmJ3NnUp56RPVvU8VHsIxCfAXWS4UpK0Gp1T0Xch2XT5GFwpIgicEIX rtZw== Return-Path: Received: from [192.168.0.41] (174-16-112-158.hlrn.qwest.net. [174.16.112.158]) by smtp.gmail.com with ESMTPSA id o16sm907547qtr.28.2020.02.19.16.26.58 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 19 Feb 2020 16:26:59 -0800 (PST) To: gcc-patches From: Martin Sebor Subject: [PATCH] use pointer size rather than array size when storing the former (PR 93829) Message-ID: <864beb08-0073-cde2-ad21-a855a7bf7dc9@gmail.com> Date: Thu, 20 Feb 2020 00:27:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------77486FB6B4EAF3EBDC952FE5" X-IsSubscribed: yes X-SW-Source: 2020-02/txt/msg01140.txt.bz2 This is a multi-part message in MIME format. --------------77486FB6B4EAF3EBDC952FE5 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-length: 410 The buffer overflow detection for multi-char stores uses the size of a source array even when what's actually being accessed (read and stored) is a pointer to the array. That leads to incorrect warnings in some cases. The attached patch corrects the function that computes the size of the access to set it to that of a pointer instead if the source is an address expression. Tested on x86_64-linux. Martin --------------77486FB6B4EAF3EBDC952FE5 Content-Type: text/x-patch; name="gcc-93829.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="gcc-93829.diff" Content-length: 4036 PR middle-end/93829 - bogus -Wstringop-overflow on memcpy of a struct with a pointer member from another with a long string gcc/testsuite/ChangeLog: PR middle-end/93829 * gcc.dg/Wstringop-overflow-32.c: New test. gcc/ChangeLog: PR middle-end/93829 * tree-ssa-strlen.c (count_nonzero_bytes): Set the size to that of a pointer in the outermost ADDR_EXPRs. diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 9a88a85b07c..1cdb581a51f 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -4587,12 +4587,15 @@ int ssa_name_limit_t::next_ssa_name (tree ssa_name) /* Determines the minimum and maximum number of leading non-zero bytes in the representation of EXP and set LENRANGE[0] and LENRANGE[1] - to each. Sets LENRANGE[2] to the total number of bytes in - the representation. Sets *NULTREM if the representation contains - a zero byte, and sets *ALLNUL if all the bytes are zero. + to each. + Sets LENRANGE[2] to the total size of the access (which may be less + than LENRANGE[1] when what's being referenced by EXP is a pointer + rather than an array). + Sets *NULTREM if the representation contains a zero byte, and sets + *ALLNUL if all the bytes are zero. OFFSET and NBYTES are the offset into the representation and - the size of the access to it determined from a MEM_REF or zero - for other expressions. + the size of the access to it determined from an ADDR_EXPR (i.e., + a pointer) or MEM_REF or zero for other expressions. Uses RVALS to determine range information. Avoids recursing deeper than the limits in SNLIM allow. Returns true on success and false otherwise. */ @@ -4692,7 +4695,13 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset, } if (TREE_CODE (exp) == ADDR_EXPR) - exp = TREE_OPERAND (exp, 0); + { + /* If the size of the access hasn't been determined yet it's that + of a pointer. */ + if (!nbytes) + nbytes = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (exp))); + exp = TREE_OPERAND (exp, 0); + } if (TREE_CODE (exp) == SSA_NAME) { @@ -4788,9 +4797,10 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset, return false; if (!nbytes) - /* If NBYTES hasn't been determined earlier from MEM_REF, - set it here. It includes all internal nuls, including - the terminating one if the string has one. */ + /* If NBYTES hasn't been determined earlier, either from ADDR_EXPR + (i.e., it's the size of a pointer), or from MEM_REF (as the size + of the access), set it here to the size of the string, including + all internal and trailing nuls if the string has any. */ nbytes = nchars - offset; prep = TREE_STRING_POINTER (exp) + offset; diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-32.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-32.c new file mode 100644 index 00000000000..e5939567a4d --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-32.c @@ -0,0 +1,51 @@ +/* PR middle-end/93829 - bogus -Wstringop-overflow on memcpy of a struct + with a pointer member from another with a long string + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +extern void* memcpy (void*, const void*, __SIZE_TYPE__); + +#define S40 "0123456789012345678901234567890123456789" + +const char s40[] = S40; + +struct S +{ + const void *p, *q, *r; +} s, sa[2]; + + +void test_lit_decl (void) +{ + struct S t = { 0, S40, 0 }; + + memcpy (&s, &t, sizeof t); // { dg-bogus "-Wstringop-overflow" } +} + +void test_str_decl (void) +{ + struct S t = { 0, s40, 0 }; + + memcpy (&s, &t, sizeof t); // { dg-bogus "-Wstringop-overflow" } +} + + +void test_lit_ssa (int i) +{ + if (i < 1) + i = 1; + struct S *p = &sa[i]; + struct S t = { 0, S40, 0 }; + + memcpy (p, &t, sizeof t); // { dg-bogus "-Wstringop-overflow" } +} + +void test_str_ssa (int i) +{ + if (i < 1) + i = 1; + struct S *p = &sa[i]; + struct S t = { 0, s40, 0 }; + + memcpy (p, &t, sizeof t); // { dg-bogus "-Wstringop-overflow" } +} --------------77486FB6B4EAF3EBDC952FE5--