llvm / llvm/llvm-project

[Clang] Crash on fold expression over structured binding pack in expansion statement

Open
#221,315 6 comments 0 reactions 0 assignees View on GitHub
clang:frontend
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

This crashes in CodeGen (https://godbolt.org/z/zs6ze3Kr3):
```c++
struct S {
int x;
int y;
};

int f() {
S s{1, 2};
template for (int _ : {0}) {
auto [...members] = s;
return (members + ...);
}
}
```
Attempting to constant-evaluate `f()` crashes in the constant evaluator instead (https://godbolt.org/z/3az5b6sGG).

### CodeGen Crash
Assertion:
```console
Unexpected placeholder builtin type!
UNREACHABLE executed at /root/llvm-project/llvm/tools/clang/lib/CodeGen/CodeGenTypes.cpp:602!
```
Stack Trace:
```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++26
1. parser at end of file
2. :6:5: LLVM IR generation of declaration 'f'
3. :6:5: Generating code for declaration 'f'
4. :8:32: LLVM IR generation of compound statement ('{}')
5. :8:32: LLVM IR generation of compound statement ('{}')
#0 0x000000000448cc18 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x448cc18)
#1 0x0000000004489e74 llvm::sys::RunSignalHandlers() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4489e74)
#2 0x000000000448a4ac llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x448a4ac)
#3 0x00000000043c71c8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
#4 0x00007b233ae45330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
#5 0x00007b233ae9ec0c pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x9ec0c)
#6 0x00007b233ae4527e raise (/lib/x86_64-linux-gnu/libc.so.6+0x4527e)
#7 0x00007b233ae288ff abort (/lib/x86_64-linux-gnu/libc.so.6+0x288ff)
#8 0x00000000043d14ca (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x43d14ca)
#9 0x0000000004c6df56 clang::CodeGen::CodeGenTypes::ConvertType(clang::QualType) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4c6df56)
#10 0x00000000049d960c (anonymous namespace)::ScalarExprEmitter::VisitExpr(clang::Expr*) (.isra.0) CGExprScalar.cpp:0:0
#11 0x00000000049ef778 clang::StmtVisitorBase::Visit(clang::Stmt*) CGExprScalar.cpp:0:0
#12 0x00000000049f519c clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x49f519c)
#13 0x0000000004b1a09d clang::CodeGen::CodeGenFunction::EmitReturnStmt(clang::ReturnStmt const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b1a09d)
#14 0x0000000004b2a12b clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b2a12b)
#15 0x0000000004b2a44d clang::CodeGen::CodeGenFunction::EmitCompoundStmt(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b2a44d)
#16 0x0000000004b2a5db clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*, llvm::ArrayRef) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b2a5db)
#17 0x0000000004b21d99 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b21d99)
#18 0x0000000004b2a12b clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b2a12b)
#19 0x0000000004b2a44d clang::CodeGen::CodeGenFunction::EmitCompoundStmt(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b2a44d)
#20 0x0000000004b2a5db clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*, llvm::ArrayRef) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b2a5db)
#21 0x0000000004b21d99 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b21d99)
#22 0x0000000004b257ad clang::CodeGen::CodeGenFunction::EmitCXXExpansionStmtInstantiation(clang::CXXExpansionStmtInstantiation const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b257ad)
#23 0x0000000004b107ec clang::CodeGen::CodeGenFunction::EmitDeclStmt(clang::DeclStmt const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b107ec)
#24 0x0000000004b2a577 clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*, llvm::ArrayRef) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b2a577)
#25 0x0000000004b21d99 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b21d99)
#26 0x0000000004b2a12b clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b2a12b)
#27 0x0000000004b93646 clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::Stmt const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b93646)
#28 0x0000000004ba7e84 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4ba7e84)
#29 0x0000000004c19752 clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4c19752)
#30 0x0000000004c128c4 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4c128c4)
#31 0x0000000004c13890 clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4c13890)
#32 0x0000000004c20839 clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) (.part.0) CodeGenModule.cpp:0:0
#33 0x0000000004fa0569 (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) ModuleBuilder.cpp:0:0
#34 0x0000000004f91544 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4f91544)
#35 0x0000000006ddcb84 clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6ddcb84)
#36 0x0000000004f9e238 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4f9e238)
#37 0x00000000052ca888 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x52ca888)
#38 0x000000000525839d clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x525839d)
#39 0x000000000539f0ed clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x539f0ed)
#40 0x0000000000d8dbac cc1_main(llvm::ArrayRef, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xd8dbac)
#41 0x0000000000d848aa ExecuteCC1Tool(llvm::SmallVectorImpl&, llvm::ToolContext const&, llvm::IntrusiveRefCntPtr) driver.cpp:0:0
#42 0x0000000000d84a2d int llvm::function_ref&)>::callback_fn&)>(long, llvm::SmallVectorImpl&) driver.cpp:0:0
#43 0x0000000005012199 void llvm::function_ref::callback_fn>, std::__cxx11::basic_string, std::allocator>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#44 0x00000000043c75c4 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x43c75c4)
#45 0x0000000005012d05 clang::driver::CC1Command::Execute(llvm::ArrayRef>, std::__cxx11::basic_string, std::allocator>*, bool*) const (.part.0) Job.cpp:0:0
#46 0x0000000004fd08e2 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4fd08e2)
#47 0x0000000004fd5247 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4fd5247)
#48 0x0000000004fdf6d5 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4fdf6d5)
#49 0x0000000000d8a09a clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xd8a09a)
#50 0x0000000000cc7dfa main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xcc7dfa)
```

### Constant Evaluator Crash
Assertion:
```console
clang++: /root/llvm-project/llvm/tools/clang/lib/AST/ExprConstant.cpp:5728:
bool EvaluateDependentExpr(const clang::Expr*, {anonymous}::EvalInfo&):
Assertion `E->containsErrors() && "valid value-dependent expression should never " "reach invalid code path."' failed.
```

Stack trace:
```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++26
1. parser at end of file
#0 0x000000000448cc18 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x448cc18)
#1 0x0000000004489e74 llvm::sys::RunSignalHandlers() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4489e74)
#2 0x000000000448a4ac llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x448a4ac)
#3 0x00000000043c71c8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
#4 0x00007a0865445330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
#5 0x00007a086549ec0c pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x9ec0c)
#6 0x00007a086544527e raise (/lib/x86_64-linux-gnu/libc.so.6+0x4527e)
#7 0x00007a08654288ff abort (/lib/x86_64-linux-gnu/libc.so.6+0x288ff)
#8 0x00007a086542881b (/lib/x86_64-linux-gnu/libc.so.6+0x2881b)
#9 0x00007a086543b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)
#10 0x00000000081a7991 EvaluateDependentExpr(clang::Expr const*, (anonymous namespace)::EvalInfo&) ExprConstant.cpp:0:0
#11 0x000000000822ece6 EvaluateStmt((anonymous namespace)::StmtResult&, (anonymous namespace)::EvalInfo&, clang::Stmt const*, clang::SwitchCase const*) (.part.0) ExprConstant.cpp:0:0
#12 0x000000000822dd38 EvaluateStmt((anonymous namespace)::StmtResult&, (anonymous namespace)::EvalInfo&, clang::Stmt const*, clang::SwitchCase const*) (.part.0) ExprConstant.cpp:0:0
#13 0x000000000822dd38 EvaluateStmt((anonymous namespace)::StmtResult&, (anonymous namespace)::EvalInfo&, clang::Stmt const*, clang::SwitchCase const*) (.part.0) ExprConstant.cpp:0:0
#14 0x000000000822de11 EvaluateStmt((anonymous namespace)::StmtResult&, (anonymous namespace)::EvalInfo&, clang::Stmt const*, clang::SwitchCase const*) (.part.0) ExprConstant.cpp:0:0
#15 0x000000000822d234 EvaluateStmt((anonymous namespace)::StmtResult&, (anonymous namespace)::EvalInfo&, clang::Stmt const*, clang::SwitchCase const*) (.part.0) ExprConstant.cpp:0:0
#16 0x000000000822dd38 EvaluateStmt((anonymous namespace)::StmtResult&, (anonymous namespace)::EvalInfo&, clang::Stmt const*, clang::SwitchCase const*) (.part.0) ExprConstant.cpp:0:0
#17 0x000000000823578b HandleFunctionCall(clang::SourceLocation, clang::FunctionDecl const*, (anonymous namespace)::LValue const*, clang::Expr const*, llvm::ArrayRef, (anonymous namespace)::CallRef, clang::Stmt const*, (anonymous namespace)::EvalInfo&, clang::APValue&, (anonymous namespace)::LValue const*) ExprConstant.cpp:0:0
#18 0x0000000008264390 (anonymous namespace)::IntExprEvaluator::VisitCallExpr(clang::CallExpr const*) ExprConstant.cpp:0:0
#19 0x00000000081ffcb2 clang::StmtVisitorBase::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#20 0x00000000081e88df Evaluate(clang::APValue&, (anonymous namespace)::EvalInfo&, clang::Expr const*) ExprConstant.cpp:0:0
#21 0x00000000081e9692 EvaluateAsRValue((anonymous namespace)::EvalInfo&, clang::Expr const*, clang::APValue&) ExprConstant.cpp:0:0
#22 0x00000000081ede9a clang::Expr::isCXX11ConstantExpr(clang::ASTContext const&, clang::APValue*, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x81ede9a)
#23 0x00000000081f1d5c clang::Expr::getIntegerConstantExpr(clang::ASTContext const&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x81f1d5c)
#24 0x000000000709fed0 AnalyzeImplicitConversions(clang::Sema&, clang::Expr*, clang::SourceLocation, bool) (.constprop.0) SemaChecking.cpp:0:0
#25 0x00000000070a0d75 clang::Sema::CheckCompletedExpr(clang::Expr*, clang::SourceLocation, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x70a0d75)
#26 0x0000000007470e87 clang::Sema::ActOnFinishFullExpr(clang::Expr*, clang::SourceLocation, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7470e87)
#27 0x00000000072aa215 clang::Sema::BuildStaticAssertDeclaration(clang::SourceLocation, clang::Expr*, clang::Expr*, clang::SourceLocation, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x72aa215)
#28 0x0000000006e51da0 clang::Parser::ParseStaticAssertDeclaration(clang::SourceLocation&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6e51da0)
#29 0x0000000006e48fd6 clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6e48fd6)
#30 0x0000000006dff8b0 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6dff8b0)
#31 0x0000000006e007c5 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6e007c5)
#32 0x0000000006ddcb9a clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6ddcb9a)
#33 0x0000000004f9e238 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4f9e238)
#34 0x00000000052ca888 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x52ca888)
#35 0x000000000525839d clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x525839d)
#36 0x000000000539f0ed clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x539f0ed)
#37 0x0000000000d8dbac cc1_main(llvm::ArrayRef, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xd8dbac)
#38 0x0000000000d848aa ExecuteCC1Tool(llvm::SmallVectorImpl&, llvm::ToolContext const&, llvm::IntrusiveRefCntPtr) driver.cpp:0:0
#39 0x0000000000d84a2d int llvm::function_ref&)>::callback_fn&)>(long, llvm::SmallVectorImpl&) driver.cpp:0:0
#40 0x0000000005012199 void llvm::function_ref::callback_fn>, std::__cxx11::basic_string, std::allocator>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#41 0x00000000043c75c4 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x43c75c4)
#42 0x0000000005012d05 clang::driver::CC1Command::Execute(llvm::ArrayRef>, std::__cxx11::basic_string, std::allocator>*, bool*) const (.part.0) Job.cpp:0:0
#43 0x0000000004fd08e2 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4fd08e2)
#44 0x0000000004fd5247 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4fd5247)
#45 0x0000000004fdf6d5 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4fdf6d5)
#46 0x0000000000d8a09a clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xd8a09a)
#47 0x0000000000cc7dfa main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xcc7dfa)
```

Contributor guide

Open the contributing guide

Research direction

Start by compiling the structured-binding-pack reproducer with C++26 and inspect the CodeGen and constant-evaluation stack traces. Read CodeGenTypes.cpp, CGExprScalar.cpp, and ExprConstant.cpp around the reported assertions, then find the relevant Clang regression-test locations. Done means both CodeGen and constant evaluation handle the example without crashing.

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
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.