[19 regression] crash if template-id used to name base class of dependent member of the current instantiation
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
This testcase (found while reducing a testcase from #59910) crashes in Clang 19 onwards: https://godbolt.org/z/8rP91nMGK
```c++
template struct A { void f(); };
template struct X {
struct S : A {};
static void f(S *p) {
p->template A::f();
}
};
void g() { X::f(nullptr); }
```
(This crashes with or without the `template` disambiguator, so this is a separate issue from #59910.)
Assertion:
```console
clang++: /root/llvm-project/llvm/tools/clang/include/clang/AST/DeclCXX.h:463:
clang::CXXRecordDecl::DefinitionData& clang::CXXRecordDecl::data() const:
Assertion `DD && "queried property of class with no definition"' failed.
```
Backtrace:
```console
#0 0x0000000004545358 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4545358)
#1 0x0000000004542184 llvm::sys::RunSignalHandlers() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4542184)
#2 0x00000000045427a4 llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x45427a4)
#3 0x000000000447e678 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
#4 0x0000749800642520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
#5 0x00007498006969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
#6 0x0000749800642476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
#7 0x00007498006287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
#8 0x000074980062871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
#9 0x0000749800639e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#10 0x0000000008040059 clang::CXXRecordDecl::forallBases(llvm::function_ref) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x8040059)
#11 0x00000000080441a0 clang::CXXRecordDecl::isProvablyNotDerivedFrom(clang::CXXRecordDecl const*) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x80441a0)
#12 0x00000000074b14a0 clang::Sema::CheckQualifiedMemberReference(clang::Expr*, clang::QualType, clang::CXXScopeSpec const&, clang::LookupResult const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x74b14a0)
#13 0x00000000074b22e8 clang::Sema::BuildMemberReferenceExpr(clang::Expr*, clang::QualType, clang::SourceLocation, bool, clang::CXXScopeSpec const&, clang::SourceLocation, clang::NamedDecl*, clang::LookupResult&, clang::TemplateArgumentListInfo const*, clang::Scope const*, bool, clang::Sema::ActOnMemberAccessExtraArgs*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x74b22e8)
#14 0x00000000079e1de8 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformMemberExpr(clang::MemberExpr*) SemaTemplateInstantiate.cpp:0:0
#15 0x00000000079b11f1 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(clang::Expr*) SemaTemplateInstantiate.cpp:0:0
#16 0x00000000079d5086 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCallExpr(clang::CallExpr*) SemaTemplateInstantiate.cpp:0:0
#17 0x00000000079b0fa7 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(clang::Expr*) SemaTemplateInstantiate.cpp:0:0
#18 0x00000000079ef3e7 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformStmt(clang::Stmt*, clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::StmtDiscardKind) SemaTemplateInstantiate.cpp:0:0
#19 0x00000000079efaa5 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCompoundStmt(clang::CompoundStmt*, bool) SemaTemplateInstantiate.cpp:0:0
#20 0x00000000079f8f63 clang::Sema::SubstStmt(clang::Stmt*, clang::MultiLevelTemplateArgumentList const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x79f8f63)
#21 0x0000000007a97e8c clang::Sema::InstantiateFunctionDefinition(clang::SourceLocation, clang::FunctionDecl*, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7a97e8c)
#22 0x0000000007a960f6 clang::Sema::PerformPendingInstantiations(bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7a960f6)
#23 0x0000000006ff6902 clang::Sema::ActOnEndOfTranslationUnitFragment(clang::TUFragmentKind) (.part.0) Sema.cpp:0:0
#24 0x0000000006ff6c82 clang::Sema::ActOnEndOfTranslationUnit() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6ff6c82)
#25 0x0000000006e5b19a clang::Parser::ParseTopLevelDecl(clang::OpaquePtr&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6e5b19a)
#26 0x0000000006e3beba clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6e3beba)
#27 0x000000000505b9f8 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x505b9f8)
#28 0x000000000537caf5 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x537caf5)
#29 0x00000000052fb6e8 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x52fb6e8)
#30 0x00000000054791ad clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x54791ad)
#31 0x0000000000deca3b cc1_main(llvm::ArrayRef, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xdeca3b)
#32 0x0000000000de339a ExecuteCC1Tool(llvm::SmallVectorImpl&, llvm::ToolContext const&, llvm::IntrusiveRefCntPtr) driver.cpp:0:0
#33 0x0000000000de351d int llvm::function_ref&)>::callback_fn&)>(long, llvm::SmallVectorImpl&) driver.cpp:0:0
#34 0x00000000050c5c49 void llvm::function_ref::callback_fn>, std::__cxx11::basic_string, std::allocator>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#35 0x000000000447eab4 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x447eab4)
#36 0x00000000050c6276 clang::driver::CC1Command::Execute(llvm::ArrayRef>, std::__cxx11::basic_string, std::allocator>*, bool*) const (.part.0) Job.cpp:0:0
#37 0x0000000005084872 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5084872)
#38 0x000000000508581e clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x508581e)
#39 0x000000000508d4c5 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x508d4c5)
#40 0x0000000000de8dc4 clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xde8dc4)
#41 0x0000000000ca132a main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xca132a)
#42 0x0000749800629d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#43 0x0000749800629e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#44 0x0000000000de2e35 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xde2e35)
```
Contributor guide
Research direction
Start by compiling the reduced C++ testcase from the issue with Clang 19 or newer and confirm the assertion. Trace the template-instantiation path through TransformMemberExpr in SemaTemplateInstantiate.cpp, then CheckQualifiedMemberReference and BuildMemberReferenceExpr; done means the testcase no longer crashes and the regression remains covered.
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
- 48/100