clang(trunk) gives an error for the following code:
consteval void f() {}
int main()
{
f(); // error: call to consteval function 'f' is not a constant expression
// note: subobject of type 'void' is not initialized
}
while gcc(trunk) compiles this without error.
I feel this is probably a clang bug, since both gcc and clang accept this code:
consteval int g() { return 42; }
int main()
{
g(); // ok
}
Here's the code to play with.
So is this a clang bug, or is the code ill-formed, or have ub, or something else?
Edit: I feel it might be relevant to point out that clang allows calling f
from other functions if they are also consteval. It only gives the error when f
is called from non-consteval functions:
consteval int h()
{
f(); // ok
return 42;
}
demo.
This was a Clang bug that was both introduced between version 10 and version 11, and fixed last month. The implementation of consteval
in Clang is mostly, but not entirely, complete, and this bug arose after one of the patches adding more complete consteval
support.
Details: the top-level entry point into Clang's constant evaluator checks whether the result is a permitted result of a constant expression -- it checks that the result doesn't contain pointers to automatic storage duration or a temporary or similar. But this check was never updated to accommodate for void
being a literal type, and would reject values of type void
for being "uninitialized". This was never noticed before the addition of consteval
support, because all top-level constant evaluations were of non-void
types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With