mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
4e89adf970
commit
5b8999d67e
|
|
@ -1,3 +1,10 @@
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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
|
static HOST_WIDE_INT
|
||||||
tree_digits (tree x, int base, bool plus, bool prefix)
|
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)
|
||||||
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)
|
||||||
/* 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)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
|
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)
|
||||||
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)
|
||||||
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)
|
||||||
#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);
|
||||||
|
|
|
||||||
|
|
@ -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"} } */
|
||||||
Loading…
Reference in New Issue