diff mbox

avoid assuming all integers are representable in HOST_WIDE_INT (PR #80497)

Message ID fcb54c22-615a-a6b0-39b0-aeb15d1001ec@gmail.com
State New
Headers show

Commit Message

Martin Sebor April 24, 2017, 11:35 p.m. UTC
Bug 80497 brings to light that my fix for PR 80364 where I corrected
the handling for int128_t was incomplete.  I handled the non-constant
case but missed the INTEGER_CST case just a few lines above.  The
attached patch also corrects that problem plus one more elsewhere
in the pass.

Both of the changes in this patch seem safe enough to make even now
in GCC 7 but since they are ice-on-invalid-code perhaps it's better
to wait for 7.1?

Martin

Comments

Jeff Law April 25, 2017, 2:24 p.m. UTC | #1
On 04/24/2017 05:35 PM, Martin Sebor wrote:
> Bug 80497 brings to light that my fix for PR 80364 where I corrected
> the handling for int128_t was incomplete.  I handled the non-constant
> case but missed the INTEGER_CST case just a few lines above.  The
> attached patch also corrects that problem plus one more elsewhere
> in the pass.
> 
> Both of the changes in this patch seem safe enough to make even now
> in GCC 7 but since they are ice-on-invalid-code perhaps it's better
> to wait for 7.1?
> 
> Martin
> 
> gcc-80497.diff
> 
> 
> PR tree-optimization/80497 - ICE at -O1 and above on valid code on x86_64-linux-gnu in tree_to_uhwi
> 
> gcc/ChangeLog:
> 
> 	PR tree-optimization/80497
> 	* gimple-ssa-sprintf.c (get_int_range): Avoid assuming all integer
> 	constants are representable in HOST_WIDE_INT.
> 	(parse_directive): Ditto.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR tree-optimization/80497
> 	* gcc.dg/tree-ssa/builtin-sprintf-warn-17.c: New test.
OK for the trunk.  Jakub's call on when it's OK for the branch -- one 
can easily argue this is a regression.

jeff
Jakub Jelinek April 25, 2017, 2:29 p.m. UTC | #2
On Tue, Apr 25, 2017 at 08:24:32AM -0600, Jeff Law wrote:
> On 04/24/2017 05:35 PM, Martin Sebor wrote:
> > Bug 80497 brings to light that my fix for PR 80364 where I corrected
> > the handling for int128_t was incomplete.  I handled the non-constant
> > case but missed the INTEGER_CST case just a few lines above.  The
> > attached patch also corrects that problem plus one more elsewhere
> > in the pass.
> > 
> > Both of the changes in this patch seem safe enough to make even now
> > in GCC 7 but since they are ice-on-invalid-code perhaps it's better
> > to wait for 7.1?
> > 
> > Martin
> > 
> > gcc-80497.diff
> > 
> > 
> > PR tree-optimization/80497 - ICE at -O1 and above on valid code on x86_64-linux-gnu in tree_to_uhwi
> > 
> > gcc/ChangeLog:
> > 
> > 	PR tree-optimization/80497
> > 	* gimple-ssa-sprintf.c (get_int_range): Avoid assuming all integer
> > 	constants are representable in HOST_WIDE_INT.
> > 	(parse_directive): Ditto.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > 	PR tree-optimization/80497
> > 	* gcc.dg/tree-ssa/builtin-sprintf-warn-17.c: New test.
> OK for the trunk.  Jakub's call on when it's OK for the branch -- one can
> easily argue this is a regression.

Ok for 7.1 if you manage to commit before 7.1rc1, otherwise ok for 7.2.

	Jakub
diff mbox

Patch

PR tree-optimization/80497 - ICE at -O1 and above on valid code on x86_64-linux-gnu in tree_to_uhwi

gcc/ChangeLog:

	PR tree-optimization/80497
	* gimple-ssa-sprintf.c (get_int_range): Avoid assuming all integer
	constants are representable in HOST_WIDE_INT.
	(parse_directive): Ditto.

gcc/testsuite/ChangeLog:

	PR tree-optimization/80497
	* gcc.dg/tree-ssa/builtin-sprintf-warn-17.c: New test.

diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index 2e62086..d3771dd 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -948,7 +948,8 @@  get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
       *pmin = tree_to_shwi (TYPE_MIN_VALUE (type));
       *pmax = tree_to_shwi (TYPE_MAX_VALUE (type));
     }
-  else if (TREE_CODE (arg) == INTEGER_CST)
+  else if (TREE_CODE (arg) == INTEGER_CST
+	   && TYPE_PRECISION (TREE_TYPE (arg)) <= TYPE_PRECISION (type))
     {
       /* For a constant argument return its value adjusted as specified
 	 by NEGATIVE and NEGBOUND and return true to indicate that the
@@ -2916,7 +2917,9 @@  parse_directive (pass_sprintf_length::call_info &info,
       if (width != -1)
 	dollar = width + info.argidx;
       else if (star_width
-	       && TREE_CODE (star_width) == INTEGER_CST)
+	       && TREE_CODE (star_width) == INTEGER_CST
+	       && (TYPE_PRECISION (TREE_TYPE (star_width))
+		   <= TYPE_PRECISION (integer_type_node)))
 	dollar = width + tree_to_shwi (star_width);
 
       /* Bail when the numbered argument is out of range (it will
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-17.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-17.c
new file mode 100644
index 0000000..27aa839
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-17.c
@@ -0,0 +1,42 @@ 
+/* PR tree-optimization/80497 - ICE at -O1 and above on valid code on
+   x86_64-linux-gnu in "tree_to_uhwi"
+   { dg-do compile }
+   { dg-options "-O2 -Wall -Wformat-overflow" }
+   { dg-require-effective-target int128 } */
+
+extern char buf[];
+
+const __int128_t sint128_max
+  = (__int128_t)1 << (sizeof sint128_max * __CHAR_BIT__ - 2);
+
+void fn0 (void)
+{
+  __int128_t si128 = 0;
+
+  __builtin_sprintf (buf, "%*i", si128, 0);
+
+  __builtin_sprintf (buf, "%.*i", si128, 0);
+
+  __builtin_sprintf (buf, "%i", si128);
+
+  __builtin_sprintf (buf, "%2$*1$i", si128, 0);
+
+  __builtin_sprintf (buf, "%2$.*1$i", si128, 0);
+}
+
+void fn1 (void)
+{
+  __int128_t si128 = sint128_max;
+
+  __builtin_sprintf (buf, "%*i", si128, 0);
+
+  __builtin_sprintf (buf, "%.*i", si128, 0);
+
+  __builtin_sprintf (buf, "%i", si128);
+
+  __builtin_sprintf (buf, "%2$*1$i", si128, 0);
+
+  __builtin_sprintf (buf, "%2$.*1$i", si128, 0);
+}
+
+/* { dg-prune-output "expects argument of type .int." } */