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;
      |         ^
*/

Reply via email to