https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104803
Bug ID: 104803 Summary: if consteval error from branch that isn't evaluated anyway Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: barry.revzin at gmail dot com Target Milestone: --- Consider this example. Yes, the body of none_of here looks... extremely bizarre. Just bear with me. template <typename R, typename P> constexpr auto none_of(R&& r, P p) -> bool { for (int i : r) { if consteval { if (p(i)) { // <== line 5 return false; } } else { if (p(i)) { // <== line 9 return false; } } } return true; } constexpr int vals[] = {1, 0, -1}; static_assert(none_of(vals, [](int i) consteval { return i > 2; })); This does not compile, with the error (https://godbolt.org/z/dEq3381ac): <source>: In instantiation of 'constexpr bool none_of(R&&, P) [with R = const int (&)[3]; P = <lambda(int)>]': <source>:18:22: required from here <source>:9:19: error: the value of 'i' is not usable in a constant expression 9 | if (p(i)) { | ^ <source>:3:14: note: 'int i' is not const 3 | for (int i : r) { | ^ Compiler returned: 1 The error is on line 9. That's the second part of the if consteval, the "else" part. That's not even supposed to be evaluated here, since we're in a static_assert. If I replace it with 'return false': template <typename R, typename P> constexpr auto none_of(R&& r, P p) -> bool { for (int i : r) { if consteval { if (p(i)) { return false; } } else { return false; } } return true; } constexpr int vals[] = {1, 0, -1}; static_assert(none_of(vals, [](int i) consteval { return i > 2; })); This compiles (https://godbolt.org/z/od93dEMf8). If 'return false;' in the else branch were executed, this would've failed. But it's (correctly) not. Something about the if consteval machinery is incorrectly evaluating the wrong branch and failing as a result.