diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/gimple-ssa-sprintf.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr83198.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr83198.c | 23 |
5 files changed, 59 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e33b45f..f4b61eb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-12-14 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/83198 + * gimple-ssa-sprintf.c (format_floating): Set type solely based on + dir.modifier, regardless of TREE_TYPE (arg). Assume non-REAL_CST + value if arg is a REAL_CST with incompatible type. + 2017-12-14 Sudakshina Das <sudi.das@arm.com> Bin Cheng <bin.cheng@arm.com> diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index 35ceb2c..75935be 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -1885,6 +1885,8 @@ static fmtresult format_floating (const directive &dir, tree arg) { HOST_WIDE_INT prec[] = { dir.prec[0], dir.prec[1] }; + tree type = (dir.modifier == FMT_LEN_L || dir.modifier == FMT_LEN_ll + ? long_double_type_node : double_type_node); /* For an indeterminate precision the lower bound must be assumed to be zero. */ @@ -1892,10 +1894,6 @@ format_floating (const directive &dir, tree arg) { /* Get the number of fractional decimal digits needed to represent the argument without a loss of accuracy. */ - tree type = arg ? TREE_TYPE (arg) : - (dir.modifier == FMT_LEN_L || dir.modifier == FMT_LEN_ll - ? long_double_type_node : double_type_node); - unsigned fmtprec = REAL_MODE_FORMAT (TYPE_MODE (type))->p; @@ -1946,7 +1944,9 @@ format_floating (const directive &dir, tree arg) } } - if (!arg || TREE_CODE (arg) != REAL_CST) + if (!arg + || TREE_CODE (arg) != REAL_CST + || !useless_type_conversion_p (type, TREE_TYPE (arg))) return format_floating (dir, prec); /* The minimum and maximum number of bytes produced by the directive. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 51f7b33..939e4a9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-12-14 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/83198 + * gcc.dg/pr83198.c: New test. + * gcc.dg/tree-ssa/pr83198.c: New test. + 2017-12-14 Sudakshina Das <sudi.das@arm.com> PR target/81228 diff --git a/gcc/testsuite/gcc.dg/pr83198.c b/gcc/testsuite/gcc.dg/pr83198.c new file mode 100644 index 0000000..856f2be --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr83198.c @@ -0,0 +1,18 @@ +/* PR tree-optimization/83198 */ +/* { dg-do compile } */ +/* { dg-options "-Wall -Wno-format" } */ + +int +foo (char *d[6], int x) +{ + int r = 0; + r += __builtin_sprintf (d[0], "%f", x); + r += __builtin_sprintf (d[1], "%a", x); + r += __builtin_sprintf (d[2], "%f", "foo"); + r += __builtin_sprintf (d[3], "%a", "bar"); +#ifdef __SIZEOF_FLOAT128__ + r += __builtin_sprintf (d[4], "%a", 1.0Q); + r += __builtin_sprintf (d[5], "%Lf", 1.0Q); +#endif + return r; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr83198.c b/gcc/testsuite/gcc.dg/tree-ssa/pr83198.c new file mode 100644 index 0000000..f9dba2a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83198.c @@ -0,0 +1,23 @@ +/* PR tree-optimization/83198 */ +/* { dg-do compile { target __float128 } } */ +/* { dg-options "-O2 -fprintf-return-value -Wno-format -fdump-tree-optimized" } */ +/* { dg-add-options __float128 } */ + +void bar (void); +void link_error (void); + +void +foo (char *x) +{ + int a = __builtin_sprintf (x, "%f", 1.0Q); + if (a < 8) + link_error (); + if (a > 13) + bar (); + if (a > 322) + link_error (); +} + +/* Verify we don't optimize return value to [8, 13]. */ +/* { dg-final { scan-tree-dump-not "link_error \\(\\);" "optimized" } } */ +/* { dg-final { scan-tree-dump "bar \\(\\);" "optimized" } } */ |