llvm / llvm/llvm-project

[clang][Sema] Crash in MultiLevelTemplateArgumentList with dependent member decltype using Completion

Open
#204,059 2 comments 0 reactions 0 assignees View on GitHub
clang:frontend clangd confirmed crash generated by fuzzer
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

This input is generated by a fuzzer.
https://godbolt.org/z/Tn54j6GYT
```cxx
template
auto k(T t) -> decltype (t.U::template B<>::MEM);
void t() {
k( C() );
}
```
```
-fsyntax-only -Xclang -code-completion-at=example.cpp:4:6
```

It seems that this input will trigger crash since clang8. However, since clang 20, the assertion changed.
Before clang20, it shows:
```
`Index < TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size()' failed.
```

Since clang20, it shows:
```
Assertion `getKind() == Type && "Unexpected kind"' failed.
```

I am not sure whether it's related to https://github.com/llvm/llvm-project/issues/162125 because before clang20. the stacktrace looks similar to it.

Current stacktrace:
```
:4:3: error: use of undeclared identifier 'C'
4 | k(C());
| ^
clang++: /root/llvm-project/clang/include/clang/Sema/Template.h:156: const clang::TemplateArgument& clang::MultiLevelTemplateArgumentList::operator()(unsigned int, unsigned int) const: Assertion `Index < TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size()' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0. Program arguments: /opt/compiler-explorer/clang-assertions-19.1.0/bin/clang++ -g -o /app/output.s -mllvm --x86-asm-syntax=intel -fno-verbose-asm -S --gcc-toolchain=/opt/compiler-explorer/gcc-14.2.0 -fcolor-diagnostics -fno-crash-diagnostics -fsyntax-only -Xclang -code-completion-at=example.cpp:4:6
1. parser at end of file
2. :3:10: parsing function body 't'
3. :3:10: in compound statement ('{}')
#0 0x0000000003ae9978 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x3ae9978)
#1 0x0000000003ae766c llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x3ae766c)
#2 0x0000000003a308f8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
#3 0x00007b264f845330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
#4 0x00007b264f89eb2c pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x9eb2c)
#5 0x00007b264f84527e raise (/lib/x86_64-linux-gnu/libc.so.6+0x4527e)
#6 0x00007b264f8288ff abort (/lib/x86_64-linux-gnu/libc.so.6+0x288ff)
#7 0x00007b264f82881b (/lib/x86_64-linux-gnu/libc.so.6+0x2881b)
#8 0x00007b264f83b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)
#9 0x000000000718a02b clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr*) SemaTemplateInstantiate.cpp:0:0
#10 0x000000000715bab6 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(clang::Expr*) SemaTemplateInstantiate.cpp:0:0
#11 0x000000000716c48c clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(clang::TypeLocBuilder&, clang::TypeLoc) SemaTemplateInstantiate.cpp:0:0
#12 0x0000000007194987 clang::Sema::SubstFunctionDeclType(clang::TypeSourceInfo*, clang::MultiLevelTemplateArgumentList const&, clang::SourceLocation, clang::DeclarationName, clang::CXXRecordDecl*, clang::Qualifiers, bool) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x7194987)
#13 0x00000000071cdd5e clang::TemplateDeclInstantiator::SubstFunctionType(clang::FunctionDecl*, llvm::SmallVectorImpl&) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x71cdd5e)
#14 0x00000000072232ea clang::TemplateDeclInstantiator::VisitFunctionDecl(clang::FunctionDecl*, clang::TemplateParameterList*, clang::TemplateDeclInstantiator::RewriteKind) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x72232ea)
#15 0x0000000007227394 void llvm::function_ref::callback_fn(long) SemaTemplateInstantiateDecl.cpp:0:0
#16 0x000000000663df41 clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x663df41)
#17 0x00000000071cdb1a clang::Sema::SubstDecl(clang::Decl*, clang::DeclContext*, clang::MultiLevelTemplateArgumentList const&) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x71cdb1a)
#18 0x000000000709a53e clang::Sema::FinishTemplateArgumentDeduction(clang::FunctionTemplateDecl*, llvm::SmallVectorImpl&, unsigned int, clang::FunctionDecl*&, clang::sema::TemplateDeductionInfo&, llvm::SmallVectorImpl const*, bool, llvm::function_ref) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x709a53e)
#19 0x000000000709ca5a void llvm::function_ref::callback_fn, clang::FunctionDecl*&, clang::sema::TemplateDeductionInfo&, bool, bool, clang::QualType, clang::Expr::Classification, llvm::function_ref)>)::'lambda1'()>(long) SemaTemplateDeduction.cpp:0:0
#20 0x000000000663df41 clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x663df41)
#21 0x00000000070a78c2 clang::Sema::DeduceTemplateArguments(clang::FunctionTemplateDecl*, clang::TemplateArgumentListInfo*, llvm::ArrayRef, clang::FunctionDecl*&, clang::sema::TemplateDeductionInfo&, bool, bool, clang::QualType, clang::Expr::Classification, llvm::function_ref)>) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x70a78c2)
#22 0x0000000006eba5e8 clang::Sema::AddTemplateOverloadCandidate(clang::FunctionTemplateDecl*, clang::DeclAccessPair, clang::TemplateArgumentListInfo*, llvm::ArrayRef, clang::OverloadCandidateSet&, bool, bool, bool, clang::CallExpr::ADLCallKind, clang::OverloadCandidateParamOrder, bool) (.constprop.1) SemaOverload.cpp:0:0
#23 0x0000000006ebadeb AddOverloadedCallCandidate(clang::Sema&, clang::DeclAccessPair, clang::TemplateArgumentListInfo*, llvm::ArrayRef, clang::OverloadCandidateSet&, bool, bool) SemaOverload.cpp:0:0
#24 0x0000000006ebb0d9 clang::Sema::AddOverloadedCallCandidates(clang::UnresolvedLookupExpr*, llvm::ArrayRef, clang::OverloadCandidateSet&, bool) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x6ebb0d9)
#25 0x000000000677c359 clang::SemaCodeCompletion::ProduceCallSignatureHelp(clang::Expr*, llvm::ArrayRef, clang::SourceLocation) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x677c359)
#26 0x000000000654dee2 clang::Parser::ParsePostfixExpressionSuffix(clang::ActionResult) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x654dee2)
#27 0x0000000006546e21 clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x6546e21)
#28 0x0000000006548f7a clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x6548f7a)
#29 0x0000000006549119 clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x6549119)
#30 0x000000000654d9a9 clang::Parser::ParseExpression(clang::Parser::TypeCastState) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x654d9a9)
#31 0x00000000065ce309 clang::Parser::ParseExprStatement(clang::Parser::ParsedStmtContext) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x65ce309)
#32 0x00000000065c4d02 clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector&, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::ParsedAttributes&, clang::ParsedAttributes&) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x65c4d02)
#33 0x00000000065c5cc0 clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x65c5cc0)
#34 0x00000000065c6ba9 clang::Parser::ParseCompoundStatementBody(bool) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x65c6ba9)
#35 0x00000000065c837a clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x65c837a)
#36 0x00000000064dd6c3 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x64dd6c3)
#37 0x0000000006512708 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::Parser::ParsedTemplateInfo&, clang::SourceLocation*, clang::Parser::ForRangeInit*) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x6512708)
#38 0x00000000064d115e clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x64d115e)
#39 0x00000000064d190e clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x64d190e)
#40 0x00000000064d8077 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x64d8077)
#41 0x00000000064d8f6f clang::Parser::ParseTopLevelDecl(clang::OpaquePtr&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x64d8f6f)
#42 0x00000000064cc33a clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x64cc33a)
#43 0x0000000004684f59 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x4684f59)
#44 0x0000000004609f8e clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x4609f8e)
#45 0x000000000476e2be clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x476e2be)
#46 0x0000000000c82b7f cc1_main(llvm::ArrayRef, char const*, void*) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0xc82b7f)
#47 0x0000000000c7bcda ExecuteCC1Tool(llvm::SmallVectorImpl&, llvm::ToolContext const&) driver.cpp:0:0
#48 0x000000000443cba9 void llvm::function_ref::callback_fn>, std::__cxx11::basic_string, std::allocator>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#49 0x0000000003a30da4 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x3a30da4)
#50 0x000000000443d19f clang::driver::CC1Command::Execute(llvm::ArrayRef>, std::__cxx11::basic_string, std::allocator>*, bool*) const (.part.0) Job.cpp:0:0
#51 0x0000000004402c05 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x4402c05)
#52 0x000000000440366d clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl>&, bool) const (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x440366d)
#53 0x000000000440b075 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl>&) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0x440b075)
#54 0x0000000000c7fe95 clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0xc7fe95)
#55 0x0000000000b547a4 main (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0xb547a4)
#56 0x00007b264f82a1ca (/lib/x86_64-linux-gnu/libc.so.6+0x2a1ca)
#57 0x00007b264f82a28b __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28b)
#58 0x0000000000c7b78e _start (/opt/compiler-explorer/clang-assertions-19.1.0/bin/clang+++0xc7b78e)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
Compiler returned: 134
```

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the godbolt input with -fsyntax-only -Xclang -code-completion-at=example.cpp:4:6 using an assertion-enabled Clang. Read clang/include/clang/Sema/Template.h and the TransformCXXDependentScopeMemberExpr path in SemaTemplateInstantiate.cpp. Done means this input no longer triggers an assertion or crash and still produces an appropriate diagnostic.

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.