llvm / llvm/llvm-project

[19 regression] crash if template-id used to name base class of dependent member of the current instantiation

Open
#195,133 3 comments 0 reactions 0 assignees View on GitHub
c++ clang:frontend crash-on-valid regression:19
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.