On Wed, 13 Dec 2017, Jakub Jelinek wrote: > Hi! > > This patch fixes 2 issues in format_floating. One is that when determining > precision, we should consider solely the type *printf* will read the > argument as (i.e. double unless L or ll modifier is used, in which case > long double), not the type of the argument, because the corresponding > argument could have any type, even not floating, or say __float128 etc. > > This is fixed in the first 2 hunks. > > The last hunk is to treat REAL_CSTs arguments of incompatible types > as unknown argument, we really don't know what say __float128 passed to > %f or double passed to %La will do; that is something diagnosed by -Wformat, > so the patch just treats it as arbitrary value of the type. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Ok. Richard. > 2017-12-13 Jakub Jelinek <ja...@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/gimple-ssa-sprintf.c.jj 2017-11-03 15:37:04.000000000 +0100 > +++ gcc/gimple-ssa-sprintf.c 2017-12-13 13:37:59.289435623 +0100 > @@ -1885,6 +1885,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. */ > @@ -1892,10 +1894,6 @@ format_floating (const directive &dir, t > { > /* 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; > > @@ -1946,7 +1944,9 @@ format_floating (const directive &dir, t > } > } > > - 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. */ > --- gcc/testsuite/gcc.dg/pr83198.c.jj 2017-12-13 13:43:36.056192309 +0100 > +++ gcc/testsuite/gcc.dg/pr83198.c 2017-12-13 13:47:11.716474956 +0100 > @@ -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; > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)