llvm / llvm/llvm-project

__PRETTY_FUNCTION__ changes depending on template instantiation

Open
#174,430 6 comments 0 reactions 0 assignees View on GitHub
clang:frontend documentation
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

```cpp
template
[[nodiscard]] constexpr
auto PrettyValueFn() {
return __PRETTY_FUNCTION__;
}

template
struct TestTemplate {
enum class TestScopedEnum { X, Y, Z };
};

#include

int main() {
// (void) TestTemplate::TestScopedEnum::X; // Access value first and the output is as expected
(void) PrettyValueFn::TestScopedEnum{}>(); // Changes __PRETTY_FUNCTION__ for given index
std::cout << PrettyValueFn::TestScopedEnum::X>() << '\n';
std::cout << PrettyValueFn::TestScopedEnum::Y>() << '\n';
std::cout << PrettyValueFn::TestScopedEnum::Z>() << '\n';
}
```

Output:

```
auto PrettyValueFn() [V = (TestTemplate::TestScopedEnum)0]
auto PrettyValueFn() [V = TestTemplate::TestScopedEnum::Y]
auto PrettyValueFn() [V = TestTemplate::TestScopedEnum::Z]
```

Expected output:

```
auto PrettyValueFn() [V = TestTemplate::TestScopedEnum::X]
auto PrettyValueFn() [V = TestTemplate::TestScopedEnum::Y]
auto PrettyValueFn() [V = TestTemplate::TestScopedEnum::Z]
```

This happens if you use a scoped enum in a template.

It works as expected, if you use a non-scoped enum or if your scoped enum is not defined in a template.

[Compiler Explorer](https://gcc.godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:1,endLineNumber:21,positionColumn:1,positionLineNumber:21,selectionStartColumn:1,selectionStartLineNumber:21,startColumn:1,startLineNumber:21),source:'template+%3Cauto+V%3E%0A%5B%5Bnodiscard%5D%5D+constexpr%0Aauto+PrettyValueFn()+%7B%0A++++return+__PRETTY_FUNCTION__%3B%0A%7D%0A%0Atemplate+%3Ctypename%3E%0Astruct+TestTemplate+%7B%0A++++enum+class+TestScopedEnum+%7B+X,+Y,+Z+%7D%3B%0A%7D%3B%0A%0A%0A%23include+%3Ciostream%3E%0A%0Aint+main()+%7B%0A++++(void)+PrettyValueFn%3Cstatic_cast%3CTestTemplate%3Cint%3E::TestScopedEnum%3E(0)%3E()%3B+//+Changes+__PRETTY_FUNCTION__+for+given+index%0A++++std::cout+%3C%3C+PrettyValueFn%3CTestTemplate%3Cint%3E::TestScopedEnum::X%3E()+%3C%3C+!'%5Cn!'%3B%0A++++std::cout+%3C%3C+PrettyValueFn%3CTestTemplate%3Cint%3E::TestScopedEnum::Y%3E()+%3C%3C+!'%5Cn!'%3B%0A++++std::cout+%3C%3C+PrettyValueFn%3CTestTemplate%3Cint%3E::TestScopedEnum::Z%3E()+%3C%3C+!'%5Cn!'%3B%0A%7D%0A'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:33.333333333333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang2110,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'0',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%2B17',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+21.1.0+(Editor+%231)',t:'0')),k:33.333333333333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'x86-64+clang+21.1.0',editorid:1,fontScale:14,fontUsePx:'0',j:1,wrap:'1'),l:'5',n:'0',o:'Output+of+x86-64+clang+21.1.0+(Compiler+%231)',t:'0')),k:33.33333333333333,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)

All versions of Clang up to the current HEAD are affected.

Contributor guide

Open the contributing guide

Research direction

Start with the reduced C++ reproducer in the issue and compare Clang's __PRETTY_FUNCTION__ output for scoped enums defined inside and outside templates, including the non-scoped enum case. Trace the compiler handling of the non-type template argument and add a regression test if the relevant test location can be identified. Done means the X, Y, and Z instantiations all produce their enumerator names rather than an underlying numeric value.

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
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.