From patchwork Thu Jan 5 21:53:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 90076 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp9172227qgi; Thu, 5 Jan 2017 13:53:48 -0800 (PST) X-Received: by 10.98.212.23 with SMTP id a23mr64542735pfh.94.1483653228062; Thu, 05 Jan 2017 13:53:48 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id r39si77243260pld.50.2017.01.05.13.53.47 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Jan 2017 13:53:48 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-445490-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-445490-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-445490-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE dis=NONE) header.from=gmail.com 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=EdNV3e4Vlt7h+IaqW83FWSl6Eje/8Ta0g6KxodRtkCsnz6XEdAFIP za1Dt14JaKHr0tlq6TbYaZ4/NoodjZcyRevaVUQQElL0Zg2lZDMgQLV0msw3LiE+ 3QL/AS8Tz+KFaT3JqEnDl6hU/Yej82fdPxa+LKf3p7fhKiz4iP5KRo= 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=pwE1o/sp8ycXjqRCrppfW2EyLg0=; b=OQLfxQ9ZOqQaM3EqDBla iEHqwRa3n40iZU2RPWq9cVbqWuNvoIftwJF4egDxRjA0MA6ZBdhz8g9co6RqfxmZ bcmV7sAq3Hb7eUQdHfhrEoQ7ywKlheYXa1Eai6jaa6Kk3xeNSOaefAm6PdI3yLje Cu8oBxNVRaDrZe5dMLbibV8= Received: (qmail 3581 invoked by alias); 5 Jan 2017 21:53:33 -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 3568 invoked by uid 89); 5 Jan 2017 21:53:32 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=no version=3.3.2 spammy=sk:wide_in, antirange, anti-range, H*M:a7a5 X-HELO: mail-qk0-f177.google.com Received: from mail-qk0-f177.google.com (HELO mail-qk0-f177.google.com) (209.85.220.177) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 05 Jan 2017 21:53:31 +0000 Received: by mail-qk0-f177.google.com with SMTP id s140so34279073qke.0 for ; Thu, 05 Jan 2017 13:53:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:subject:to:message-id:date:user-agent :mime-version; bh=4e+GcVf5wMqKzBFOlN4PTu972vhqJLotYYq0R/2HH78=; b=SnLVuSWxygo4AJmOediEtvGurKnmi1zIgNuJuJCoQowDFCFA55fSPGcRpBFjhVtL5+ eJXXCeiCxZ3QbtKmimwCedOhjdzl20BsTlr1YBBUf+0W0VcUSdeMq/MjrLP1+p0pF/uY I1uGBwNd3iOHl7Q5SL345oO0YSzE7UFWevdwLcwJl5u9YYJkxHD1Qe0P/37eRwWLFZLu QVR366JqOUhq4nCTia8Sc7JgN8YuT1U5gyTXplg9jCXPYQyZL8XS5zmWLYSm+azia6s0 IXhIgA3WwEDN3ImvS9Ta1BZ9g3/DdobwAIbVHlq2qgxEt8SN66J3kbQluug89wLf6M7p SUsw== X-Gm-Message-State: AIkVDXIhILm5dtBk4dz1vue7uiZ5G+mxXdZXmdzgJ43GxLapsvoUvczfSNadB9dKccrFXQ== X-Received: by 10.55.104.22 with SMTP id d22mr58216425qkc.127.1483653209382; Thu, 05 Jan 2017 13:53:29 -0800 (PST) Received: from [192.168.0.26] (71-212-249-238.hlrn.qwest.net. [71.212.249.238]) by smtp.gmail.com with ESMTPSA id z22sm49050859qkb.22.2017.01.05.13.53.28 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Jan 2017 13:53:28 -0800 (PST) From: Martin Sebor Subject: [PATCH] avoid false positives due to signed to unsigned conversion (PR 78973) To: Gcc Patch List Message-ID: <6ee328c6-788a-8f87-a7a5-c6412e4223ea@gmail.com> Date: Thu, 5 Jan 2017 14:53:27 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 MIME-Version: 1.0 X-IsSubscribed: yes When the size passed to a call to a function like memcpy is a signed integer whose range has a negative lower bound and a positive upper bound the lower bound of the range of the argument after conversion to size_t may be in excess of the maximum object size (PTRDIFF_MAX by default). This results in -Wstringop-overflow false positives. The attached patch detects this case and avoids the problem. Btw., I had a heck of a time creating a test case for this. The large translation unit submitted with the bug is from a file in the Linux kernel of some complexity. There, the range of the int variable (before conversion to size_t) is [INT_MIN, INT_MAX]. It seems very difficult to create a VR_RANGE for a signed int that matches it. The test case I came up with that still reproduces the false positive crates an anti-range for the signed int argument by converting an unsigned int in one range to a signed int and constraining it to another range. The false positive is avoided because the code doesn't (yet) handle anti-ranges. Martin PS This seems lie a bug or gotcha in the get_range_info() function. In the regression test added by the patch the VRP dump shows the following: n.0_1: ~[0, 4] _6: [18446744071562067968, +INF] ... _6 = (long unsigned int) n.0_1; __builtin_memset (d_5(D), 0, _6); but get_range_info(_6) returns the VR_RANGE: [ 0xffffffff:80000000, 0xffffffff:ffffffff ] That doesn't seem right. Is there a better/more appropriate way to determine the "correct" range? If not, perhaps get_range_info should be enhanced to make it possible to call it to detect this conversion and report a more correct result (e.g., based on a new, optional argument). Martin PR c/78973 - [7.0 regression] warning: ‘memcpy’: specified size between 18446744071562067968 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=] gcc/ChangeLog: PR c/78973 * builtins.c (get_size_range): Handle signed to unsigned conversion. gcc/testsuite/ChangeLog: PR c/78973 * gcc.dg/pr78973.c: New test. diff --git a/gcc/builtins.c b/gcc/builtins.c index 5b76dfd..883d25c 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -3051,9 +3051,26 @@ get_size_range (tree exp, tree range[2]) if (range_type == VR_RANGE) { + /* The range can be the result of a conversion of a signed + variable to size_t with the lower bound after conversion + corresponding to a negative lower bound of the original + variable. Avoid the false positive for this case. */ + gimple *def = SSA_NAME_DEF_STMT (exp); + if (is_gimple_assign (def)) + { + tree_code code = gimple_assign_rhs_code (def); + if (code == NOP_EXPR) + { + tree rhs = gimple_assign_rhs1 (def); + if (!TYPE_UNSIGNED (TREE_TYPE (rhs))) + return get_size_range (rhs, range); + } + } + /* Interpret the bound in the variable's type. */ range[0] = wide_int_to_tree (TREE_TYPE (exp), min); range[1] = wide_int_to_tree (TREE_TYPE (exp), max); + return true; } else if (range_type == VR_ANTI_RANGE) diff --git a/gcc/testsuite/gcc.dg/pr78973.c b/gcc/testsuite/gcc.dg/pr78973.c new file mode 100644 index 0000000..ef212cf --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr78973.c @@ -0,0 +1,18 @@ +/* PR c/78973 - [7.0 regression] warning: ‘memcpy’: specified size between + 18446744071562067968 and 18446744073709551615 exceeds maximum object + size 9223372036854775807 [-Wstringop-overflow=] + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +void f (void *p, int n) +{ + if (n <= 4) + __builtin_memset (p, 0, n); /* { dg-bogus "exceeds maximum object size" } */ +} + +void g (void *d, unsigned n) +{ + if (n < 5) + n = 5; + f (d, n); +}