[Bug c++/100038] New: -Warray-bound triggers false positives

2021-04-11 Thread nicholas.stranchfield--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100038

Bug ID: 100038
   Summary: -Warray-bound triggers false positives
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: nicholas.stranchfi...@you-spam.com
  Target Milestone: ---

When compiling LLVM, I noticed that GCC produces some -Warray-bounds warnings,
namely

In file included from mwe.cpp:4:
SparseBitVector.h: In function ‘int main()’:
SparseBitVector.h:129:15: warning: array subscript 2 is above array bounds of
‘const BitWord [2]’ {aka ‘const long unsigned int [2]’} [-Warray-bounds]
  129 |   if (Bits[i] != 0)
  |   ^
SparseBitVector.h:54:11: note: while referencing
‘llvm::SparseBitVectorElement<128>::Bits’
   54 |   BitWord Bits[BITWORDS_PER_ELEMENT];
  |   ^~~~
SparseBitVector.h:138:15: warning: array subscript 4294967295 is above array
bounds of ‘const BitWord [2]’ {aka ‘const long unsigned int [2]’}
[-Warray-bounds]
  138 |   if (Bits[Idx] != 0)
  |   ^
SparseBitVector.h:54:11: note: while referencing
‘llvm::SparseBitVectorElement<128>::Bits’
   54 |   BitWord Bits[BITWORDS_PER_ELEMENT];
  |   ^~~~
In file included from mwe.cpp:3:
SmallVector.h:537:7: warning: array subscript 1 is outside array bounds of ‘int
[1]’ [-Warray-bounds]
  537 |   ++EltPtr;
  |   ^~
mwe.cpp:21:29: note: while referencing ‘’
   21 |  VS.insert(VS.begin() + 1, 5);
  | ^
In file included from mwe.cpp:3:
SmallVector.h:566:7: warning: array subscript 1 is outside array bounds of ‘int
[1]’ [-Warray-bounds]
  566 |   ++EltPtr;
  |   ^~
mwe.cpp:22:6: note: while referencing ‘val’
   22 |  int val = 6;
  |  ^~~

On inspection of the source, it seems these are false positives OR some
optimization went havoc (hopefully it did not), e.g. for SparseBitVector.h we
have

struct SparseBitVectorElement {
  // ...
  BitWord Bits[BITWORDS_PER_ELEMENT]; // line 54
  // ...
  int find_first() const {
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
  if (Bits[i] != 0) // line 129
// ...
  }
}

which looks pretty sound to me.  Searching around the internet, I'm not the
only one with these warnings, e.g. they show up in Fedora's LLVM build [0,1]
and Debian's [2].
In particular, this case looks very simple and a common theme which should not
trigger such warning.

[0]
https://kojipkgs.fedoraproject.org/packages/llvm/10.0.0/0.6.rc6.fc33/data/logs/ppc64le/build.log
[1]
https://kojipkgs.fedoraproject.org/packages/llvm/11.0.0/0.2.rc3.fc34/data/logs/s390x/build.log
[2]
https://buildd.debian.org/status/fetch.php?pkg=llvm-toolchain-11&arch=amd64&ver=1%3A11.0.1-2&stamp=1609987721&raw=0

The SmallVector related warning appeared first with GCC 9.x, while the
SparseBitVector related warnings appeared with GCC 10 (tested GCC 10.2.0) and
are absent in GCC-9.3.0.
The warnings trigger with -O2 but not with -O1 and -DNDEBUG is needed for the
SparseBitVector one.

If LLVM headers (version 10 or 11) are installed, then the following minimal
working example triggers the warnings:

g++ -I/usr/lib/llvm/11/include -DNDEBUG -O2 -Warray-bounds -o mwe.cpp.o -c
mwe.cpp
cat mwe.cpp

#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SparseBitVector.h"

#include 

using namespace llvm;

int main()
{
// Trigger: SparseBitVector (lines 138, 129)
SparseBitVector<> Vec;
Vec.set(5);
// force the vector
printf("%d\n", Vec.find_first());
printf("%d\n", Vec.find_last());

// Trigger: SmallVector (lines 537, 566)
SmallVector VS = {1, 2, 3, 4};
VS.insert(VS.begin() + 1, 5);
int val = 6;
VS.insert(VS.begin() + 2, val);
// force the vector
for (int i : VS) {
printf("%d\n", i);
}
}

[Bug middle-end/100038] -Warray-bound triggers false positives

2021-04-11 Thread nicholas.stranchfield--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100038

--- Comment #2 from Nicholas Stranchfield  
---
Created attachment 50557
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50557&action=edit
gzipped output of g++-10.2.0

Sure, here you go.

[Bug middle-end/100038] -Warray-bound triggers false positives

2021-04-11 Thread nicholas.stranchfield--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100038

--- Comment #3 from Nicholas Stranchfield  
---
Created attachment 50558
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50558&action=edit
gzipped output for SparseBitVector example

[Bug middle-end/100038] -Warray-bound triggers false positives

2021-04-11 Thread nicholas.stranchfield--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100038

--- Comment #4 from Nicholas Stranchfield  
---
Created attachment 50559
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50559&action=edit
gzipped output for SmallVector example

[Bug middle-end/100038] -Warray-bound triggers false positives

2021-04-11 Thread nicholas.stranchfield--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100038

--- Comment #5 from Nicholas Stranchfield  
---
Created attachment 50560
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50560&action=edit
Output for only the SmallVector example

Here the output for only the SmallVector.h test case.

P.S.: Sorry for the nose, mistook the attachment text area for the comment
field...

[Bug middle-end/100038] -Warray-bound triggers false positives

2021-04-11 Thread nicholas.stranchfield--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100038

--- Comment #6 from Nicholas Stranchfield  
---
Created attachment 50561
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50561&action=edit
Output for only the SparseBitVector example

Here the output for only the SparseBitVector.h test case.