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

Reply via email to