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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Blocks|                            |88443
         Resolution|---                         |DUPLICATE
             Status|NEW                         |RESOLVED

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
The warning is issued based on the last MEM_REF in the IL below which stores 16
bytes to the address _1.  The address is computed by adding (h + 2) to _12, the
address of the action member on type int.  The middle-end treats the address of
a member plus its size as interchangeable for the address of the next member,
while the warning relies on the two being distinct (it's invalid to access a
member using a pointer to another).  If, instead of using &MEM[(struct c
*)f_2(D) + 2B].action, it used the equivalent but strictly (according to C/C++
rules) valid &MEM[(short *)f_2(D) + 2B], i.e., the address of the enclosing
struct, this wouldn't be a problem because all stores at that address are valid
up to the size of the struct and the warning interprets that as the store to
the member that begins at that offset.  Of course, referencing the member to
which the store applies would be ideal.

A similar false positive with the same root cause was reported in pr94655 so
resolving as a dupe.

  <bb 2> [local count: 1073741824]:
  _12 = &MEM[(struct c *)f_2(D) + 2B].action;   <<< address of f->c.e.action
  .ASAN_CHECK (7, _12, 2, 2);
  MEM[(struct c *)f_2(D) + 2B].action = 0;
  _9 = (sizetype) h_5(D);
  _10 = _9 + 2;
  _1 = _12 + _10;
  .ASAN_CHECK (4, g_6(D), 16, 1);
  _7 = MEM <__int128 unsigned> [(char * {ref-all})g_6(D)];
  .ASAN_CHECK (5, _1, 16, 1);
  MEM <__int128 unsigned> [(char * {ref-all})_1] = _7;   <<< store at
f->c.e.action + h that's bigger than size of action

Incidentally, replacing the '__builtin_memcpy(&j->d.b[h], g, 16)' call with the
equivalent '__builtin_memcpy(j->d.b + h, g, 16)' avoids the waning because the
IL emitted in that case corresponds to valid code (as far as the warning is
concerned); see below.  It also implies that these differences in the IL are
incidental rather than a deliberate feature and could with some effort be
avoided.

  <bb 2> [local count: 1073741824]:
  _11 = &MEM[(struct c *)f_4(D) + 2B].action;
  .ASAN_CHECK (7, _11, 2, 2);
  MEM[(struct c *)f_4(D) + 2B].action = 0;
  _1 = &MEM[(struct c *)f_4(D) + 2B].d.b;   <<< address of f->c.d.b
  _2 = (sizetype) h_7(D);
  _3 = _1 + _2;
  .ASAN_CHECK (4, g_8(D), 16, 1);
  _9 = MEM <__int128 unsigned> [(char * {ref-all})g_8(D)];
  .ASAN_CHECK (5, _3, 16, 1);
  MEM <__int128 unsigned> [(char * {ref-all})_3] = _9;   <<< in-bounds store at
f->c.d.b + h

*** This bug has been marked as a duplicate of bug 94655 ***


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88443
[Bug 88443] [meta-bug] bogus/missing -Wstringop-overflow warnings

Reply via email to