This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] fix ICE on %lf directive in format_floating in gimple-ssa-sprintf.c (middle-end/77683)
- From: Martin Sebor <msebor at gmail dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 21 Sep 2016 14:47:51 -0600
- Subject: [PATCH] fix ICE on %lf directive in format_floating in gimple-ssa-sprintf.c (middle-end/77683)
- Authentication-results: sourceware.org; auth=none
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
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" } */