From patchwork Wed Jan 4 21:43:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 89915 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp8688155qgi; Wed, 4 Jan 2017 13:44:26 -0800 (PST) X-Received: by 10.84.210.167 with SMTP id a36mr151144187pli.125.1483566266626; Wed, 04 Jan 2017 13:44:26 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id p12si42597879pgd.152.2017.01.04.13.44.26 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Jan 2017 13:44:26 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-445410-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-445410-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-445410-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=quYxyd+W87TACBLBMNaZKdG72EzrVxlq5VrulijzPXfDt3mB3kn7e 3uEcVrLH6yX7bkOuuziPYhIN9exxxzjCeg0+a+bVfm/cG80AyaY7lfsTnJI9SSPu RSKOLGeFh8tZ5WLdqGYzYkDhd0mQlNkx69AMGKPDQ8UX84nz0swrgk= 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=C08z9lHH1IWhqEQJflAp3XKCuUQ=; b=Qd8hjNNSVUriGCjpY6p5 t8JYm6IThU2R1Tc7taOeLvqsknhnEHGve0Hnn7RGLsnj+R0yGWW7+CF0mw5ZN/AD WZI6tDCx77gtseE9J/zSOtIfv1VvwwojJhU19UMnHRJrgsB0LgBLjOfTKSjktaV5 asn42nf6BJfyAYu6bnqHxoM= Received: (qmail 94740 invoked by alias); 4 Jan 2017 21:44:04 -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 94712 invoked by uid 89); 4 Jan 2017 21:44:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy=10259, 338, 6, 3386, sk:printr X-HELO: mail-qt0-f176.google.com Received: from mail-qt0-f176.google.com (HELO mail-qt0-f176.google.com) (209.85.216.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 04 Jan 2017 21:44:01 +0000 Received: by mail-qt0-f176.google.com with SMTP id c47so503129443qtc.2 for ; Wed, 04 Jan 2017 13:44:01 -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=5sz1bJtsSGPvfstNndFHgWcYXx66WjRGEzU2SsvdKSE=; b=sylJ+uDLLMwW1puUgP+KYVS1QnIN9kDIpNvoRyuyaoJ+6A4MEps04GF9vrlN0syhhh eJbkkIa2dcpB+8tzsDh4wkLjnzkW1nV4juqhPpPTzU/KxafWF0zGEAsv73789i1yd++c 87OWShDvNhDT0ICAztTbKvs2oO2LdeuRvSuWcjTPfrwwfl8pSInTCurQJdvwaF6N3hxl b9rWV62DH5xhwvHsKB8HFl5HVCjDOOXRViPdbWQEBuXoO94nc9YwZeVbRKs1TChkjxAn m5TeLkwAY82MsbHDEHBcS2kbWjsAWA1BJwGMpRcwM/lmh3JfVYt4NwG65d5E79I1WUBq xbnA== X-Gm-Message-State: AIkVDXJD+oQihsce797HHJvCCxvqEoMN7u2KcBWgKeZQSuuOhpgc5PCV8MlwNPZz16EhVg== X-Received: by 10.200.36.125 with SMTP id d58mr61772090qtd.126.1483566239580; Wed, 04 Jan 2017 13:43:59 -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 21sm46764814qkh.4.2017.01.04.13.43.58 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Jan 2017 13:43:59 -0800 (PST) From: Martin Sebor Subject: [PATCH] correct off-by-one error in handling of precision of negative numbers (PR 78910) To: Gcc Patch List Message-ID: <92847957-b488-9f2f-96b8-e443b9d2882a@gmail.com> Date: Wed, 4 Jan 2017 14:43:57 -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 The attached patch corrects an off-by-one mistake in handling non-zero precisions in signed conversions (%d and %i) with negative arguments, such as in sprintf(d, "%.2", -1). The call which results in the three bytes "-01" on output, not 2. I.e., the minus sign must be taken into consideration. Thanks Martin PR tree-optimization/78910 - Wrong print-return-value for a negative number gcc/ChangeLog: PR tree-optimization/78910 * gimple-ssa-sprintf.c (tree_digits): Add an argument. (format_integer): Correct off-by-one error in the handling of precision with negative numbers in signed conversions.. gcc/testsuite/ChangeLog: PR tree-optimization/78910 * gcc.dg/tree-ssa/builtin-sprintf-warn-7.c: Adjust text of expected diagnostics. * gcc.dg/tree-ssa/builtin-sprintf.c: Add test cases. * gcc.dg/tree-ssa/pr78910.c: New test. diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index d468cd7..6a9f679 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -549,17 +549,18 @@ ilog (unsigned HOST_WIDE_INT x, int base) } /* Return the number of bytes resulting from converting into a string - the INTEGER_CST tree node X in BASE. PLUS indicates whether 1 for - a plus sign should be added for positive numbers, and PREFIX whether - the length of an octal ('O') or hexadecimal ('0x') prefix should be - added for nonzero numbers. Return -1 if X cannot be represented. */ - -static int -tree_digits (tree x, int base, bool plus, bool prefix) + the INTEGER_CST tree node X in BASE with a minimum of PREC digits. + PLUS indicates whether 1 for a plus sign should be added for positive + numbers, and PREFIX whether the length of an octal ('O') or hexadecimal + ('0x') prefix should be added for nonzero numbers. Return -1 if X cannot + be represented. */ + +static HOST_WIDE_INT +tree_digits (tree x, int base, HOST_WIDE_INT prec, bool plus, bool prefix) { unsigned HOST_WIDE_INT absval; - int res; + HOST_WIDE_INT res; if (TYPE_UNSIGNED (TREE_TYPE (x))) { @@ -591,7 +592,9 @@ tree_digits (tree x, int base, bool plus, bool prefix) return -1; } - res += ilog (absval, base); + int ndigs = ilog (absval, base); + + res += prec < ndigs ? ndigs : prec; if (prefix && absval) { @@ -1022,10 +1025,9 @@ format_integer (const conversion_spec &spec, tree arg) /* True when a conversion is preceded by a prefix indicating the base of the argument (octal or hexadecimal). */ bool maybebase = spec.get_flag ('#'); - len = tree_digits (arg, base, maybesign, maybebase); - - if (len < prec) - len = prec; + len = tree_digits (arg, base, prec, maybesign, maybebase); + if (len < 1) + len = HOST_WIDE_INT_MAX; } if (len < width) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-7.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-7.c index 7787255..e087a8f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-7.c @@ -35,11 +35,16 @@ void test_integer_var (int i) T (0, "%*d", INT_MAX, i); /* { dg-warning "writing 2147483647 bytes" } */ T (0, "%.*d", INT_MIN, i); /* { dg-warning "writing between 1 and 11 bytes" } */ - T (0, "%.*d", INT_MAX, i); /* { dg-warning "writing 2147483647 bytes" } */ + + /* The following writes INT_MAX digits and, when i is negative, a minus + sign. */ + T (0, "%.*d", INT_MAX, i); /* { dg-warning "writing between 2147483647 and 2147483648 bytes" } */ T (0, "%*.*d", INT_MIN, INT_MIN, i); /* { dg-warning "writing 2147483648 bytes" } */ - T (0, "%*.*d", INT_MAX, INT_MAX, i); /* { dg-warning "writing 2147483647 bytes" } */ + /* The following writes INT_MAX digits and, when i is negative, a minus + sign. */ + T (0, "%*.*d", INT_MAX, INT_MAX, i); /* { dg-warning "writing between 2147483647 and 2147483648 bytes" } */ } void test_floating_a_cst (void) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf.c index 96892c1..275cb28 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf.c @@ -319,17 +319,61 @@ test_d_i (int i, long li) RNG ( 1, 6, 7, "%hi", i); RNG ( 1, 5, 6, "%hu", i); + RNG ( 1, 6, 7, "%.1hi", i); + RNG ( 2, 6, 7, "%.2hi", i); + RNG ( 3, 6, 7, "%.3hi", i); + RNG ( 4, 6, 7, "%.4hi", i); + RNG ( 5, 6, 7, "%.5hi", i); + RNG ( 6, 7, 8, "%.6hi", i); + RNG ( 7, 8, 9, "%.7hi", i); + #elif __SIZEOF_SHORT__ == 4 RNG ( 1, 11, 12, "%hi", i); RNG ( 1, 10, 11, "%hu", i); + + RNG ( 1, 11, 12, "%.1hi", i); + RNG ( 2, 11, 12, "%.2hi", i); + RNG ( 3, 11, 12, "%.3hi", i); + RNG ( 4, 11, 12, "%.4hi", i); + RNG ( 5, 11, 12, "%.5hi", i); + RNG ( 6, 11, 12, "%.6hi", i); + RNG ( 7, 11, 12, "%.7hi", i); + RNG ( 8, 11, 12, "%.8hi", i); + RNG ( 9, 11, 12, "%.9hi", i); + RNG (10, 11, 12, "%.10hi", i); + RNG (11, 12, 13, "%.11hi", i); + RNG (12, 13, 14, "%.12hi", i); + RNG (13, 14, 15, "%.13hi", i); #endif #if __SIZEOF_INT__ == 2 RNG ( 1, 6, 7, "%i", i); RNG ( 1, 5, 6, "%u", i); + + RNG ( 1, 6, 7, "%.1i", i); + RNG ( 2, 6, 7, "%.2i", i); + RNG ( 3, 6, 7, "%.3i", i); + RNG ( 4, 6, 7, "%.4i", i); + RNG ( 5, 6, 7, "%.5i", i); + RNG ( 6, 7, 8, "%.6i", i); + RNG ( 7, 8, 9, "%.7i", i); #elif __SIZEOF_INT__ == 4 RNG ( 1, 11, 12, "%i", i); RNG ( 1, 10, 11, "%u", i); + + RNG ( 1, 11, 12, "%.1i", i); + RNG ( 2, 11, 12, "%.2i", i); + RNG ( 3, 11, 12, "%.3i", i); + RNG ( 4, 11, 12, "%.4i", i); + RNG ( 5, 11, 12, "%.5i", i); + RNG ( 6, 11, 12, "%.6i", i); + RNG ( 7, 11, 12, "%.7i", i); + RNG ( 8, 11, 12, "%.8i", i); + RNG ( 9, 11, 12, "%.9i", i); + RNG (10, 11, 12, "%.10i", i); + RNG (11, 12, 13, "%.11i", i); + RNG (12, 13, 14, "%.12i", i); + RNG (13, 14, 15, "%.13i", i); #elif __SIZEOF_INT__ == 8 RNG ( 1, 20, 21, "%i", i); RNG ( 1, 19, 20, "%u", i); @@ -338,6 +382,20 @@ test_d_i (int i, long li) #if __SIZEOF_LONG__ == 4 RNG ( 1, 11, 12, "%li", li); RNG ( 1, 10, 11, "%lu", li); + + RNG ( 1, 11, 12, "%.1li", li); + RNG ( 2, 11, 12, "%.2li", li); + RNG ( 3, 11, 12, "%.3li", li); + RNG ( 4, 11, 12, "%.4li", li); + RNG ( 5, 11, 12, "%.5li", li); + RNG ( 6, 11, 12, "%.6li", li); + RNG ( 7, 11, 12, "%.7li", li); + RNG ( 8, 11, 12, "%.8li", li); + RNG ( 9, 11, 12, "%.9li", li); + RNG (10, 11, 12, "%.10li", li); + RNG (11, 12, 13, "%.11li", li); + RNG (12, 13, 14, "%.12li", li); + RNG (13, 14, 15, "%.13li", li); #elif __SIZEOF_LONG__ == 8 RNG ( 1, 20, 21, "%li", li); RNG ( 1, 19, 20, "%lu", li); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr78910.c b/gcc/testsuite/gcc.dg/tree-ssa/pr78910.c new file mode 100644 index 0000000..ba5216e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr78910.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/78910 - Wrong print-return-value for a negative number + { dg-do compile } + { dg-options "-O2 -fdump-tree-optimized" } */ + +int main() +{ + char b[128]; + int l = __builtin_sprintf (b, "%.2d", -1); + __builtin_printf ("b: '%s', length: %d\n", b, l); + if (l != 3) + __builtin_abort (); + return 0; +} + +/* { dg-final { scan-tree-dump-not "abort" "optimized"} } */