https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93246
Bug ID: 93246 Summary: Unexpected program behavior when -fsanitize=address and -O2/O3 used Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: sanitizer Assignee: unassigned at gcc dot gnu.org Reporter: mtekieli+gcc at gmail dot com CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org, jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at gcc dot gnu.org Target Milestone: --- #include <iostream> /* $ g++-9 -O2 -fsanitize=address main.cpp && ./a.out x=0, y=0, z=1 $ g++-8 -O2 -fsanitize=address main.cpp && ./a.out x=1, y=1, z=1 $ clang++-9 -O2 -fsanitize=address main.cpp && ./a.out x=1, y=1, z=1 */ template <typename = void> struct Optional { auto is_present() const { return inner.present; } auto set_present() { if (not is_present()) inner.present = true; } struct InnerType { bool present = false; char padding[1] = {0}; }; using inner_t = InnerType; // InnerType inner = {}; // this works as expected! inner_t inner = {}; // this doesn't! }; template <typename WrappedType> struct Wrapper { auto operator-> () { return value; } WrappedType *value; }; int main() { Optional<> buf{}; Wrapper<Optional<>> wo = {&buf}; wo->set_present(); auto x = wo->is_present(); auto y = wo->is_present(); std::cout << "x=" << x << ", y=" << y; auto z = wo->is_present(); std::cout << ", z=" << z << "\n"; } /* Above code produces expected results when: * -fsanitize=address is not used * -O1 instead of -O2/O3 is used * gcc8 is used * InnerType instead of inner_t alias is used */