llvm / llvm/llvm-project

[Clang] Crash on fold expression involving lambda with requires clause

Open
#199,524 3 comments 0 reactions 0 assignees View on GitHub
clang:frontend concepts confirmed crash-on-valid lambda
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

```c++
template
constexpr auto count_invocable{[] (auto... args) {
return (0U + ... +
requires { [] (auto) requires (sizeof(args) > 1) {}(0); }
);
}};

static_assert(count_invocable(0, 1) == 2);
```

See https://compiler-explorer.com/z/3nTnWvadd.

Assertion:
```console
clang++: /root/llvm-project/llvm/tools/clang/lib/AST/ExprCXX.cpp:2038:
clang::CXXFoldExpr::CXXFoldExpr(clang::QualType, clang::UnresolvedLookupExpr*, clang::SourceLocation, clang::Expr*, clang::BinaryOperatorKind, clang::SourceLocation, clang::Expr*, clang::SourceLocation, clang::UnsignedOrNone):
Assertion `LHS->containsUnexpandedParameterPack() != RHS->containsUnexpandedParameterPack() && "Exactly one of LHS or RHS should contain an unexpanded pack"' failed.
```

Stack dump

```console
0. Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/clang++ -g -o /app/output.s -mllvm --x86-asm-syntax=intel -fno-verbose-asm -S --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot -fcolor-diagnostics -fno-crash-diagnostics -std=c++20
1. :8:36: current parser token '('
#0 0x000000000458fa58 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x458fa58)
#1 0x000000000458c894 llvm::sys::RunSignalHandlers() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x458c894)
#2 0x000000000458ceb4 llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x458ceb4)
#3 0x00000000044c9428 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
#4 0x000076c5b8c42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
#5 0x000076c5b8c969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
#6 0x000076c5b8c42476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
#7 0x000076c5b8c287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
#8 0x000076c5b8c2871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
#9 0x000076c5b8c39e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#10 0x000000000839722c (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x839722c)
#11 0x0000000007bb0cee clang::Sema::BuildCXXFoldExpr(clang::UnresolvedLookupExpr*, clang::SourceLocation, clang::Expr*, clang::BinaryOperatorKind, clang::SourceLocation, clang::Expr*, clang::SourceLocation, clang::OptionalUnsigned) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7bb0cee)
#12 0x0000000007ada2bf clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCXXFoldExpr(clang::CXXFoldExpr*) SemaTemplateInstantiate.cpp:0:0
#13 0x0000000007ab2eb8 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(clang::Expr*) SemaTemplateInstantiate.cpp:0:0
#14 0x0000000007ad3a18 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformInitializer(clang::Expr*, bool) (.part.0) SemaTemplateInstantiate.cpp:0:0
#15 0x0000000007ad3ddc clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformReturnStmt(clang::ReturnStmt*) SemaTemplateInstantiate.cpp:0:0
#16 0x0000000007af1c35 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCompoundStmt(clang::CompoundStmt*, bool) SemaTemplateInstantiate.cpp:0:0
#17 0x0000000007ab27f5 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformLambdaExpr(clang::LambdaExpr*) SemaTemplateInstantiate.cpp:0:0
#18 0x0000000007ab36c1 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(clang::Expr*) SemaTemplateInstantiate.cpp:0:0
#19 0x0000000007ad367b clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExprs(clang::Expr* const*, unsigned int, bool, llvm::SmallVectorImpl&, bool*) SemaTemplateInstantiate.cpp:0:0
#20 0x0000000007ad6e6c clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformInitListExpr(clang::InitListExpr*) SemaTemplateInstantiate.cpp:0:0
#21 0x0000000007ab3121 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(clang::Expr*) SemaTemplateInstantiate.cpp:0:0
#22 0x0000000007ad3a18 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformInitializer(clang::Expr*, bool) (.part.0) SemaTemplateInstantiate.cpp:0:0
#23 0x0000000007ad4674 clang::Sema::SubstInitializer(clang::Expr*, clang::MultiLevelTemplateArgumentList const&, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7ad4674)
#24 0x0000000007b429e8 clang::Sema::InstantiateVariableInitializer(clang::VarDecl*, clang::VarDecl*, clang::MultiLevelTemplateArgumentList const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7b429e8)
#25 0x0000000007b9640c clang::Sema::BuildVariableInstantiation(clang::VarDecl*, clang::VarDecl*, clang::MultiLevelTemplateArgumentList const&, llvm::SmallVector*, clang::DeclContext*, clang::LocalInstantiationScope*, bool, clang::VarTemplateSpecializationDecl*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7b9640c)
#26 0x0000000007b96a11 clang::TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(clang::VarTemplateDecl*, clang::VarDecl*, llvm::ArrayRef, clang::VarTemplateSpecializationDecl*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7b96a11)
#27 0x0000000007ba2b1a clang::Sema::BuildVarTemplateInstantiation(clang::VarTemplateDecl*, clang::VarDecl*, clang::TemplateArgumentList const*, llvm::SmallVectorImpl&, clang::SourceLocation, llvm::SmallVector*, clang::LocalInstantiationScope*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7ba2b1a)
#28 0x000000000798d09a clang::Sema::CheckVarTemplateId(clang::VarTemplateDecl*, clang::SourceLocation, clang::SourceLocation, clang::TemplateArgumentListInfo const&, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x798d09a)
#29 0x000000000798dba4 clang::Sema::CheckVarTemplateId(clang::CXXScopeSpec const&, clang::DeclarationNameInfo const&, clang::VarTemplateDecl*, clang::NamedDecl*, clang::SourceLocation, clang::TemplateArgumentListInfo const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x798dba4)
#30 0x000000000798de07 clang::Sema::BuildTemplateIdExpr(clang::CXXScopeSpec const&, clang::SourceLocation, clang::LookupResult&, bool, clang::TemplateArgumentListInfo const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x798de07)
#31 0x00000000074ac328 clang::Sema::ActOnIdExpression(clang::Scope*, clang::CXXScopeSpec&, clang::SourceLocation, clang::UnqualifiedId&, bool, bool, clang::CorrectionCandidateCallback*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x74ac328)
#32 0x0000000006fdda35 clang::Parser::tryParseCXXIdExpression(clang::CXXScopeSpec&, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6fdda35)
#33 0x0000000006fddd5e clang::Parser::ParseCXXIdExpression(bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6fddd5e)
#34 0x0000000006fc1f14 clang::Parser::ParseCastExpression(clang::CastParseKind, bool, bool&, clang::TypoCorrectionTypeBehavior, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6fc1f14)
#35 0x0000000006fc17f0 clang::Parser::ParseCastExpression(clang::CastParseKind, bool, bool&, clang::TypoCorrectionTypeBehavior, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6fc17f0)
#36 0x0000000006fce79e clang::Parser::ParseConstantExpressionInExprEvalContext(clang::TypoCorrectionTypeBehavior) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6fce79e)
#37 0x0000000006fa5c16 clang::Parser::ParseStaticAssertDeclaration(clang::SourceLocation&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6fa5c16)
#38 0x0000000006f944d6 clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6f944d6)
#39 0x0000000006f4ff56 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6f4ff56)
#40 0x0000000006f50e65 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6f50e65)
#41 0x0000000006f31d0a clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6f31d0a)
#42 0x00000000050bbc58 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x50bbc58)
#43 0x00000000053ede05 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x53ede05)
#44 0x000000000536c868 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x536c868)
#45 0x00000000054ea6cd clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x54ea6cd)
#46 0x0000000000e0a61b cc1_main(llvm::ArrayRef, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xe0a61b)
#47 0x0000000000e00f7a ExecuteCC1Tool(llvm::SmallVectorImpl&, llvm::ToolContext const&, llvm::IntrusiveRefCntPtr) driver.cpp:0:0
#48 0x0000000000e010fd int llvm::function_ref&)>::callback_fn&)>(long, llvm::SmallVectorImpl&) driver.cpp:0:0
#49 0x000000000512e039 void llvm::function_ref::callback_fn>, std::__cxx11::basic_string, std::allocator>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#50 0x00000000044c9864 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x44c9864)
#51 0x000000000512e686 clang::driver::CC1Command::Execute(llvm::ArrayRef>, std::__cxx11::basic_string, std::allocator>*, bool*) const (.part.0) Job.cpp:0:0
#52 0x00000000050ec722 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x50ec722)
#53 0x00000000050ed6ce clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x50ed6ce)
#54 0x00000000050f5385 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x50f5385)
#55 0x0000000000e069a4 clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xe069a4)
#56 0x0000000000cae6ea main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xcae6ea)
#57 0x000076c5b8c29d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#58 0x000076c5b8c29e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#59 0x0000000000e00a15 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xe00a15)
```

Contributor guide

Open the contributing guide

Research direction

Reproduce the C++20 example with Clang assertions enabled and inspect clang/lib/AST/ExprCXX.cpp around the CXXFoldExpr assertion, then follow the instantiation path through SemaTemplateInstantiate.cpp. Determine why the lambda requires-clause produces invalid unexpanded-pack state; done means the example no longer crashes and regression coverage is added.

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
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.