https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100038
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|WAITING |NEW See Also| |https://gcc.gnu.org/bugzill | |a/show_bug.cgi?id=98465 CC| |msebor at gcc dot gnu.org --- Comment #7 from Martin Sebor <msebor at gcc dot gnu.org> --- Confirmed with attachment 50560 and the output/IL below. The problem is caused by the test (presumably for self-insertion) in SmallVectorImpl<T>::insert(iterator, const T&): const T *EltPtr = &Elt; if (I <= EltPtr && EltPtr < this->end()) ++EltPtr; I don't see anything in the IL to avoid it without compromising it at the same time. We suppressed a similar false positive in std::string::insert() in pr98465. It was done by keeping the equivalent test from being inlined because the usual suppression mechanism, #pragma GCC diagnostic, doesn't work reliably with inlining (something that will hopefully be fixed in GCC 12). Another alternative to consider is inserting an optimization barrier after the block above: asm volatile("": : :"memory"); Another (future) alternative is to annotate the SmallVector::BeginX with some new attribute telling the optimizer it doesn't alias unrelated objects (like val). This doesn't exist but it would help not just avoid warnings but also emit more optimal code. (As an aside, the pointer test above is strictly unspecified because it compares the addresses of unrelated objects, It should convert the pointers to integers first but that wouldn't prevent the warning.) In file included from mwe_smallvector.cpp:2: SmallVector.h: In function ‘int main()’: SmallVector.h:537:7: warning: array subscript 1 is outside array bounds of ‘int [1]’ [-Warray-bounds] mwe_smallvector.cpp:12:11: note: while referencing ‘<anonymous>’ In file included from mwe_smallvector.cpp:2: SmallVector.h:566:7: warning: array subscript 1 is outside array bounds of ‘int [1]’ [-Warray-bounds] mwe_smallvector.cpp:13:6: note: while referencing ‘val’ ... int main () { ... int D.55243; ... <bb 3> _21 = VS.D.54770.BeginX; _1 = _21 + 4; ... <bb 10> [local count: 32183167]: _52 = MEM[(struct SmallVectorTemplateCommon *)&VS].D.54770.BeginX; I_54 = _52 + 4; <bb 11> [local count: 97524748]: # I_69 = PHI <_1(8), I_54(10)> ... <bb 13> [local count: 97524748]: _115 = (long unsigned int) _111; _116 = -_115; _117 = _66 + _116; _70 = MEM[(const struct SmallVectorBase *)&VS].Size; _71 = _70 + 1; MEM[(struct SmallVectorBase *)&VS].Size = _71; if (&D.55243 >= I_69) goto <bb 14>; [50.00%] else goto <bb 16>; [50.00%] <bb 14> [local count: 48762374]: _72 = MEM[(struct SmallVectorTemplateCommon *)&VS].D.54770.BeginX; _73 = (long unsigned int) _71; _74 = _73 * 4; _75 = _72 + _74; if (&D.55243 < _75) goto <bb 15>; [50.00%] else goto <bb 16>; [50.00%] <bb 15> [local count: 24381187]: _50 = MEM[(type &)&D.55243 + 4]; <<< -Warray-bounds