__builtin_is_constant_evaluated is the builtin used to for implementing std::is_constant_evaluated in the standard library on clang and gcc.
code that is not valid in constant context is also often harder for the optimizer to constant fold.
for example:
int f(int i) {
if (__builtin_is_constant_evaluated())
return 1;
else {
int* ptr = new int(1);
int i = *ptr;
delete ptr;
return i;
}
}
is emitted by gcc -O3 as:
f(int):
sub rsp, 8
mov edi, 4
call operator new(unsigned long)
mov esi, 4
mov rdi, rax
call operator delete(void*, unsigned long)
mov eax, 1
add rsp, 8
ret
so the optimizer used __builtin_is_constant_evaluated() == 0
clang fold this to a constant but this is because clang's optimizer can remove unneeded dynamic allocation, not because it used __builtin_is_constant_evaluated() == 1.
i am aware that this would make the return value of __builtin_is_constant_evaluated() implementation defined because optimization vary from one compiler to an other. but is_constant_evaluated should already be used only when both path have the same observable behaviors.
why does the optimizer not use __builtin_is_constant_evaluated() == 1 and fallback to __builtin_is_constant_evaluated() == 0 if it wasn't able to fold ?