[clang:frontend] Expression is not constant because initializer is not known
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
See the code at [Compile Explorer link](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:47,endLineNumber:12,positionColumn:47,positionLineNumber:12,selectionStartColumn:47,selectionStartLineNumber:12,startColumn:47,startLineNumber:12),source:'%0Atemplate%3Ctypename+T%3E%0Astruct+foo%0A%7B%0A++++static+constinit+const+foo+FooConstant%3B%0A++++static+constinit+const+int+IntConstant%3B%0A%0A++++int+value_+%7B%7D%3B%0A%7D%3B%0A%0Atemplate%3Ctypename+T%3E%0Aconstexpr+inline+foo%3CT%3E+foo%3CT%3E::FooConstant%7B1%7D%3B%0A%0Atemplate%3Ctypename+T%3E%0Aconstexpr+inline+int+foo%3CT%3E::IntConstant%7B1%7D%3B%0A%0Atemplate%3C%3E%0Aconstexpr+inline+foo%3Cvoid%3E+foo%3Cvoid%3E::FooConstant%7B1%7D%3B%0A%0Ausing+FooInt+%3D+foo%3Cint%3E%3B%0Ausing+FooVoid+%3D+foo%3Cvoid%3E%3B%0A%0Astatic_assert(FooInt::IntConstant)%3B+++++++++//+Ok%0Astatic_assert(FooInt::FooConstant.value_)%3B++//+Error%0Astatic_assert(FooVoid::FooConstant.value_)%3B+//+Ok%0Astatic_assert(FooVoid::IntConstant)%3B++++++++//+Ok%0A'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:45.608327911515936,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:compiler,i:(compiler:clang_trunk,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!(),options:'-std%3Dc%2B%2B26',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+clang+(trunk)+(Editor+%231)',t:'0')),k:50,l:'4',m:50,n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'x86-64+gcc+16.1',editorid:1,fontScale:14,fontUsePx:'0',j:1,wrap:'1'),l:'5',n:'0',o:'Output+of+x86-64+clang+(trunk)+(Compiler+%231)',t:'0')),header:(),l:'4',m:50,n:'0',o:'',s:0,t:'0')),k:54.39167208848406,l:'3',n:'0',o:'',t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)
The same code is copy pasted here:
```c++
template
struct foo
{
static constinit const foo FooConstant;
static constinit const int IntConstant;
int value_ {};
};
template
constexpr inline foo foo::FooConstant{1};
template
constexpr inline int foo::IntConstant{1};
template<>
constexpr inline foo foo::FooConstant{1};
using FooInt = foo;
using FooVoid = foo;
static_assert(FooInt::IntConstant); // Ok
static_assert(FooInt::FooConstant.value_); // Error
static_assert(FooVoid::FooConstant.value_); // Ok
static_assert(FooVoid::IntConstant); // Ok
```
Clang's output:
```
:24:15: error: static assertion expression is not an integral constant expression
24 | static_assert(FooInt::FooConstant.value_); // Error
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
:24:15: note: initializer of 'FooConstant' is unknown
:5:32: note: declared here
5 | static constinit const foo FooConstant;
| ^
1 error generated.
```
Possibly rejects-valid because GCC compiles the same code, I don't see anything wrong with it.
It is not the same as #166166 because this error requires an out of line template definition, and it requires the static data member to be of the same type as the class template enclosing it, as the example shows.
Contributor guide
Research direction
Reproduce the reduced C++26 example with Clang trunk from the Compile Explorer link, then compare its result with GCC. Start by tracing constant-expression evaluation for the out-of-line templated FooConstant definition and the FooInt specialization; done means Clang accepts the FooInt::FooConstant.value_ static assertion without regressing the other assertions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100