https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86274

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P2
   Target Milestone|---                         |7.4

--- Comment #12 from Richard Biener <rguenth at gcc dot gnu.org> ---
So after gimplification I see

      __s = __builtin_alloca (__n);
      __builtin_va_start (&__args, 0);
      __len = __convf (__s, __n, __fmt, &__args);
      __builtin_va_end (&__args);
      std::allocator<char>::allocator (&D.109301);
      try
        {
          try
            {
              _1 = (sizetype) __len;
              _2 = __s + _1;
              std::__cxx11::basic_string<char>::basic_string<char*> (<retval>,
__s, _2, &D.109301);
              return <retval>;
            }
          finally
            {
              std::allocator<char>::~allocator (&D.109301);
            }

which after SSA rewrite looks like

  std::__cxx11::basic_string<char>::basic_string<char*> (_16(D), __s_7, _2,
&D.109301);

So we're rewriting <retval> into SSA which is expected, <retval>
is DECL_BY_REFERENCE.  So that is a red herring.

I suppose the new printf code simply doesn't handle default-defs that
come in as DECL_BY_REFERENCE RESULT_DECL.

Note what the pass causes is simply treating

_3 = vsnprintf (__s_2, 328, "%f", &__args);

as not returning zero and thus eliding a == 0 check.  For some reason
it says _3 is [8, 322] though but obviously 'NaN' prints as 3 characters
only...

So, martin?  Reduced testcase:

volatile double x;
int main()
{
  char *s = __builtin_alloca (220);
  x = __builtin_nan("nan");
  if (__builtin_snprintf (s, 220, "%f", x) != 3)
    __builtin_abort ();
  return 0;
}

Reply via email to