From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 583583857C71; Sun, 11 Apr 2021 17:47:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 583583857C71 From: "nicholas.stranchfield@you-spam.com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/100038] New: -Warray-bound triggers false positives Date: Sun, 11 Apr 2021 17:47:54 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: unknown X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: nicholas.stranchfield@you-spam.com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Apr 2021 17:47:54 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D100038 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.stranchfield@you-spam.com Target Milestone: --- When compiling LLVM, I noticed that GCC produces some -Warray-bounds warnin= gs, namely In file included from mwe.cpp:4: SparseBitVector.h: In function =E2=80=98int main()=E2=80=99: SparseBitVector.h:129:15: warning: array subscript 2 is above array bounds = of =E2=80=98const BitWord [2]=E2=80=99 {aka =E2=80=98const long unsigned int [= 2]=E2=80=99} [-Warray-bounds] 129 | if (Bits[i] !=3D 0) | ~~~~^ SparseBitVector.h:54:11: note: while referencing =E2=80=98llvm::SparseBitVectorElement<128>::Bits=E2=80=99 54 | BitWord Bits[BITWORDS_PER_ELEMENT]; | ^~~~ SparseBitVector.h:138:15: warning: array subscript 4294967295 is above array bounds of =E2=80=98const BitWord [2]=E2=80=99 {aka =E2=80=98const long unsi= gned int [2]=E2=80=99} [-Warray-bounds] 138 | if (Bits[Idx] !=3D 0) | ~~~~^ SparseBitVector.h:54:11: note: while referencing =E2=80=98llvm::SparseBitVectorElement<128>::Bits=E2=80=99 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 = =E2=80=98int [1]=E2=80=99 [-Warray-bounds] 537 | ++EltPtr; | ^~ mwe.cpp:21:29: note: while referencing =E2=80=98=E2=80=99 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 = =E2=80=98int [1]=E2=80=99 [-Warray-bounds] 566 | ++EltPtr; | ^~ mwe.cpp:22:6: note: while referencing =E2=80=98val=E2=80=99 22 | int val =3D 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 =3D 0; i < BITWORDS_PER_ELEMENT; ++i) if (Bits[i] !=3D 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/l= ogs/ppc64le/build.log [1] https://kojipkgs.fedoraproject.org/packages/llvm/11.0.0/0.2.rc3.fc34/data/l= ogs/s390x/build.log [2] https://buildd.debian.org/status/fetch.php?pkg=3Dllvm-toolchain-11&arch=3Da= md64&ver=3D1%3A11.0.1-2&stamp=3D1609987721&raw=3D0 The SmallVector related warning appeared first with GCC 9.x, while the SparseBitVector related warnings appeared with GCC 10 (tested GCC 10.2.0) a= nd are absent in GCC-9.3.0. The warnings trigger with -O2 but not with -O1 and -DNDEBUG is needed for t= he 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 =3D {1, 2, 3, 4}; VS.insert(VS.begin() + 1, 5); int val =3D 6; VS.insert(VS.begin() + 2, val); // force the vector for (int i : VS) { printf("%d\n", i); } }=