Your code is fine from what I can tell. Clang seems to struggle with the = default constructor rather than just defining a default constructor manually. It has the following spiel in its source code about it:
DR1351:
If the brace-or-equal-initializer of a non-static data member
invokes a defaulted default constructor of its class or of an
enclosing class in a potentially evaluated subexpression, the
program is ill-formed.This resolution is unworkable: the exception specification of the
default constructor can be needed in an unevaluated context, in
particular, in the operand of a noexcept-expression, and we can be
unable to compute an exception specification for an enclosed class.Any attempt to resolve the exception specification of a defaulted default
constructor before the initializer is lexically complete will ultimately
come here at which point we can diagnose it.
I think it may be incorrectly picking up the error, personally. But it specifially mentions “defaulted default constructor”.
The following seems to work:
#include <utility>
struct foo
{
int x{0};
foo() noexcept {} // = default;
void f() noexcept(noexcept(std::declval<foo&>())) {}
};
int main()
{
}