The following program calling a consteval function causes code to be emitted to compute the result of maxFoo() at runtime, when one would expect it to be computed at compile-time: $ cat <<EOF | clang++ -xc++ - -std=c++2a -Os -S -o a.s && cat a.s #include <array> #include <algorithm> struct Foo { int i; }; static constexpr std::array<Foo, 3> foos = {{{1}, {2}, {3}}}; static int consteval maxFoo() { auto it = std::max_element(foos.begin(), foos.end(), [](auto lhs, auto rhs) { return lhs.i < rhs.i; }); return it->i; } int main() { return maxFoo(); } EOF Here's a few interesting observations: 1. This only happens when -Os or -O1 are used. 2. Even slight modifications of the above code will cause it to be inlined, for example implementing `maxFoo()` equivalently but in a single expression. 3. The same issue happens whether `consteval` is used or not (which leads me to think this is a codegen issue, not a front-end issue). Godbolt link: https://godbolt.org/z/MA9U8b After playing around and debugging Clang for a bit, I am fairly confident that this is not a bug per-se, but only an important QOI issue. In particular, I think Clang behaves correctly with respect to the Standard, which only says about immediate functions (http://eel.is/c++draft/expr.const#13): > [...] An expression or conversion is an immediate invocation if > it is a potentially-evaluated explicit or implicit invocation of > an immediate function and is not in an immediate function context. > An immediate invocation shall be a constant expression. This doesn't talk about codegen, since the Standard doesn't have such a notion. Also, Clang does treat `maxFoo()` as a constant expression, and in fact the front-end even calculates the result properly in an APValue -- so Clang is *correct* as far as the Standard is concerned. However, the code generation appears to never be passed that knowledge, and as a result it can sometimes fail to fold the immediate call, depending on optimization levels. Since the intent of consteval was *specifically* to make sure that no code is generated for such calls, I would argue this is an important QOI issue (if we're being pedantic), and straight up a bug (as far as 99% of users are concerned).
This may not technically be a bug, but it is a serious deviation from the intent, and this is one of the primary reasons why Clang does not claim to support `consteval` yet.
yeah, this isn't implemented yet. i have a patch to fix this https://reviews.llvm.org/D76420
the patch has landed and the problem should be fixed.