https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97388
Bug ID: 97388 Summary: constexpr evaluator incorrectly claims double delete with function parameter Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: david at doublewise dot net Target Milestone: --- The following translation unit ``` struct S { int * m_ptr; constexpr S(): m_ptr(new int()) { } constexpr S(S && other) noexcept: m_ptr(other.m_ptr) { other.m_ptr = nullptr; } constexpr ~S() noexcept { delete m_ptr; } }; constexpr bool test(S v) { auto x = static_cast<S &&>(v); return true; } static_assert(test(S())); ``` is rejected with ``` <source>:23:19: error: non-constant condition for static assertion 23 | static_assert(test(S())); | ~~~~^~~~~ Compiler returned: 1 ``` This problem does not occur if `v` is turned into a local variable instead of a function parameter. The error message is also not helpful in this case. It gives a much more helpful (but still erroneous) error message if `std::allocator` is used instead of `new` and `delete`: ``` <source>:28:19: error: non-constant condition for static assertion 28 | static_assert(test(S())); | ~~~~^~~~~ In file included from /opt/compiler-explorer/gcc-trunk-20201012/include/c++/11.0.0/memory:64, from <source>:1: <source>:28:25: in 'constexpr' expansion of '(&<anonymous>)->S::~S()' <source>:17:36: in 'constexpr' expansion of 'std::allocator<int>().std::allocator<int>::deallocate(((S*)this)->S::m_ptr, 1)' /opt/compiler-explorer/gcc-trunk-20201012/include/c++/11.0.0/bits/allocator.h:183:30: error: deallocation of already deallocated storage 183 | ::operator delete(__p); | ~~~~~~~~~~~~~~~~~^~~~~ Compiler returned: 1 ``` See it live: https://godbolt.org/z/hcv88h