From ea5869d3243849afbdcd550ae8da1be9b7f9d289 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 15 Dec 2017 23:14:41 +0100 Subject: [PATCH] backport: re PR tree-optimization/83198 (ICE in format_floating, at gimple-ssa-sprintf.c:1900) Backported from mainline 2017-12-14 Jakub Jelinek 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 --- gcc/ChangeLog | 7 +++++++ gcc/gimple-ssa-sprintf.c | 10 +++++----- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.dg/pr83198.c | 18 ++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr83198.c | 23 +++++++++++++++++++++++ 5 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr83198.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr83198.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ea21c4c4803..e446c98d605 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,13 @@ 2017-12-15 Jakub Jelinek Backported from mainline + 2017-12-14 Jakub Jelinek + + 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 PR tree-optimization/80631 diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index d3771ddcc67..a4dc035d6e9 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 61ba4beb780..db89eafd532 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -6,6 +6,10 @@ Backported from mainline 2017-12-14 Jakub Jelinek + 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. diff --git a/gcc/testsuite/gcc.dg/pr83198.c b/gcc/testsuite/gcc.dg/pr83198.c new file mode 100644 index 00000000000..856f2be07d5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr83198.c @@ -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 index 00000000000..f9dba2acc68 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83198.c @@ -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" } } */