llvm-project
llvm-project copied to clipboard
[clang] Assertion failure in case of nested `ArrayInitLoopExpr` using `-std=c++17`
The following snippet causes an assertion failure when compiled with -std=c++17
:
struct S {
int i;
};
void crash() {
S s[2][2];
int res[4];
res[0] = [s] { return s[0][0].i; }(); <-- crash here
}
The failure is caused by the nested ArrayInitLoopExpr
. The related part of the AST looks like this:
|-ArrayInitLoopExpr 'S[2][2]'
| |-OpaqueValueExpr 'S[2][2]' lvalue
| | `-DeclRefExpr'S[2][2]' lvalue Var 's' 'S[2][2]'
| `-ArrayInitLoopExpr 'S[2]' <-- note this
| |-OpaqueValueExpr 'S[2]' lvalue
| | `-ArraySubscriptExpr 'S[2]' lvalue
| | |-ImplicitCastExpr 'S (*)[2]' <ArrayToPointerDecay>
| | | `-OpaqueValueExpr 'S[2][2]' lvalue
| | | `-DeclRefExpr 'S[2][2]' lvalue Var 's' 'S[2][2]'
| | `-ArrayInitIndexExpr 'unsigned long'
| `-CXXConstructExpr 'S' 'void (const S &) noexcept'
In ArrayExprEvaluator::VisitArrayInitLoopExpr()
we loop over the elements of the init loop and
try to evaluate each of them.
1.) We visit the first init loop with type S[2][2]
.
2.) We visit the nested one for the first time, which has the type S[2]
.
3.) We visit the nested one for the second time, which has the type S[2]
.
4.) assert(Result.isAbsent() && "local created multiple times");
fails in CallStackFrame::createLocal()
.
For the stack trace please see godbolt.
@llvm/issue-subscribers-clang-frontend
@llvm/issue-subscribers-c-17
Might be related to https://github.com/llvm/llvm-project/issues/55163
The problem seems to only occur with assertions enabled.
https://godbolt.org/z/5bdbsvGxx
Confirmed
Assertion:
clang++: /root/llvm-project/clang/lib/AST/ExprConstant.cpp:1915:
clang::APValue& {anonymous}::CallStackFrame::createLocal(clang::APValue::LValueBase, const void*, clang::QualType, {anonymous}::ScopeKind):
Assertion `Result.isAbsent() && "local created multiple times"' failed.
Backtrace:
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-trunk/bin/clang++ -gdwarf-4 -g -o /app/output.s -mllvm --x86-asm-syntax=intel -S --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot -fcolor-diagnostics -fno-crash-diagnostics -std=c++17 <source>
1. <source>:11:1: current parser token '}'
2. <source>:5:14: parsing function body 'crash'
3. <source>:5:14: in compound statement ('{}')
#0 0x0000000003708fb8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3708fb8)
#1 0x0000000003706c7c llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3706c7c)
#2 0x000000000364f8d8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
#3 0x00007f3760fa7420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
#4 0x00007f3760a6a00b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
#5 0x00007f3760a49859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
#6 0x00007f3760a49729 (/lib/x86_64-linux-gnu/libc.so.6+0x22729)
#7 0x00007f3760a5afd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
#8 0x0000000006f8b1e2 (anonymous namespace)::CallStackFrame::createLocal(clang::APValue::LValueBase, void const*, clang::QualType, (anonymous namespace)::ScopeKind) ExprConstant.cpp:0:0
#9 0x0000000006f8b3b9 clang::APValue& (anonymous namespace)::CallStackFrame::createTemporary<clang::OpaqueValueExpr>(clang::OpaqueValueExpr const*, clang::QualType, (anonymous namespace)::ScopeKind, (anonymous namespace)::LValue&) (.constprop.0) ExprConstant.cpp:0:0
#10 0x0000000006fbcdb4 (anonymous namespace)::ArrayExprEvaluator::VisitArrayInitLoopExpr(clang::ArrayInitLoopExpr const*) ExprConstant.cpp:0:0
#11 0x0000000006feaed4 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous namespace)::ArrayExprEvaluator, bool>::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#12 0x0000000006fec4dd EvaluateArray(clang::Expr const*, (anonymous namespace)::LValue const&, clang::APValue&, (anonymous namespace)::EvalInfo&) ExprConstant.cpp:0:0
#13 0x0000000006fb8df5 EvaluateInPlace(clang::APValue&, (anonymous namespace)::EvalInfo&, (anonymous namespace)::LValue const&, clang::Expr const*, bool) ExprConstant.cpp:0:0
#14 0x0000000006fbd062 (anonymous namespace)::ArrayExprEvaluator::VisitArrayInitLoopExpr(clang::ArrayInitLoopExpr const*) ExprConstant.cpp:0:0
#15 0x0000000006feaed4 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous namespace)::ArrayExprEvaluator, bool>::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#16 0x0000000006fec4dd EvaluateArray(clang::Expr const*, (anonymous namespace)::LValue const&, clang::APValue&, (anonymous namespace)::EvalInfo&) ExprConstant.cpp:0:0
#17 0x0000000006fb8df5 EvaluateInPlace(clang::APValue&, (anonymous namespace)::EvalInfo&, (anonymous namespace)::LValue const&, clang::Expr const*, bool) ExprConstant.cpp:0:0
#18 0x0000000006fef04e clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous namespace)::RecordExprEvaluator, bool>::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#19 0x0000000006fefbb8 EvaluateRecord(clang::Expr const*, (anonymous namespace)::LValue const&, clang::APValue&, (anonymous namespace)::EvalInfo&) ExprConstant.cpp:0:0
#20 0x0000000006fb8e1d EvaluateInPlace(clang::APValue&, (anonymous namespace)::EvalInfo&, (anonymous namespace)::LValue const&, clang::Expr const*, bool) ExprConstant.cpp:0:0
#21 0x0000000006fc37ff (anonymous namespace)::LValueExprEvaluator::VisitMaterializeTemporaryExpr(clang::MaterializeTemporaryExpr const*) (.isra.0) ExprConstant.cpp:0:0
#22 0x0000000006fc459e clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous namespace)::LValueExprEvaluator, bool>::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#23 0x0000000006fe77cb (anonymous namespace)::ExprEvaluatorBase<(anonymous namespace)::LValueExprEvaluator>::VisitCastExpr(clang::CastExpr const*) ExprConstant.cpp:0:0
#24 0x0000000006fc4914 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous namespace)::LValueExprEvaluator, bool>::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#25 0x0000000006fc5d8d EvaluateLValue(clang::Expr const*, (anonymous namespace)::LValue&, (anonymous namespace)::EvalInfo&, bool) ExprConstant.cpp:0:0
#26 0x0000000007002712 (anonymous namespace)::IntExprEvaluator::VisitCallExpr(clang::CallExpr const*) ExprConstant.cpp:0:0
#27 0x0000000006fab7f6 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous namespace)::IntExprEvaluator, bool>::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#28 0x0000000006f9a57e Evaluate(clang::APValue&, (anonymous namespace)::EvalInfo&, clang::Expr const*) ExprConstant.cpp:0:0
#29 0x0000000006fc4d83 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous namespace)::LValueExprEvaluator, bool>::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#30 0x0000000006fc5d8d EvaluateLValue(clang::Expr const*, (anonymous namespace)::LValue&, (anonymous namespace)::EvalInfo&, bool) ExprConstant.cpp:0:0
#31 0x0000000006f9a14e Evaluate(clang::APValue&, (anonymous namespace)::EvalInfo&, clang::Expr const*) ExprConstant.cpp:0:0
#32 0x0000000006fa4809 EvaluateAsRValue((anonymous namespace)::EvalInfo&, clang::Expr const*, clang::APValue&) ExprConstant.cpp:0:0
#33 0x0000000006fa545f clang::Expr::EvaluateForOverflow(clang::ASTContext const&) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6fa545f)
#34 0x0000000006030465 clang::Sema::CheckForIntOverflow(clang::Expr const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6030465)
#35 0x000000000608faf4 clang::Sema::CheckCompletedExpr(clang::Expr*, clang::SourceLocation, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x608faf4)
#36 0x00000000065153c4 clang::Sema::ActOnFinishFullExpr(clang::Expr*, clang::SourceLocation, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x65153c4)
#37 0x000000000678d45e clang::Sema::ActOnExprStmt(clang::ActionResult<clang::Expr*, true>, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x678d45e)
#38 0x0000000005f57e54 clang::Parser::ParseExprStatement(clang::Parser::ParsedStmtContext) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f57e54)
#39 0x0000000005f4e43d clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::ParsedAttributes&, clang::ParsedAttributes&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f4e43d)
#40 0x0000000005f4f278 clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f4f278)
#41 0x0000000005f501b9 clang::Parser::ParseCompoundStatementBody(bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f501b9)
#42 0x0000000005f51ada clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f51ada)
#43 0x0000000005e7f1c1 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e7f1c1)
#44 0x0000000005ea67a8 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::SourceLocation*, clang::Parser::ForRangeInit*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ea67a8)
#45 0x0000000005e730ab clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e730ab)
#46 0x0000000005e737df clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (.part.0) Parser.cpp:0:0
#47 0x0000000005e79ef4 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e79ef4)
#48 0x0000000005e7a71d clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e7a71d)
#49 0x0000000005e6ea5a clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e6ea5a)
#50 0x00000000049724d8 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x49724d8)
#51 0x00000000041d6509 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x41d6509)
#52 0x00000000041571ee clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x41571ee)
#53 0x00000000042b584e clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x42b584e)
#54 0x0000000000bdcb46 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbdcb46)
#55 0x0000000000bd440a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#56 0x0000000003fb4a69 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#57 0x000000000364fd84 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x364fd84)
#58 0x0000000003fb505f clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (.part.0) Job.cpp:0:0
#59 0x0000000003f7d3a5 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f7d3a5)
#60 0x0000000003f7de0d clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f7de0d)
#61 0x0000000003f85d35 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f85d35)
#62 0x0000000000bd9fec clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbd9fec)
#63 0x0000000000ad4d61 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xad4d61)
#64 0x00007f3760a4b083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#65 0x0000000000bd3eee _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbd3eee)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
Compiler returned: 134
CC @tbaederr who might have some ideas here