Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clang says call to void consteval function is not a constant expression

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.

like image 538
cigien Avatar asked Aug 11 '20 19:08

cigien


Video Answer


1 Answers

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.

like image 166
Richard Smith Avatar answered Oct 07 '22 15:10

Richard Smith