diff mbox

fix ICE on %lf directive in format_floating in gimple-ssa-sprintf.c (middle-end/77683)

Message ID 233b7261-7c27-5730-6f6f-b9143cd987a6@gmail.com
State New
Headers show

Commit Message

Martin Sebor Sept. 21, 2016, 8:47 p.m. UTC
The attached patch corrects the handling of the 'l' length modifier
for floating point directives (such as %lf) where it's specified to
have no effect.  It also replaces the gcc_unreachable() macro with
a return statement telling the pass to give up on unknown length
modifiers (rather than abort).

Martin
diff mbox

Patch

PR middle-end/77683 - ICE on %lf directive in format_floating in
  gimple-ssa-sprintf.c:1163

gcc/testsuite/ChangeLog:
2016-09-21  Martin Sebor  <msebor@redhat.com>

	PR middle-end/77683
	* gcc.dg/tree-ssa/builtin-sprintf-warn-1.c: Add test cases.

gcc/ChangeLog:
2016-09-21  Martin Sebor  <msebor@redhat.com>

	PR middle-end/77683
	* gimple-ssa-sprintf.c (format_integer): Fail gracefully when
	length modifier is not expected.
	(format_floating): Ignore l length modifier and fail gracefuly
	when it isn't one of the other expected ones.


diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index 2e4a89f..34595a5 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -867,7 +867,14 @@  format_integer (const conversion_spec &spec, tree arg)
       break;
 
     default:
-      gcc_unreachable ();
+      {
+	fmtresult res = fmtresult ();
+	res.range.min = HOST_WIDE_INT_MAX;
+	res.range.max = HOST_WIDE_INT_MAX;
+	res.bounded = false;
+	res.constant = false;
+	return res;
+      }
     }
 
   /* The type of the argument to the directive, either deduced from
@@ -1145,6 +1152,7 @@  format_floating (const conversion_spec &spec, int width, int prec)
 
   switch (spec.modifier)
     {
+    case FMT_LEN_l:
     case FMT_LEN_none:
       type = double_type_node;
       break;
@@ -1160,7 +1168,14 @@  format_floating (const conversion_spec &spec, int width, int prec)
       break;
 
     default:
-      gcc_unreachable ();
+      {
+	fmtresult res = fmtresult ();
+	res.range.min = HOST_WIDE_INT_MAX;
+	res.range.max = HOST_WIDE_INT_MAX;
+	res.bounded = false;
+	res.constant = false;
+	return res;
+      }
     }
 
   /* The minimum and maximum number of bytes produced by the directive.  */
@@ -1246,7 +1261,14 @@  format_floating (const conversion_spec &spec, int width, int prec)
       }
 
     default:
-      gcc_unreachable ();
+      {
+	fmtresult res = fmtresult ();
+	res.range.min = HOST_WIDE_INT_MAX;
+	res.range.max = HOST_WIDE_INT_MAX;
+	res.bounded = false;
+	res.constant = false;
+	return res;
+      }
     }
 
   if (0 < width)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
index 7261dbd..214dbdc 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
@@ -863,6 +863,8 @@  void test_sprintf_chk_z_const (void)
 void test_sprintf_chk_e_const (void)
 {
   T (-1, "%E",   0.0);
+  T (-1, "%lE",  0.0);
+
   T ( 0, "%E",   0.0);          /* { dg-warning "into a region" } */
   T ( 0, "%e",   0.0);          /* { dg-warning "into a region" } */
   T ( 1, "%E",   1.0);          /* { dg-warning "into a region" } */
@@ -1073,6 +1075,8 @@  void test_sprintf_chk_int_nonconst (int a)
 void test_sprintf_chk_e_nonconst (double d)
 {
   T (-1, "%E",          d);
+  T (-1, "%lE",         d);
+
   T ( 0, "%E",          d);           /* { dg-warning "writing between 12 and 14 bytes into a region of size 0" } */
   T ( 0, "%e",          d);           /* { dg-warning "into a region" } */
   T ( 1, "%E",          d);           /* { dg-warning "into a region" } */
@@ -1104,6 +1108,8 @@  void test_sprintf_chk_e_nonconst (double d)
 void test_sprintf_chk_f_nonconst (double d)
 {
   T (-1, "%F",          d);
+  T (-1, "%lF",         d);
+
   T ( 0, "%F",          d);           /* { dg-warning "into a region" } */
   T ( 0, "%f",          d);           /* { dg-warning "into a region" } */
   T ( 1, "%F",          d);           /* { dg-warning "into a region" } */