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.