https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92956
--- Comment #13 from Martin Sebor <msebor at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #9) Thanks for the nice test case! The assumptions the warning makes aren't accidental: it tries to detect bugs that would otherwise go undetected, and it relies on the fact that the IL, although ambiguous (as in: matching both valid code injected by GCC itself, as well as accidental bugs introduced by careless programmers), corresponds to the source code more often than not. It's a trade-off between false negatives and false positives, with the balance shifting each time a new transformation is added that breaks the assumption. The only way to do better is to make the IL reflect the distinction between the two classes of uses). The GIMPLE in the test case in comment #10 that causes the warning is this: p_2(D)->l = l_3(D); vectp.5_21 = &p_2(D)->t.a; MEM <vector(8) char> [(char *)vectp.5_21] = { 2, 3, 4, 5, 6, 7, 8, 9 }; and the warning sees that vectp.5_21 is just a pointer to p->t.a. If, for example, the IL instead looked like this: p_2(D)->l = l_3(D); MEM[(Vec8 *)p_2(D) + 8B] = { 2, 3, 4, 5, 6, 7, 8, 9 }; vectp.10_14 = &p_2(D)->t.i; the warning (as it is today) wouldn't trigger (Vec8 is a typedef for __attribute__ ((vector_size (8))) char) because it doesn't know how to convert offsets into structs into members (but that's just a limitation that I hope to remove). But even this IL is still ambiguous because it corresponds to this assignment: *((Vec8*)&p->t.a) = (Vec8){ 2, 3, 4, 5, 6, 7, 8, 9 }; Here the overflow is intended to be detected but won't be. Worse, a trivial change to the code like so results in the former IL, bringing the warning back: *((__attribute__ ((vector_size (8))) char*)&p->t.a) = (__attribute__ ((vector_size (8))) char){ 2, 3, 4, 5, 6, 7, 8, 9 }; To avoid this problem we just need to "encode" the cast in the MEM_REF destination argument (or maybe the type of the offset) used by optimizers in a way that doesn't correspond to a valid source code construct. Or, more generally, just use some unused bit in the MEM_REF representation to distinguish the two cases. I'm not an expert on GIMPLE so I don't have a good sense of what would work or work best, but if the idea is sound I'll try to look into it for GCC 11.