https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89785
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #4)
> Also consider the equivalent(?)
>
> constexpr foo() { throw 42; } // with or without constexpr
>
> constexpr int Addrlen(int domain) {
> switch (domain) {
> case 0:
> return 0;
> case 2:
> return 42;
> }
> foo();
> }
>
> if Addrlen is allowed to be constexpr when foo() is not called
> [and is not declared constexpr]. And whether foo may be declared
> constexpr or not.
foo cannot be constexpr, but no diagnostic is required:
> For a constexpr function or constexpr constructor that is neither defaulted
> nor a template, if no argument values exist such that an invocation of the
> function or constructor could be an evaluated subexpression of a core
> constant expression (7.7), or, for a constructor, a constant initializer for
> some object (6.8.3.2), the program is ill-formed, no diagnostic required.
Addrlen *can* be constexpr, because there are argument values that allow it to
be evaluated at compile time, without ever reaching the throw (or reaching the
call to the non-constexpr foo).