llvm / llvm/llvm-project

[clang][AST] Explicit function template specialization creates extra redecl from primary template

Open
#206,790 1 comment 0 reactions 0 assignees View on GitHub
clang:frontend
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Given this code:

```cpp
template int &add(T &a);

template <> int &add(int &a);

template <> int &add(int &a) { return a; }
```

When walking the redeclaration chain for the explicit specialization definition, I see an extra `FunctionDecl` before the user-written specialization declaration:

```text
FunctionDecl 0x55a63817a8e8 line:3:18 add 'int &(int &)' explicit_specialization external-linkage
|-TemplateArgument type 'int'
| `-BuiltinType 0x55a63812b540 'int'
`-ParmVarDecl 0x55a63817a810 col:35 a 'int &'

FunctionDecl 0x55a63817a508 prev 0x55a63817a8e8 col:18 add 'int &(int &)' explicit_specialization external-linkage
|-TemplateArgument type 'int'
| `-BuiltinType 0x55a63812b540 'int'
`-ParmVarDecl 0x55a63817a430 col:32 a 'int &'
```

The first decl looks like it was created from the primary template, its source range and parameter location point at the primary template, but its name location points at the explicit specialization.

This decl does not show up as a normal `FunctionDecl` in the AST dump. The AST dump only seems to reference it indirectly through the `prev` chain:

```text
...
|-FunctionTemplateDecl 0x55a63817a2c0 col:28 add external-linkage
| |-TemplateTypeParmDecl 0x55a638179f80 col:20 referenced typename depth 0 index 0 T
| |-FunctionDecl 0x55a63817a218 col:28 add 'int &(T &)'
| | `-ParmVarDecl 0x55a63817a0d0 col:35 a 'T &'
| `-Function 0x55a63817ab48 'add' 'int &(int &)'
|-FunctionDecl 0x55a63817a508 prev 0x55a63817a8e8 col:18 add 'int &(int &)' explicit_specialization external-linkage
| // `prev 0x55a63817a8e8` references the first explicit specialization from the
| // redecl-chain dump, even though that decl does not appear here as a full FunctionDecl.
| |-TemplateArgument type 'int'
| | `-BuiltinType 0x55a63812b540 'int'
| `-ParmVarDecl 0x55a63817a430 col:32 a 'int &'
...
```

I would not expect this generated-looking decl to appear in the redeclaration chain as an explicit specialization redecl. It looks like an internal decl created while checking/deducing the explicit specialization is being left in the actual redecl chain.

https://godbolt.org/z/oxY75P6e8

cc: @AaronBallman @erichkeane

Contributor guide

Open the contributing guide

Research direction

Reproduce the explicit function-template specialization example using the linked Godbolt case and inspect the redeclaration chain and AST dump. The report names no repository file or test path, so trace the Clang AST handling for explicit specialization redeclarations. Done means the generated-looking declaration is no longer left in the actual explicit-specialization redeclaration chain.

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
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.