re PR tree-optimization/83198 (ICE in format_floating, at gimple-ssa-sprintf.c:1900)
authorJakub Jelinek <jakub@redhat.com>
Thu, 14 Dec 2017 11:01:17 +0000 (12:01 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 14 Dec 2017 11:01:17 +0000 (12:01 +0100)
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.

* gcc.dg/pr83198.c: New test.
* gcc.dg/tree-ssa/pr83198.c: New test.

From-SVN: r255626

gcc/ChangeLog
gcc/gimple-ssa-sprintf.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr83198.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr83198.c [new file with mode: 0644]

index e33b45f34eaeec16ad7dc2f588c5bcfbc8c88334..f4b61eb6b1c9fab09bf7d2bf1f1cdddd538addc4 100644 (file)
@@ -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>
 
index 35ceb2cfb75914d26f4245ce25cda0205c4edd8a..75935bef5e8e0bd76355b5fa4bf8712c5c48bfa3 100644 (file)
@@ -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.  */
index 51f7b33e840362dfdda48787915648bf0229a4c9..939e4a9a149a6ec81cf8f498975bedbd95896f67 100644 (file)
@@ -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 (file)
index 0000000..856f2be
--- /dev/null
@@ -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 (file)
index 0000000..f9dba2a
--- /dev/null
@@ -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" } } */