[Bug middle-end/103483] context-sensitive ranges change triggers stringop-overread

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Dec 2 22:14:28 GMT 2021


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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|missed-optimization         |

--- Comment #10 from Martin Sebor <msebor at gcc dot gnu.org> ---
Using -O2 doesn't avoid the warning in general.  The following C test case
reproduces an equivalent warning at all optimization levels (with GCC 11 it
triggers a -Warray-bounds only).  The warning works as designed.  If you don't
want these warnings to trigger on these cases we need change the design,
starting with outlining the conditions under which they should trigger.  As it
is, they all trigger for every invalid call in the IL, whether it's in the
source code of the original test case, or in the standard library headers (like
in the case of std::string) inlined into user code, or whether it's isolated by
the compiler.  Fiddling with optimization levels, disabling them for system
headers, or other heuristics won't prevent them under other conditions.

$ cat t.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout
-Wno-array-bounds t.c
static inline __attribute__ ((always_inline))
void f (char *d, const char *s, __SIZE_TYPE__ n)
{
  if (n == 1)
    *d = *s;
  else
    __builtin_memcpy (d, s, n);
}

static inline  __attribute__ ((always_inline))
void ff (char *d, const char *s0, const char *s1)
{
  f (d, s0, s1 - s0);
}

void g (void*);

void h (int n)
{
  char a[1] = "";
  char b[16];
  if (n)
    ff (b, a, a + n);
  g (b);
}

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

Removing basic block 7
void h (int n)
{
  char b[16];
  char a[1];
  sizetype _1;

  <bb 2> [local count: 1073741824]:
  a = "";
  if (n_5(D) != 0)
    goto <bb 3>; [50.00%]
  else
    goto <bb 6>; [50.00%]

  <bb 3> [local count: 536870913]:
  _1 = (sizetype) n_5(D);
  if (_1 == 1)
    goto <bb 4>; [51.12%]
  else
    goto <bb 5>; [48.88%]

  <bb 4> [local count: 274448412]:
  MEM[(char *)&b] = 0;
  goto <bb 6>; [100.00%]

  <bb 5> [local count: 262422500]:
  __builtin_memcpy (&b, &a, _1);

  <bb 6> [local count: 1073741824]:
  g (&b);
  a ={v} {CLOBBER};
  b ={v} {CLOBBER};
  return;

}


In function ‘f’,
    inlined from ‘ff’ at t.c:13:3,
    inlined from ‘h’ at t.c:23:5:
t.c:7:5: warning: ‘__builtin_memcpy’ reading 2 or more bytes from a region of
size 1 [-Wstringop-overread]
    7 |     __builtin_memcpy (d, s, n);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~
t.c: In function ‘h’:
t.c:20:8: note: source object ‘a’ of size 1
   20 |   char a[1] = "";
      |        ^


More information about the Gcc-bugs mailing list