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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic,
                   |                            |missed-optimization
            Summary|early string folding        |early string folding
                   |defeats strlen optimization |defeats strlen optimization
                   |                            |and -Warray-bounds

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
Here's another test showing the consequences of the early folding: In f()
below, the strlen() call isn't folded and so the -Warray-bounds warning has a
chance to detect the out-of-bounds index.  But because the strlen() call is not
folded, the program will behave unpredictably.  Folding the call to zero
instead after the warning has been issued would be safer and result in more
predictable results.  In g(), on the other hand, the early folding prevents the
warning and also leads to a result that's inconsistent with one that would be
obtained by a valid program (also unsafe and difficult to debug).

$ cat d.c && gcc -O2 -S -Wall -Wextra -fdump-tree-strlen=/dev/stdout d.c
const char a[] = "123";

void f (int i)
{
  if (i < 7)
    i = 7;

  const char *s = &a[i];  // -Warray-bounds

  if (__builtin_strlen (s) > 3)   // not folded (bad)
    __builtin_puts ("impossible!");
}

void g (int i)
{
  if (i < 7)
    i = 7;

  if (__builtin_strlen (&a[i]) > 3)   // no -Warray-bounds, folded to true
    __builtin_puts ("impossible!");
}

d.c: In function ‘f’:
d.c:8:19: warning: array subscript 7 is above array bounds of ‘const char[4]’
[-Warray-bounds]
   const char *s = &a[i];  // -Warray-bounds
                   ^~~~~
d.c:3:6: warning: offset ‘7’ outside bounds of constant string [-Warray-bounds]
 void f (int i)
      ^

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

f (int i)
{
  const char * s;
  long unsigned int _1;
  sizetype _2;

  <bb 2> [local count: 1073741825]:
  i_8 = MAX_EXPR <i_4(D), 7>;
  _2 = (sizetype) i_8;
  s_5 = &a + _2;
  _1 = __builtin_strlen (s_5);
  if (_1 > 3)
    goto <bb 3>; [33.00%]
  else
    goto <bb 4>; [67.00%]

  <bb 3> [local count: 354334802]:
  __builtin_puts ("impossible!");

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

}



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

g (int i)
{
  <bb 2> [local count: 1073741825]:
  __builtin_puts ("impossible!");
  return;

}

Reply via email to