Commit 5b8999d6 by Martin Sebor Committed by Martin Sebor

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.

From-SVN: r244116
parent 4e89adf9
2017-01-05 Martin Sebor <msebor@redhat.com>
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..
2017-01-05 Eric Botcazou <ebotcazou@adacore.com> 2017-01-05 Eric Botcazou <ebotcazou@adacore.com>
* doc/invoke.texi (C Dialect Options): Document it. * doc/invoke.texi (C Dialect Options): Document it.
......
...@@ -549,17 +549,18 @@ ilog (unsigned HOST_WIDE_INT x, int base) ...@@ -549,17 +549,18 @@ ilog (unsigned HOST_WIDE_INT x, int base)
} }
/* Return the number of bytes resulting from converting into a string /* Return the number of bytes resulting from converting into a string
the INTEGER_CST tree node X in BASE. PLUS indicates whether 1 for the INTEGER_CST tree node X in BASE with a minimum of PREC digits.
a plus sign should be added for positive numbers, and PREFIX whether PLUS indicates whether 1 for a plus sign should be added for positive
the length of an octal ('O') or hexadecimal ('0x') prefix should be numbers, and PREFIX whether the length of an octal ('O') or hexadecimal
added for nonzero numbers. Return -1 if X cannot be represented. */ ('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) static HOST_WIDE_INT
tree_digits (tree x, int base, HOST_WIDE_INT prec, bool plus, bool prefix)
{ {
unsigned HOST_WIDE_INT absval; unsigned HOST_WIDE_INT absval;
int res; HOST_WIDE_INT res;
if (TYPE_UNSIGNED (TREE_TYPE (x))) if (TYPE_UNSIGNED (TREE_TYPE (x)))
{ {
...@@ -591,7 +592,9 @@ tree_digits (tree x, int base, bool plus, bool prefix) ...@@ -591,7 +592,9 @@ tree_digits (tree x, int base, bool plus, bool prefix)
return -1; return -1;
} }
res += ilog (absval, base); int ndigs = ilog (absval, base);
res += prec < ndigs ? ndigs : prec;
if (prefix && absval) if (prefix && absval)
{ {
...@@ -1022,10 +1025,9 @@ format_integer (const conversion_spec &spec, tree arg) ...@@ -1022,10 +1025,9 @@ format_integer (const conversion_spec &spec, tree arg)
/* True when a conversion is preceded by a prefix indicating the base /* True when a conversion is preceded by a prefix indicating the base
of the argument (octal or hexadecimal). */ of the argument (octal or hexadecimal). */
bool maybebase = spec.get_flag ('#'); bool maybebase = spec.get_flag ('#');
len = tree_digits (arg, base, maybesign, maybebase); len = tree_digits (arg, base, prec, maybesign, maybebase);
if (len < 1)
if (len < prec) len = HOST_WIDE_INT_MAX;
len = prec;
} }
if (len < width) if (len < width)
......
2017-01-05 Martin Sebor <msebor@redhat.com>
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.
2017-01-05 Eric Botcazou <ebotcazou@adacore.com> 2017-01-05 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/sso-10.c: New test. * gcc.dg/sso-10.c: New test.
......
...@@ -35,11 +35,16 @@ void test_integer_var (int i) ...@@ -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_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_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_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) void test_floating_a_cst (void)
......
...@@ -319,17 +319,61 @@ test_d_i (int i, long li) ...@@ -319,17 +319,61 @@ test_d_i (int i, long li)
RNG ( 1, 6, 7, "%hi", i); RNG ( 1, 6, 7, "%hi", i);
RNG ( 1, 5, 6, "%hu", 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 #elif __SIZEOF_SHORT__ == 4
RNG ( 1, 11, 12, "%hi", i); RNG ( 1, 11, 12, "%hi", i);
RNG ( 1, 10, 11, "%hu", 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 #endif
#if __SIZEOF_INT__ == 2 #if __SIZEOF_INT__ == 2
RNG ( 1, 6, 7, "%i", i); RNG ( 1, 6, 7, "%i", i);
RNG ( 1, 5, 6, "%u", 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 #elif __SIZEOF_INT__ == 4
RNG ( 1, 11, 12, "%i", i); RNG ( 1, 11, 12, "%i", i);
RNG ( 1, 10, 11, "%u", 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 #elif __SIZEOF_INT__ == 8
RNG ( 1, 20, 21, "%i", i); RNG ( 1, 20, 21, "%i", i);
RNG ( 1, 19, 20, "%u", i); RNG ( 1, 19, 20, "%u", i);
...@@ -338,6 +382,20 @@ test_d_i (int i, long li) ...@@ -338,6 +382,20 @@ test_d_i (int i, long li)
#if __SIZEOF_LONG__ == 4 #if __SIZEOF_LONG__ == 4
RNG ( 1, 11, 12, "%li", li); RNG ( 1, 11, 12, "%li", li);
RNG ( 1, 10, 11, "%lu", 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 #elif __SIZEOF_LONG__ == 8
RNG ( 1, 20, 21, "%li", li); RNG ( 1, 20, 21, "%li", li);
RNG ( 1, 19, 20, "%lu", li); RNG ( 1, 19, 20, "%lu", li);
......
/* 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"} } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment