https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109745
Bug ID: 109745
Summary: Incorrect code generated with -O1 when having a
constexpr object modifying a mutable member
Product: gcc
Version: 13.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: carlosgalvezp at gmail dot com
Target Milestone: ---
Hi!
We are bumping our GCC installation from
6910cad55ffc330dc9767d2c8e0b66ccfa4134af to
07c52d1eec9671af92b7ce977b469f13a87887ad and one of our unit tests fails. I
have managed to reduce the code to the following minimal example, compiled with
-std=c++14 -O1:
#include <cassert>
#include <new>
template <class T>
class Foo {
public:
constexpr Foo() : has_value_{true} {}
Foo(Foo const& other) {
if (other.hasValue()) {
static_cast<void>(new (&value_) T(other.value()));
has_value_ = true;
}
}
constexpr bool hasValue() const { return has_value_; }
constexpr T const& value() const { return value_; }
private:
T value_{};
bool has_value_{false};
};
enum class State {
initialized,
copy_constructed,
copied_from,
};
class Stateful {
public:
constexpr Stateful() = default;
constexpr Stateful(Stateful const& other)
: state_{State::copy_constructed} {
other.state_ = State::copied_from;
}
constexpr State state() const { return state_; }
private:
mutable State state_{State::initialized};
};
int main() {
constexpr Foo<Stateful> x{};
const Foo<Stateful> y{x};
assert(State::copied_from == x.value().state());
}
Godbolt: https://godbolt.org/z/oTd8M9P91
The problem seems to also appear between GCC 12.2 and 13.1.
The test runs fine on Clang trunk.
One observation is that if I make "x" 'const' instead of 'constexpr', the test
passes.
Do we have UB in our code, or is this an actual regression in GCC?
Thanks!