https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92332
Bug ID: 92332 Summary: invalid optimization in certain situations involving placement new on i686 Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cbcode at gmail dot com Target Milestone: --- Created attachment 47157 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47157&action=edit minimal example showing problem See code below and attached (running ubuntu linux on intel). g++-9 -m64 compiles and runs fine, all optimization levels. g++-9 -m32 -O1 and below compile and run fine. g++-9 -m32 -O2 and above generate incorrect warning and incorrect code. g++-8 (8.3.0) behaves same as g++-9. #include <cstdint> #include <cstdio> #include <new> using std::size_t; using std::uint32_t; using std::uint64_t; template<typename T, size_t N> struct myarray { T data[N]; }; myarray<uint32_t, 2> mul(uint32_t a, uint32_t b) noexcept { alignas(uint64_t) myarray<uint32_t, 2> ab; #if 1 //no bug for #if 0 ::new(&ab) uint64_t(uint64_t(a) * b); #else uint64_t const c = uint64_t(a) * b; ab.data[0] = uint32_t(c); ab.data[1] = uint32_t(c >> 32); #endif return ab; } struct bar : myarray<uint32_t, 2> { bar& operator+=(uint32_t a) noexcept { this->data[0] += a; //no bug when commented out this->data[1] += a; //no bug when commented out return *this; } }; struct foo : myarray<uint32_t, 2> { foo() noexcept { static_cast<bar&>(*::new(this) myarray<uint32_t, 2>(mul(0xdeadbeef, 0xdeadbeef))) += 1; } }; int main() { foo f; std::printf("0x%x, 0x%x\n", f.data[0], f.data[1]); std::printf("0x%x, 0x%x\n", 0x216da322, 0xc1b1cd13); return 0; } /* $ g++-9 -m64 -Wall -O2 -o bug bug.cpp //OK $ g++-9 -m32 -Wall -O1 -o bug bug.cpp //Ok $ g++-9 -m32 -Wall -O2 -o bug bug.cpp bug.cpp: In function ‘int main()’: bug.cpp:24:23: warning: ‘f.bar::<anonymous>.myarray<unsigned int, 2>::data[0]’ is used uninitialized in this function [-Wuninitiali 24 | this->data[0] += a; //no bug when commented out | ~~~~~~~~~~~~~~^~~~ bug.cpp:35:9: note: ‘f.bar::<anonymous>.myarray<unsigned int, 2>::data[0]’ was declared here 35 | foo f; | ^ bug.cpp:25:23: warning: ‘f.bar::<anonymous>.myarray<unsigned int, 2>::data[1]’ is used uninitialized in this function [-Wuninitiali 25 | this->data[1] += a; //no bug when commented out | ~~~~~~~~~~~~~~^~~~ bug.cpp:35:9: note: ‘f.bar::<anonymous>.myarray<unsigned int, 2>::data[1]’ was declared here 35 | foo f; | ^ */