backport: re PR tree-optimization/83198 (ICE in format_floating, at gimple-ssa-sprintf.c:1900)

Backported from mainline
	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.

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

From-SVN: r255728
This commit is contained in:
Jakub Jelinek 2017-12-15 23:14:41 +01:00 committed by Jakub Jelinek
parent a31d2f7b36
commit ea5869d324
5 changed files with 57 additions and 5 deletions

View File

@ -1,6 +1,13 @@
2017-12-15 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
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-12 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/80631

View File

@ -1717,6 +1717,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. */
@ -1724,10 +1726,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;
@ -1778,7 +1776,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. */

View File

@ -6,6 +6,10 @@
Backported from mainline
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.
PR c++/79650
* g++.dg/template/pr79650.C: New test.

View File

@ -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;
}

View File

@ -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" } } */