From patchwork Tue Oct 8 00:58:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 1173040 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-510438-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="M9h+1j24"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="hrUA1iWa"; 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 46nJrS1wsxz9s4Y for ; Tue, 8 Oct 2019 11:58:48 +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:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=V+IkCtpVUZ23bIrXMODXvhs+uMpw96VnaLA2DcM5OvXJIDfIWn /J2uubMQiR5iaR/K2gaAaM7Ar2XuHY/r5LNbB/8LipKtg4zAgF7YMNLN1lGbwric C2kf01MXSnJJGPWRnY8h64i87L7iCKC1Upxb2F8fosqadNJqbcQqYevtg= 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:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=rsTxxhx3nslPbPM2ssLaQfi6eVc=; b=M9h+1j24wPKXUGAvIOV7 2B3BuonfisOKvJJ0Mi3AJ1FIXJM1pj2ogQEYmf6HwYYd0advRWp9nO8A2yaDjYgO nr3KIMJvT/v5r+KDGYEGtzsnYd56HSusgtJPgLHAhHC3ehV1xZ7ESjIYyvSzSf/+ +dVeyfTKra0nBFYWc39G+p4= Received: (qmail 16477 invoked by alias); 8 Oct 2019 00:58:40 -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 16464 invoked by uid 89); 8 Oct 2019 00:58:40 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.6 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mail-io1-f44.google.com Received: from mail-io1-f44.google.com (HELO mail-io1-f44.google.com) (209.85.166.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 08 Oct 2019 00:58:39 +0000 Received: by mail-io1-f44.google.com with SMTP id b136so32926393iof.3 for ; Mon, 07 Oct 2019 17:58:38 -0700 (PDT) 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=u+9O/LSCYpc4T00FOfUQ/1JFrka6XT2POsm+xg08Eag=; b=hrUA1iWasVgD+D4fOfRTsmyT0zAQ0+iHfutakTSGXeLpt4m5a29FwDzgSh6Zfemk4l ZWYCu8uaRn4IM7heP+EjgITfSI6FcEcmf0cl3pl1Y4wEAeuf3cEIcti7HDcpvSbHEWYh wg92Xal0zb4r8sDUJUHEBspIorgmS5714swPD1W0ZvTxIi+rNBUuRHNJxJn9JVFa58o1 2vsxOMoFi+/AyLPQnaLodZ6DoCNI1pCAlpa722arTRr1EYaMY3/uT88sfeX3OHQWTI2Q A1nnbnudemGL2Hpaz5egi1vXbT7OUeC1XyOxbHYNGILt+YZa6h8NuYVRg+ng92yK3Znq ZImw== Received: from [192.168.0.41] ([71.218.12.255]) by smtp.gmail.com with ESMTPSA id h4sm6067089iom.17.2019.10.07.17.58.36 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 07 Oct 2019 17:58:36 -0700 (PDT) To: gcc-patches , Jeff Law From: Martin Sebor Subject: [PATCH] avoid a spurious -Wstringop-overflow due to multiple MEM_REFs (PR 92014) Message-ID: <71b5c989-dd1f-d753-505a-30618448a6df@gmail.com> Date: Mon, 7 Oct 2019 18:58:35 -0600 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 Last week's enhancement to detect one-byte buffer overflows exposed a bug that let the warning use the size of a prior MEM_REF access and "override" the size of the actual store to the character array. When the store was smaller than the prior access (e.g., one byte, vs an 8-byte null pointer read such as in a PHI), this would lead to a false positive. The attached patch has the function fail after it has determined the size of the store from a MEM_REF if one of its recursive invocations finds another MEM_REF. Tested on x86_64-linux. Since the bug is causing trouble in Glibc builds I will plan on committing the fix tomorrow. Martin PR middle-end/92014 - bogus warning: writing 8 bytes into a region of size 1 in timezone/zic.c gcc/ChangeLog: PR middle-end/92014 * tree-ssa-strlen.c (count_nonzero_bytes): Avoid recursing for MEM_REF again once nbytes has been set . gcc/testsuite/ChangeLog: PR middle-end/92014 * gcc.dg/Wstringop-overflow-19.c: New test. Index: gcc/testsuite/gcc.dg/Wstringop-overflow-19.c =================================================================== --- gcc/testsuite/gcc.dg/Wstringop-overflow-19.c (nonexistent) +++ gcc/testsuite/gcc.dg/Wstringop-overflow-19.c (working copy) @@ -0,0 +1,27 @@ +/* PR middle-end/92014 - bogus warning: writing 8 bytes into a region + of size 1 in timezone/zic.c + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +struct +{ + char *s1, *s2; + char c; +} z; + + +void f (char **a, int i, int j) +{ + char * cp = __builtin_strchr (a[i], '%'); + + if (cp && *++cp != 's') + return; + + z.s1 = __builtin_strdup (a[i]); + if (!z.s1) __builtin_abort (); + + z.s2 = __builtin_strdup (a[j]); + if (!z.s2) __builtin_abort (); + + z.c = cp ? *cp : '\0'; // { dg-bogus "\\\[-Wstringop-overflow" } +} Index: gcc/tree-ssa-strlen.c =================================================================== --- gcc/tree-ssa-strlen.c (revision 276657) +++ gcc/tree-ssa-strlen.c (working copy) @@ -3741,13 +3741,16 @@ int ssa_name_limit_t::next_ssa_name (tree ssa_name return 0; } -/* Determine the minimum and maximum number of leading non-zero bytes +/* 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. Set LENRANGE[2] to the total number of bytes in - the representation. Set *NULTREM if the representation contains - a zero byte, and set *ALLNUL if all the bytes are zero. Avoid - recursing deeper than the limits in SNLIM allow. Return true - on success and false otherwise. */ + 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. + 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. + Avoid recursing deeper than the limits in SNLIM allow. + Returns true on success and false otherwise. */ static bool count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset, @@ -3843,6 +3846,9 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_ if (TREE_CODE (exp) == MEM_REF) { + if (nbytes) + return false; + tree arg = TREE_OPERAND (exp, 0); tree off = TREE_OPERAND (exp, 1); @@ -3910,8 +3916,10 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_ lenrange[0] = 0; prep = NULL; } - else + else if (!nbytes) nbytes = repsize; + else if (nbytes < repsize) + return false; } if (!nbytes)