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