From patchwork Tue Nov 22 22:21:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 83512 Delivered-To: patch@linaro.org Received: by 10.140.97.165 with SMTP id m34csp2344123qge; Tue, 22 Nov 2016 14:21:39 -0800 (PST) X-Received: by 10.99.251.69 with SMTP id w5mr48189960pgj.124.1479853299814; Tue, 22 Nov 2016 14:21:39 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id e72si30324561pfl.77.2016.11.22.14.21.39 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 Nov 2016 14:21:39 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-442296-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-442296-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-442296-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:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=JpRO+asBxGR8aXvmFLGQ0RqMVhxBdEbqibR+d1E7B08cJOs3Pk j/WMVr6GDSufmioc3IXjTjjoL5SJpdqNn6M3EqT1oQ5z74Smx6ODgLZouKRL/jIE ee+eVRdSfMsOQ7oyG6sezwhw4Qc+D+Omgcf4rUuU5lv7jZ7ybYRyELiKY= 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=UlP9f+RfJb+IA+V0p78VZIxoMWw=; b=pVHYll1I80Eq0Vn4zTU1 Zp1lSIgw73p2GHud7IK44SvdG8cfjwfWQjfPGZInkxuCPINF1mEgRppJBFzjYIRx ytvfb3KJI3BK6VgEmcfIZhC2TUPtL3v3a1Ni0Br53m9jghijwmymBpgHeGu2G4Z8 WvOxQnFTQC8EQ20NK420PWs= Received: (qmail 123784 invoked by alias); 22 Nov 2016 22:21:24 -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 123770 invoked by uid 89); 22 Nov 2016 22:21:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 spammy=lieu, 169, bounded, exercised X-HELO: mail-qk0-f173.google.com Received: from mail-qk0-f173.google.com (HELO mail-qk0-f173.google.com) (209.85.220.173) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 22 Nov 2016 22:21:22 +0000 Received: by mail-qk0-f173.google.com with SMTP id x190so45485740qkb.0 for ; Tue, 22 Nov 2016 14:21:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version; bh=UdQNJEViojLzh4rx7LhHV+trqjofkPGEcKyAnV2QeYg=; b=SNdrcrx/eAUot9K/fB15CjBIxIrVPiJofO7NdnLcHJaXJKIHXn2+Q6+cT4MLSH+fPu BmlYDZDrbgQBYY3TUEZEELZN5OvOD3gzLSxMZgTTlT6ym9/ISTIixZBUK8mXIJJXyita Rm/np+Fk0D9nOt27Ddv3ZF1lSkMlNhZ7dTHmb3NtC77l82jFtCxJyFjqTFBuiLK8njnM IC1yGO2XSmz1TZUd6CfL7s5Q3ta7v7lctyAQRhwQeHqArsJr7ctpEhjsgobV8HkjhXLo 2UgupMua8nOLf1TmWh6d9sgRtY9mDpSByLLln5pylxikAGzyNGTj8bbTs1lldaHaMPp4 Rrmw== X-Gm-Message-State: AKaTC03uWrTX52eW07KPiG3HlKlfkPsvI6UXQw1rLnEnLM8k05K1mcch7A0zuk8iLEc7CQ== X-Received: by 10.55.39.88 with SMTP id n85mr24377144qkn.244.1479853280869; Tue, 22 Nov 2016 14:21:20 -0800 (PST) Received: from [192.168.0.26] (75-166-206-79.hlrn.qwest.net. [75.166.206.79]) by smtp.gmail.com with ESMTPSA id h46sm14758863qta.35.2016.11.22.14.21.20 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 Nov 2016 14:21:20 -0800 (PST) To: Gcc Patch List From: Martin Sebor Subject: [PATCH] 78461 - [7 Regression] ICE: in operator+=, at gimple-ssa-sprintf.c:214 Message-ID: Date: Tue, 22 Nov 2016 15:21:18 -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 With r242674 having enabled the -fprintf-return-value option by default, when warnings are disabled the gimple-ssa-sprintf pass is now exercised in ways it was not being tested. One of these untested use cases exposed a bug in the logic used to compute the minimum number of bytes output by a %.*s directive with a known precision and a string of unknown length. The bug manifested itself by triggering an ICE. The attached patch corrects this problem. Thanks Martin PR middle-end/78461 - [7 Regression] ICE: in operator+= gcc/testsuite/ChangeLog: PR middle-end/78461 * gcc.dg/tree-ssa/builtin-sprintf-4.c: New test. * gcc.dg/tree-ssa/builtin-sprintf-warn-2.c: Adjust warning text. gcc/ChangeLog: PR middle-end/78461 * gimple-ssa-sprintf.c (format_string): Correct the maxima and set the minimum number of bytes for an unknown string to zero. Index: gcc/gimple-ssa-sprintf.c =================================================================== --- gcc/gimple-ssa-sprintf.c (revision 242703) +++ gcc/gimple-ssa-sprintf.c (working copy) @@ -1533,18 +1533,15 @@ format_string (const conversion_spec &spec, tree a fmtresult res; /* The maximum number of bytes for an unknown wide character argument - to a "%lc" directive adjusted for precision but not field width. */ + to a "%lc" directive adjusted for precision but not field width. + 6 is the longest UTF-8 sequence for a single wide character. */ const unsigned HOST_WIDE_INT max_bytes_for_unknown_wc - = (1 == warn_format_length ? 0 <= prec ? prec : 0 - : 2 == warn_format_length ? 0 <= prec ? prec : 1 - : 0 <= prec ? prec : 6 /* Longest UTF-8 sequence. */); + = (0 <= prec ? prec : 1 < warn_format_length ? 6 : 1); /* The maximum number of bytes for an unknown string argument to either a "%s" or "%ls" directive adjusted for precision but not field width. */ const unsigned HOST_WIDE_INT max_bytes_for_unknown_str - = (1 == warn_format_length ? 0 <= prec ? prec : 0 - : 2 == warn_format_length ? 0 <= prec ? prec : 1 - : HOST_WIDE_INT_MAX); + = (0 <= prec ? prec : 1 < warn_format_length); /* The result is bounded unless overriddden for a non-constant string of an unknown length. */ @@ -1648,7 +1645,7 @@ format_string (const conversion_spec &spec, tree a if (0 <= prec) { if (slen.range.min >= target_int_max ()) - slen.range.min = max_bytes_for_unknown_str; + slen.range.min = 0; else if ((unsigned)prec < slen.range.min) slen.range.min = prec; Index: gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-4.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-4.c (revision 0) +++ gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-4.c (working copy) @@ -0,0 +1,69 @@ +/* PR middle-end/78461 - [7 Regression] ICE: in operator+=, at + gimple-ssa-sprintf.c:214 + Disable warnings to exercise code paths through the pass that may + not be exercised when the -Wformat-length option is in effect. */ +/* { dg-compile } + { dg-options "-O2 -fdump-tree-optimized -w" } */ + + +#define CAT(s, n) s ## n +#define FAIL(line) CAT (failure_on_line_, line) + +/* Emit a call to a function named failure_on_line_NNN when EXPR is false. */ +#define ASSERT(expr) \ + do { \ + extern void FAIL (__LINE__)(void); \ + if (!(expr)) FAIL (__LINE__)(); \ + } while (0) + +#define KEEP(line) CAT (keep_call_on_line_, line) + +/* Emit a call to a function named keep_call_on_line_NNN when EXPR is true. + Used to verify that the expression need not be the only one that holds. */ +#define ASSERT_MAYBE(expr) \ + do { \ + extern void KEEP (__LINE__)(void); \ + if (expr) KEEP (__LINE__)(); \ + } while (0) + +int f0 (const char *s) +{ + int n = __builtin_snprintf (0, 0, "%.*s%08x", 1, s, 1); + + ASSERT (7 < n && n < 10); + + ASSERT_MAYBE (8 == n); + ASSERT_MAYBE (9 == n); + + return n; +} + +char buf[64]; + +int f1 (const char *s) +{ + int n = __builtin_snprintf (buf, 64, "%.*s%08x", 1, s, 1); + + ASSERT (7 < n && n < 10); + + ASSERT_MAYBE (8 == n); + ASSERT_MAYBE (9 == n); + + return n; +} + +int f2 (const char *s) +{ + int n = __builtin_snprintf (0, 0, "%.*s", 2, s); + + ASSERT (0 <= n && n <= 2); + + ASSERT_MAYBE (0 == n); + ASSERT_MAYBE (1 == n); + ASSERT_MAYBE (2 == n); + + return n; +} + +/* { dg-final { scan-tree-dump-not "failure_on_line" "optimized"} } + { dg-final { scan-tree-dump-times "keep_call_on_line" 7 "optimized"} } */ Index: gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-2.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-2.c (revision 242703) +++ gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-2.c (working copy) @@ -93,10 +93,10 @@ void test_s_nonconst (const char *s, const wchar_t T (1, "%s", s); /* { dg-warning "nul past the end" "sprintf transformed into strcpy" { xfail *-*-* } } */ T (1, "%1s", s); /* { dg-warning "nul past the end" } */ T (1, "%.0s", s); - T (1, "%.1s", s); /* { dg-warning "writing a terminating nul" } */ + T (1, "%.1s", s); /* { dg-warning "may write a terminating nul" } */ T (1, "%.0ls", ws); - T (1, "%.1ls", ws); /* { dg-warning "writing a terminating nul" } */ + T (1, "%.1ls", ws); /* { dg-warning "may write a terminating nul" } */ T (1, "%ls", ws); /* { dg-warning "writing a terminating nul" } */ /* Verify that the size of the array is used in lieu of its length.