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

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2017-12-14
                 CC|                            |msebor at gcc dot gnu.org
     Ever confirmed|0                           |1

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
That's right.  String lengths are computed by and available only within the
strlen pass, while sprintf/snprintf calls are processed by the sprintf pass. 
The two passes should probably be integrated somehow to benefit from each
other's analysis.  The example below shows where the integration would benefit
in the strlen pass.

$ cat d.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout d.c
void f (char *d)
{
  __builtin_sprintf (d, "%s", "123");

  if (__builtin_strlen (d) != 3)   // folded
    __builtin_abort ();            // eliminated
}

void g (char *d)
{
  int n = __builtin_sprintf (d, "%i", 123);

  if (n != 3)                      // folded
    __builtin_abort ();            // eliminated
}

void h (char *d)
{
  __builtin_sprintf (d, "%i", 123);

  if (__builtin_strlen (d) != 3)   // not folded
    __builtin_abort ();            // not eliminated
}


;; Function f (f, funcdef_no=0, decl_uid=1892, cgraph_uid=0, symbol_order=0)

f (char * d)
{
  <bb 2> [local count: 1073741825]:
  __builtin_memcpy (d_3(D), "123", 4); [tail call]
  return;

}



;; Function g (g, funcdef_no=1, decl_uid=1895, cgraph_uid=1, symbol_order=1)

g (char * d)
{
  <bb 2> [local count: 1073741825]:
  __builtin_sprintf (d_2(D), "%i", 123); [tail call]
  return;

}



;; Function h (h, funcdef_no=2, decl_uid=1899, cgraph_uid=2, symbol_order=2)

h (char * d)
{
  long unsigned int _1;

  <bb 2> [local count: 1073741825]:
  __builtin_sprintf (d_3(D), "%i", 123);
  _1 = __builtin_strlen (d_3(D));
  if (_1 != 3)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [99.96%]

  <bb 3> [count: 0]:
  __builtin_abort ();

  <bb 4> [local count: 1073312327]:
  return;

}

Reply via email to