https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105050
Bug ID: 105050 Summary: error: expression '<statement>' is not a constant expression Product: gcc Version: 12.0 Status: UNCONFIRMED Keywords: diagnostic Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- template<typename _Tp> struct expected { void _M_swap_val(expected&) { } void _M_swap_unex(expected&) { } void _M_swap_val_unex(expected&) { } bool _M_has_value = true; constexpr void swap(expected& __x) { if (this->has_value()) { if (__x.has_value()) this->_M_swap_val(__x); else this->_M_swap_val_unex(__x); } else { if (__x.has_value()) __x._M_swap_val_unex(*this); else this->_M_swap_unex(__x); } } constexpr bool has_value() const noexcept { return this->_M_has_value; } }; constexpr bool test_swap() { expected<int> e1, e2; e1.swap(e2); return true; } static_assert(test_swap()); This doesn't give a very helpful diagnostic: x.ii:43:24: error: non-constant condition for static assertion 43 | static_assert(test_swap()); | ~~~~~~~~~^~ x.ii:43:24: in 'constexpr' expansion of 'test_swap()' x.ii:38:10: error: 'constexpr void expected<_Tp>::swap(expected<_Tp>&) [with _Tp = int]' called in a constant expression 38 | e1.swap(e2); | ~~~~~~~^~~~ x.ii:13:5: note: 'constexpr void expected<_Tp>::swap(expected<_Tp>&) [with _Tp = int]' is not usable as a 'constexpr' function because: 13 | swap(expected& __x) | ^~~~ x.ii:15:7: error: expression '<statement>' is not a constant expression 15 | if (this->has_value()) | ^~ The problem is that the _M_swap_val, _M_swap_unex and _M_swap_val_unex functions are not constexpr, but the diagnostic doesn't make that obvious.