[clang-tools-extra] [clangd] fix crashes in SemanticHighlighting on NTTP typed `decltype(constexpr-auto-variable)` (PR #207323)
Nathan Ridge via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 5 23:56:43 PDT 2026
HighCommander4 wrote:
Testcase for reference:
```c++
constexpr auto v = 0;
template <decltype(v) t> class c {};
```
This is `TSI->getType()`, i.e. the type of the NTTP as written in the source:
```
DecltypeType 0x55bf2ddb8fa0 'decltype(v)' sugar
|-DeclRefExpr 0x55bf2ddb8f80 'const int' lvalue Var 0x55bf2ddb8d30 'v' 'const int' non_odr_use_unevaluated
`-QualType 0x55bf2ddb8ef1 'const int' const
`-AutoType 0x55bf2ddb8ef0 'int' sugar
`-BuiltinType 0x55bf2dd88930 'int'
```
It's a `DecltypeType` because that's how the type is written. The value of the decltype is "the declared type of `v`", which is a `QualType` because `v` is `const`, wrapping an `AutoType` because `v` is declared with `auto`, wrapping a `BuiltinType` because `int` is what the `auto` is deduced to.
When computing the type that the NTTP's `getType()` will return, however, `[temp.param]p5` needs to be obeyed: "The top-level cv-qualifiers on the template-parameter are ignored when determining its type.", which happens [here](https://searchfox.org/llvm/rev/4fb7bf3323ea54d929f3846e6cd28d9dda1b891c/clang/lib/Sema/SemaTemplate.cpp#1477-1479). This requires removing the `DecltypeType` sugar, so that `getType()` is just:
```
AutoType 0x55bf2ddb8ef0 'int' sugar
`-BuiltinType 0x55bf2dd88930 'int'
```
This type will naturally return true for `getContainedAutoType()`, but the original `DecltypeType` will not. This is [deliberate](https://searchfox.org/llvm/rev/4fb7bf3323ea54d929f3846e6cd28d9dda1b891c/clang/include/clang/AST/TypeBase.h#2960-2965): "This looks through declarators like pointer types, but not through decltype or typedefs." (The intention is to find an `auto` type written at the variable's declaration, not a referenced `auto` type that's written somewhere else, as is the case here.)
Conclusions:
* The AST modeling here seems reasonable
* The patch produces the desired outcome (we do _not_ want this call to produce a highlighting token for the `AutoType` returned by `D->getType()`, because that's actually an `auto` type written in a different declaration)
https://github.com/llvm/llvm-project/pull/207323
More information about the cfe-commits
mailing list