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
/*
$ 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 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 struct Wrapper {
auto operator-> () { return value; }
WrappedType *value;
};
int main() {
Optional<> buf{};
Wrapper> 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
*/