From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id D456D384A87E; Tue, 19 May 2020 11:39:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D456D384A87E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1589888359; bh=YTy6qGRAJWH1wUPX8pEA3cDEp590cSmyKY1sMK3QNbA=; h=From:To:Subject:Date:From; b=K9zD88D+4pLgSjpPlpvhagjlH5aL7rzThcVSXyt4cdDX69YJslR/lawWN6ZbWOvqQ pdjjlLD7hDq/YM/2YmlB/mtZQHqsvUbunWw05fMRQNHC5lHqYdIqbw5n/1fe2GrpZF dXpSwdsp6c2HlJSnL3cVOpAUQ6NBhASztHNujkUI= From: "syomalina at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/95202] New: Assignment to a member is wrongly optimized away by g++ with -fstrict-aliasing Date: Tue, 19 May 2020 11:39:19 +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: 9.2.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: syomalina at gmail dot 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 attachments.created 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: Tue, 19 May 2020 11:39:19 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D95202 Bug ID: 95202 Summary: Assignment to a member is wrongly optimized away by g++ with -fstrict-aliasing Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: syomalina at gmail dot com Target Milestone: --- Created attachment 48559 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=3D48559&action=3Dedit the preprocessed file (*.i*) that triggers the bug The following code produces a wrong ERROR print with -fstrict-aliasing enab= led. It sounds like a commonly reported false-positive bug with aliasing rules violation from the FAQ, but it's not (imho :-)), as no type-casting and mem= ory manipulations are involved.=20 The problem could be related to the following bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D93246, as "the symptoms" are= quite similar and type aliases are involved also here. But for the code below -fno-ipa-sra doesn't help, only -fno-strict-aliasing does.=20 The problem appears with GCC 9.2.0, 9.1.0. It doesn't appear with GCC 9.3 a= nd 10.1. The reason I've thought it would be still useful to report the bug is= : a very fragile code constellation which allows to reproduce the problem. I've marked in comments below what could be done to prevent the problem from appearing. It looks like that even a slight change in the optimizer could "hide" the problem back, what could have happened in the later versions of = GCC. So, it would be great to check what is the root cause of the problem, and i= f it was actually fixed in later GCC versions.=20 The code below models variable sized array allocated on stack. Then 2x dimension array is created with sizes 32 and 4 respectively. The bug happe= ns in this line: outerArrItem.innerArray.setSize(innerArraySize); body.numElements is not updated with the new size (4) for the inner array, = and following access to an element [0] of the inner array raises the error.=20 // -------------------------------- #include template class VariableSizedArray { public: void setSize(uint32_t num) { body.numElements =3D num; } T& operator[](uint32_t idx) { if (idx >=3D CAPACITY or idx >=3D body.numElements) { raiseIndexErr("", 42, "ERROR: Invalid idx: ", idx, 42, body.numElements); } return body.elems[idx]; } // Changes in parameters make the problem to disappear static void raiseIndexErr(const char*, uint32_t, const char* error, uint32_t idx, uint32_t, uint32_t num) { // If printf is used, problem disappears std::cerr << error << idx << "! Capacity: " << CAPACITY << ", number elements: " << num << ::std::endl; } // private: // If private -- problem disappears struct Data { uint32_t numElements; T elems[CAPACITY]; }; using Body =3D Data;=20 Body body; // If Data is used directly here w/o "using", problem disapp= ears }; static constexpr int outerArraySize =3D 32; static constexpr int innerArraySize =3D 4; class InnerArrayItem { public: void use(){}; uint8_t dummy[1]{}; // when removed or not an array, problem disappears }; class OuterArrayItem { public: uint8_t dummy{0}; // When removed, problem disappears VariableSizedArray innerArray{}; }; struct TestProblem { // When parameter removed (its always 0) -- problem disappears static void run(const uint8_t index0) { VariableSizedArray outerArray{}; outerArray.setSize(outerArraySize); auto& outerArrItem =3D outerArray[index0]; outerArrItem.innerArray.setSize(innerArraySize); // ERROR: invalid idx is reported for outerArray[0].innerArray[0] access! outerArrItem.innerArray[index0].use(); } }; int main() { TestProblem::run(0); std::cout << "Test finished." << std::endl; return 0; } /* Execution results: $ g++ --version # same happens for 9.1.0 as well g++ (GCC) 9.2.0 Copyright (C) 2019 Free Software Foundation, Inc. # Just -O1 $ rm gccBug; g++ -o gccBug -Wall -Werror -O1 TestGccBug.cpp && ./gccBug Test finished. # -O1 with -fstrict-aliasing $ rm gccBug; g++ -o gccBug -Wall -Werror -O1 -fstrict-aliasing TestGccBug.c= pp && ./gccBug=20 ERROR: Invalid idx: 0! Capacity: 4, number elements: 0 Test finished. # Just -O2 $ rm gccBug; g++ -o gccBug -Wall -Werror -O2 TestGccBug.cpp && ./gccBug ERROR: Invalid idx: 0! Capacity: 4, number elements: 0 Test finished. # Just -O3 $ rm gccBug; g++ -o gccBug -Wall -Werror -O3 TestGccBug.cpp && ./gccBug ERROR: Invalid idx: 0! Capacity: 4, number elements: 0 Test finished. # -O3 with -fno-ipa-sra as recommended in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D93246 $ rm gccBug; g++ -o gccBug -Wall -Werror -O3 -fno-ipa-sra TestGccBug.cpp && ./gccBug ERROR: Invalid idx: 0! Capacity: 4, number elements: 0 Test finished. # -O3 with -fno-ipa-sra and -fno-strict-aliasing $ rm gccBug; g++ -o gccBug -Wall -Werror -O3 -fno-ipa-sra -fno-strict-alias= ing TestGccBug.cpp && ./gccBug Test finished. # -O3 with -fno-strict-aliasing $ rm gccBug; g++ -o gccBug -Wall -Werror -O3 -fno-strict-aliasing TestGccBug.cpp && ./gccBug Test finished. */ Verbose output of GCC compilation: $ g++ -v -save-temps -o gccBug -Wall -Werror -Wextra -O3 TestGccBug.cpp Using built-in specs. COLLECT_GCC=3Dg++ COLLECT_LTO_WRAPPER=3D/opt/gcc/x86_64/9.2.0a-1/libexec/gcc/x86_64-redhat-li= nux/9.2.0/lto-wrapper Target: x86_64-redhat-linux Configured with: ../configure --prefix=3D/opt/gcc/x86_64/9.2.0a-1 --exec-prefix=3D/opt/gcc/x86_64/9.2.0a-1 --bindir=3D/opt/gcc/x86_64/9.2.0a-= 1/bin --sbindir=3D/opt/gcc/x86_64/9.2.0a-1/sbin --sysconfdir=3D/opt/gcc/x86_64/9.2.0a-1/etc --datadir=3D/opt/gcc/x86_64/9.2.0a-1/share --includedir=3D/opt/gcc/x86_64/9.2.0a-1/include --libdir=3D/opt/gcc/x86_64/9.2.0a-1/lib --libexecdir=3D/opt/gcc/x86_64/9.2.0a-1/libexec --localstatedir=3D/var --sharedstatedir=3D/var/lib --mandir=3D/opt/gcc/x86_64/9.2.0a-1/man --infodir=3D/opt/gcc/x86_64/9.2.0a-1/info --with-docdir=3D/opt/gcc/x86_64/9.2.0a-1/doc --enable-shared --enable-languages=3Dc,c++ --enable-threads=3Dposix --enable-checking=3Drel= ease --with-system-zlib --disable-libunwind-exceptions --enable-libssp --enable-= lto --with-gnu-ld --verbose --disable-gtktest --target=3Dx86_64-redhat-linux --build=3Dx86_64-redhat-linux --host=3Dx86_64-redhat-linux --enable-__cxa_a= texit --enable-pic Thread model: posix gcc version 9.2.0 (GCC)=20 COLLECT_GCC_OPTIONS=3D'-v' '-save-temps' '-o' 'gccBug' '-Wall' '-Werror' '-Wextra' '-O3' '-shared-libgcc' '-mtune=3Dgeneric' '-march=3Dx86-64' /opt/gcc/x86_64/9.2.0a-1/libexec/gcc/x86_64-redhat-linux/9.2.0/cc1plus -E -quiet -v -D_GNU_SOURCE TestGccBug.cpp -mtune=3Dgeneric -march=3Dx86-64 -Wa= ll -Werror -Wextra -O3 -fpch-preprocess -o TestGccBug.ii ignoring nonexistent directory "/opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_64-redhat-linux/9.2.0/../../../../x86= _64-redhat-linux/include" #include "..." search starts here: #include <...> search starts here: /opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_64-redhat-linux/9.2.0/../../../../incl= ude/c++/9.2.0 /opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_64-redhat-linux/9.2.0/../../../../incl= ude/c++/9.2.0/x86_64-redhat-linux /opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_64-redhat-linux/9.2.0/../../../../incl= ude/c++/9.2.0/backward /opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_64-redhat-linux/9.2.0/include /usr/local/include /opt/gcc/x86_64/9.2.0a-1/include /opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_64-redhat-linux/9.2.0/include-fixed /usr/include End of search list. COLLECT_GCC_OPTIONS=3D'-v' '-save-temps' '-o' 'gccBug' '-Wall' '-Werror' '-Wextra' '-O3' '-shared-libgcc' '-mtune=3Dgeneric' '-march=3Dx86-64' /opt/gcc/x86_64/9.2.0a-1/libexec/gcc/x86_64-redhat-linux/9.2.0/cc1plus -fpreprocessed TestGccBug.ii -quiet -dumpbase TestGccBug.cpp -mtune=3Dgener= ic -march=3Dx86-64 -auxbase TestGccBug -O3 -Wall -Werror -Wextra -version -o TestGccBug.s GNU C++14 (GCC) version 9.2.0 (x86_64-redhat-linux) compiled by GNU C version 9.2.0, GMP version 5.0.0, MPFR version 3.= 1.0, MPC version 1.1.0, isl version none GGC heuristics: --param ggc-min-expand=3D100 --param ggc-min-heapsize=3D131= 072 GNU C++14 (GCC) version 9.2.0 (x86_64-redhat-linux) compiled by GNU C version 9.2.0, GMP version 5.0.0, MPFR version 3.= 1.0, MPC version 1.1.0, isl version none GGC heuristics: --param ggc-min-expand=3D100 --param ggc-min-heapsize=3D131= 072 Compiler executable checksum: 4b6a28fa973d06df756608f08fdba542 COLLECT_GCC_OPTIONS=3D'-v' '-save-temps' '-o' 'gccBug' '-Wall' '-Werror' '-Wextra' '-O3' '-shared-libgcc' '-mtune=3Dgeneric' '-march=3Dx86-64' as -v --64 -o TestGccBug.o TestGccBug.s GNU assembler version 2.32 (x86_64-redhat-linux) using BFD version (GNU Binutils) 2.32 COMPILER_PATH=3D/opt/gcc/x86_64/9.2.0a-1/libexec/gcc/x86_64-redhat-linux/9.= 2.0/:/opt/gcc/x86_64/9.2.0a-1/libexec/gcc/x86_64-redhat-linux/9.2.0/:/opt/g= cc/x86_64/9.2.0a-1/libexec/gcc/x86_64-redhat-linux/:/opt/gcc/x86_64/9.2.0a-= 1/lib/gcc/x86_64-redhat-linux/9.2.0/:/opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_6= 4-redhat-linux/ LIBRARY_PATH=3D/opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_64-redhat-linux/9.2.0/:= /opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_64-redhat-linux/9.2.0/../../../../lib6= 4/:/lib/../lib64/:/usr/lib/../lib64/:/opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_6= 4-redhat-linux/9.2.0/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS=3D'-v' '-save-temps' '-o' 'gccBug' '-Wall' '-Werror' '-Wextra' '-O3' '-shared-libgcc' '-mtune=3Dgeneric' '-march=3Dx86-64' /opt/gcc/x86_64/9.2.0a-1/libexec/gcc/x86_64-redhat-linux/9.2.0/collect2 -plugin /opt/gcc/x86_64/9.2.0a-1/libexec/gcc/x86_64-redhat-linux/9.2.0/liblto_plugi= n.so -plugin-opt=3D/opt/gcc/x86_64/9.2.0a-1/libexec/gcc/x86_64-redhat-linux/9.2.= 0/lto-wrapper -plugin-opt=3D-fresolution=3DTestGccBug.res -plugin-opt=3D-pass-through=3D-= lgcc_s -plugin-opt=3D-pass-through=3D-lgcc -plugin-opt=3D-pass-through=3D-lc -plugin-opt=3D-pass-through=3D-lgcc_s -plugin-opt=3D-pass-through=3D-lgcc --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o gccBug /lib/../lib64/crt1.o /lib/../lib64/crti.o /opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_64-redhat-linux/9.2.0/crtbegin.o -L/opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_64-redhat-linux/9.2.0 -L/opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_64-redhat-linux/9.2.0/../../../../li= b64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_64-redhat-linux/9.2.0/../../.. TestGccBug.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /opt/gcc/x86_64/9.2.0a-1/lib/gcc/x86_64-redhat-linux/9.2.0/crtend.o /lib/../lib64/crtn.o COLLECT_GCC_OPTIONS=3D'-v' '-save-temps' '-o' 'gccBug' '-Wall' '-Werror' '-Wextra' '-O3' '-shared-libgcc' '-mtune=3Dgeneric' '-march=3Dx86-64'=