Skip to content

[clang] Crash from constexpr-evaluation of structured-binding variable #67690

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
hazohelet opened this issue Sep 28, 2023 · 8 comments · Fixed by #67778
Closed

[clang] Crash from constexpr-evaluation of structured-binding variable #67690

hazohelet opened this issue Sep 28, 2023 · 8 comments · Fixed by #67778
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party crash Prefer [crash-on-valid] or [crash-on-invalid]

Comments

@hazohelet
Copy link
Member

The use of &c at the end of the following code causes clang ICE.

using size_t = decltype(sizeof(0));

namespace std {
template <typename T> struct tuple_size;
template <size_t, typename> struct tuple_element;
} // namespace std

template <typename T> struct std::tuple_size<const T> : std::tuple_size<T> {};
template <size_t N, typename T> struct std::tuple_element<N, const T> {
  typedef const typename std::tuple_element<N, T>::type type;
};

struct C {
  template <int> int get() const;
};
template <> struct std::tuple_size<C> {
  static const int value = 1;
};
template <> struct std::tuple_element<0, C> {
  typedef int type;
};

template <const C *p> void f() {
  const auto &[c] = *p;
  &c;
}

Live demo: https://godbolt.org/z/918oE41Ke
Backtrace:

clang++: /root/llvm-project/clang/lib/AST/ExprConstant.cpp:3381: bool evaluateVarDeclInit({anonymous}::EvalInfo&, const clang::Expr*, const clang::VarDecl*, {anonymous}::CallStackFrame*, unsigned int, clang::APValue*&):
Assertion `!VD->mightBeUsableInConstantExpressions(Info.Ctx)' failed.
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++2b <source>
1.	<source>:25:5: current parser token ';'
2.	<source>:23:32: parsing function body 'f'
3.	<source>:23:32: 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 0x00007f76867d4420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007f768629700b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
 #5 0x00007f7686276859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
 #6 0x00007f7686276729 (/lib/x86_64-linux-gnu/libc.so.6+0x22729)
 #7 0x00007f7686287fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #8 0x0000000006f80225 (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6f80225)
 #9 0x0000000006fa9b66 (anonymous namespace)::LValueExprEvaluator::VisitVarDecl(clang::Expr const*, clang::VarDecl const*) ExprConstant.cpp:0:0
#10 0x0000000006fe7e9b (anonymous namespace)::LValueExprEvaluator::VisitDeclRefExpr(clang::DeclRefExpr const*) ExprConstant.cpp:0:0
#11 0x0000000006fc4837 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous namespace)::LValueExprEvaluator, bool>::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#12 0x0000000006fe7eb6 (anonymous namespace)::LValueExprEvaluator::VisitDeclRefExpr(clang::DeclRefExpr const*) ExprConstant.cpp:0:0
#13 0x0000000006fc4837 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous namespace)::LValueExprEvaluator, bool>::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#14 0x0000000006fc5d8d EvaluateLValue(clang::Expr const*, (anonymous namespace)::LValue&, (anonymous namespace)::EvalInfo&, bool) ExprConstant.cpp:0:0
#15 0x0000000006f9a14e Evaluate(clang::APValue&, (anonymous namespace)::EvalInfo&, clang::Expr const*) ExprConstant.cpp:0:0
#16 0x0000000006fb8e42 EvaluateInPlace(clang::APValue&, (anonymous namespace)::EvalInfo&, (anonymous namespace)::LValue const&, clang::Expr const*, bool) ExprConstant.cpp:0:0
#17 0x0000000006ff4208 clang::Expr::EvaluateAsConstantExpr(clang::Expr::EvalResult&, clang::ASTContext const&, clang::Expr::ConstantExprKind) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6ff4208)
#18 0x0000000006eaf122 clang::computeDependence(clang::UnaryOperator*, clang::ASTContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6eaf122)
#19 0x0000000006f623f3 clang::UnaryOperator::Create(clang::ASTContext const&, clang::Expr*, clang::UnaryOperatorKind, clang::QualType, clang::ExprValueKind, clang::ExprObjectKind, clang::SourceLocation, bool, clang::FPOptionsOverride) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6f623f3)
#20 0x00000000063ffa0f clang::Sema::CreateBuiltinUnaryOp(clang::SourceLocation, clang::UnaryOperatorKind, clang::Expr*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x63ffa0f)
#21 0x00000000064004ed clang::Sema::BuildUnaryOp(clang::Scope*, clang::SourceLocation, clang::UnaryOperatorKind, clang::Expr*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x64004ed)
#22 0x0000000005ed5bf9 clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ed5bf9)
#23 0x0000000005ed7d8a clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ed7d8a)
#24 0x0000000005ed7f29 clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ed7f29)
#25 0x0000000005edcc29 clang::Parser::ParseExpression(clang::Parser::TypeCastState) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5edcc29)
#26 0x0000000005f57dc7 clang::Parser::ParseExprStatement(clang::Parser::ParsedStmtContext) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f57dc7)
#27 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)
#28 0x0000000005f4f278 clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f4f278)
#29 0x0000000005f501b9 clang::Parser::ParseCompoundStatementBody(bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f501b9)
#30 0x0000000005f51ada clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f51ada)
#31 0x0000000005e7f1c1 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e7f1c1)
#32 0x0000000005f6b520 clang::Parser::ParseSingleDeclarationAfterTemplate(clang::DeclaratorContext, clang::Parser::ParsedTemplateInfo const&, clang::ParsingDeclRAIIObject&, clang::SourceLocation&, clang::ParsedAttributes&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f6b520)
#33 0x0000000005f70a18 clang::Parser::ParseTemplateDeclarationOrSpecialization(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::AccessSpecifier) (.part.0) ParseTemplate.cpp:0:0
#34 0x0000000005f70cd3 clang::Parser::ParseDeclarationStartingWithTemplate(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f70cd3)
#35 0x0000000005eaea0b clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5eaea0b)
#36 0x0000000005e79814 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e79814)
#37 0x0000000005e7a71d clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e7a71d)
#38 0x0000000005e6ea5a clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e6ea5a)
#39 0x00000000049724d8 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x49724d8)
#40 0x00000000041d6509 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x41d6509)
#41 0x00000000041571ee clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x41571ee)
#42 0x00000000042b584e clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x42b584e)
#43 0x0000000000bdcb46 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbdcb46)
#44 0x0000000000bd440a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#45 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
#46 0x000000000364fd84 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x364fd84)
#47 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
#48 0x0000000003f7d3a5 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f7d3a5)
#49 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)
#50 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)
#51 0x0000000000bd9fec clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbd9fec)
#52 0x0000000000ad4d61 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xad4d61)
#53 0x00007f7686278083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#54 0x0000000000bd3eee _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbd3eee)
@hazohelet hazohelet added clang:frontend Language frontend issues, e.g. anything involving "Sema" crash Prefer [crash-on-valid] or [crash-on-invalid] labels Sep 28, 2023
@llvmbot
Copy link
Member

llvmbot commented Sep 28, 2023

@llvm/issue-subscribers-clang-frontend

The use of `&c` at the end of the following code causes clang ICE.
using size_t = decltype(sizeof(0));

namespace std {
template &lt;typename T&gt; struct tuple_size;
template &lt;size_t, typename&gt; struct tuple_element;
} // namespace std

template &lt;typename T&gt; struct std::tuple_size&lt;const T&gt; : std::tuple_size&lt;T&gt; {};
template &lt;size_t N, typename T&gt; struct std::tuple_element&lt;N, const T&gt; {
  typedef const typename std::tuple_element&lt;N, T&gt;::type type;
};

struct C {
  template &lt;int&gt; int get() const;
};
template &lt;&gt; struct std::tuple_size&lt;C&gt; {
  static const int value = 1;
};
template &lt;&gt; struct std::tuple_element&lt;0, C&gt; {
  typedef int type;
};

template &lt;const C *p&gt; void f() {
  const auto &amp;[c] = *p;
  &amp;c;
}

Live demo: https://godbolt.org/z/918oE41Ke
Backtrace:

clang++: /root/llvm-project/clang/lib/AST/ExprConstant.cpp:3381: bool evaluateVarDeclInit({anonymous}::EvalInfo&amp;, const clang::Expr*, const clang::VarDecl*, {anonymous}::CallStackFrame*, unsigned int, clang::APValue*&amp;):
Assertion `!VD-&gt;mightBeUsableInConstantExpressions(Info.Ctx)' failed.
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++2b &lt;source&gt;
1.	&lt;source&gt;:25:5: current parser token ';'
2.	&lt;source&gt;:23:32: parsing function body 'f'
3.	&lt;source&gt;:23:32: in compound statement ('{}')
 #<!-- -->0 0x0000000003708fb8 llvm::sys::PrintStackTrace(llvm::raw_ostream&amp;, 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 0x00007f76867d4420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #<!-- -->4 0x00007f768629700b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
 #<!-- -->5 0x00007f7686276859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
 #<!-- -->6 0x00007f7686276729 (/lib/x86_64-linux-gnu/libc.so.6+0x22729)
 #<!-- -->7 0x00007f7686287fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #<!-- -->8 0x0000000006f80225 (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6f80225)
 #<!-- -->9 0x0000000006fa9b66 (anonymous namespace)::LValueExprEvaluator::VisitVarDecl(clang::Expr const*, clang::VarDecl const*) ExprConstant.cpp:0:0
#<!-- -->10 0x0000000006fe7e9b (anonymous namespace)::LValueExprEvaluator::VisitDeclRefExpr(clang::DeclRefExpr const*) ExprConstant.cpp:0:0
#<!-- -->11 0x0000000006fc4837 clang::StmtVisitorBase&lt;llvm::make_const_ptr, (anonymous namespace)::LValueExprEvaluator, bool&gt;::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#<!-- -->12 0x0000000006fe7eb6 (anonymous namespace)::LValueExprEvaluator::VisitDeclRefExpr(clang::DeclRefExpr const*) ExprConstant.cpp:0:0
#<!-- -->13 0x0000000006fc4837 clang::StmtVisitorBase&lt;llvm::make_const_ptr, (anonymous namespace)::LValueExprEvaluator, bool&gt;::Visit(clang::Stmt const*) ExprConstant.cpp:0:0
#<!-- -->14 0x0000000006fc5d8d EvaluateLValue(clang::Expr const*, (anonymous namespace)::LValue&amp;, (anonymous namespace)::EvalInfo&amp;, bool) ExprConstant.cpp:0:0
#<!-- -->15 0x0000000006f9a14e Evaluate(clang::APValue&amp;, (anonymous namespace)::EvalInfo&amp;, clang::Expr const*) ExprConstant.cpp:0:0
#<!-- -->16 0x0000000006fb8e42 EvaluateInPlace(clang::APValue&amp;, (anonymous namespace)::EvalInfo&amp;, (anonymous namespace)::LValue const&amp;, clang::Expr const*, bool) ExprConstant.cpp:0:0
#<!-- -->17 0x0000000006ff4208 clang::Expr::EvaluateAsConstantExpr(clang::Expr::EvalResult&amp;, clang::ASTContext const&amp;, clang::Expr::ConstantExprKind) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6ff4208)
#<!-- -->18 0x0000000006eaf122 clang::computeDependence(clang::UnaryOperator*, clang::ASTContext const&amp;) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6eaf122)
#<!-- -->19 0x0000000006f623f3 clang::UnaryOperator::Create(clang::ASTContext const&amp;, clang::Expr*, clang::UnaryOperatorKind, clang::QualType, clang::ExprValueKind, clang::ExprObjectKind, clang::SourceLocation, bool, clang::FPOptionsOverride) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6f623f3)
#<!-- -->20 0x00000000063ffa0f clang::Sema::CreateBuiltinUnaryOp(clang::SourceLocation, clang::UnaryOperatorKind, clang::Expr*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x63ffa0f)
#<!-- -->21 0x00000000064004ed clang::Sema::BuildUnaryOp(clang::Scope*, clang::SourceLocation, clang::UnaryOperatorKind, clang::Expr*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x64004ed)
#<!-- -->22 0x0000000005ed5bf9 clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&amp;, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ed5bf9)
#<!-- -->23 0x0000000005ed7d8a clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ed7d8a)
#<!-- -->24 0x0000000005ed7f29 clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ed7f29)
#<!-- -->25 0x0000000005edcc29 clang::Parser::ParseExpression(clang::Parser::TypeCastState) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5edcc29)
#<!-- -->26 0x0000000005f57dc7 clang::Parser::ParseExprStatement(clang::Parser::ParsedStmtContext) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f57dc7)
#<!-- -->27 0x0000000005f4e43d clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector&lt;clang::Stmt*, 32u&gt;&amp;, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::ParsedAttributes&amp;, clang::ParsedAttributes&amp;) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f4e43d)
#<!-- -->28 0x0000000005f4f278 clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector&lt;clang::Stmt*, 32u&gt;&amp;, clang::Parser::ParsedStmtContext, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f4f278)
#<!-- -->29 0x0000000005f501b9 clang::Parser::ParseCompoundStatementBody(bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f501b9)
#<!-- -->30 0x0000000005f51ada clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&amp;) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f51ada)
#<!-- -->31 0x0000000005e7f1c1 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&amp;, clang::Parser::ParsedTemplateInfo const&amp;, clang::Parser::LateParsedAttrList*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e7f1c1)
#<!-- -->32 0x0000000005f6b520 clang::Parser::ParseSingleDeclarationAfterTemplate(clang::DeclaratorContext, clang::Parser::ParsedTemplateInfo const&amp;, clang::ParsingDeclRAIIObject&amp;, clang::SourceLocation&amp;, clang::ParsedAttributes&amp;, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f6b520)
#<!-- -->33 0x0000000005f70a18 clang::Parser::ParseTemplateDeclarationOrSpecialization(clang::DeclaratorContext, clang::SourceLocation&amp;, clang::ParsedAttributes&amp;, clang::AccessSpecifier) (.part.0) ParseTemplate.cpp:0:0
#<!-- -->34 0x0000000005f70cd3 clang::Parser::ParseDeclarationStartingWithTemplate(clang::DeclaratorContext, clang::SourceLocation&amp;, clang::ParsedAttributes&amp;, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f70cd3)
#<!-- -->35 0x0000000005eaea0b clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&amp;, clang::ParsedAttributes&amp;, clang::ParsedAttributes&amp;, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5eaea0b)
#<!-- -->36 0x0000000005e79814 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&amp;, clang::ParsedAttributes&amp;, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e79814)
#<!-- -->37 0x0000000005e7a71d clang::Parser::ParseTopLevelDecl(clang::OpaquePtr&lt;clang::DeclGroupRef&gt;&amp;, clang::Sema::ModuleImportState&amp;) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e7a71d)
#<!-- -->38 0x0000000005e6ea5a clang::ParseAST(clang::Sema&amp;, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e6ea5a)
#<!-- -->39 0x00000000049724d8 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x49724d8)
#<!-- -->40 0x00000000041d6509 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x41d6509)
#<!-- -->41 0x00000000041571ee clang::CompilerInstance::ExecuteAction(clang::FrontendAction&amp;) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x41571ee)
#<!-- -->42 0x00000000042b584e clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x42b584e)
#<!-- -->43 0x0000000000bdcb46 cc1_main(llvm::ArrayRef&lt;char const*&gt;, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbdcb46)
#<!-- -->44 0x0000000000bd440a ExecuteCC1Tool(llvm::SmallVectorImpl&lt;char const*&gt;&amp;, llvm::ToolContext const&amp;) driver.cpp:0:0
#<!-- -->45 0x0000000003fb4a69 void llvm::function_ref&lt;void ()&gt;::callback_fn&lt;clang::driver::CC1Command::Execute(llvm::ArrayRef&lt;std::optional&lt;llvm::StringRef&gt;&gt;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt;&gt;*, bool*) const::'lambda'()&gt;(long) Job.cpp:0:0
#<!-- -->46 0x000000000364fd84 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref&lt;void ()&gt;) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x364fd84)
#<!-- -->47 0x0000000003fb505f clang::driver::CC1Command::Execute(llvm::ArrayRef&lt;std::optional&lt;llvm::StringRef&gt;&gt;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt;&gt;*, bool*) const (.part.0) Job.cpp:0:0
#<!-- -->48 0x0000000003f7d3a5 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&amp;, clang::driver::Command const*&amp;, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f7d3a5)
#<!-- -->49 0x0000000003f7de0d clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&amp;, llvm::SmallVectorImpl&lt;std::pair&lt;int, clang::driver::Command const*&gt;&gt;&amp;, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f7de0d)
#<!-- -->50 0x0000000003f85d35 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&amp;, llvm::SmallVectorImpl&lt;std::pair&lt;int, clang::driver::Command const*&gt;&gt;&amp;) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f85d35)
#<!-- -->51 0x0000000000bd9fec clang_main(int, char**, llvm::ToolContext const&amp;) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbd9fec)
#<!-- -->52 0x0000000000ad4d61 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xad4d61)
#<!-- -->53 0x00007f7686278083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#<!-- -->54 0x0000000000bd3eee _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbd3eee)

@shafik
Copy link
Collaborator

shafik commented Sep 28, 2023

Looks like it started in clang12: https://godbolt.org/z/n9z9P1fca

Looks related to but not identical to: #53598

@shafik shafik added the confirmed Verified by a second party label Sep 28, 2023
@shafik
Copy link
Collaborator

shafik commented Sep 28, 2023

I reduced it to this: https://godbolt.org/z/3c5rzxorT

struct C {
  int x;
};

template <const C *p> void f() {
  const auto &[c] = *p;
  &c;
}

and then the backtrace looks like: #53598

so I think these are probably the same problem but different ways of hitting it but not 💯

@tbaederr
Copy link
Contributor

if (Init->isValueDependent()) {
// The DeclRefExpr is not value-dependent, but the variable it refers to
// has a value-dependent initializer. This should only happen in
// constant-folding cases, where the variable is not actually of a suitable
// type for use in a constant expression (otherwise the DeclRefExpr would
// have been value-dependent too), so diagnose that.
assert(!VD->mightBeUsableInConstantExpressions(Info.Ctx));
if (!Info.checkingPotentialConstantExpression()) {
Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
? diag::note_constexpr_ltor_non_constexpr
: diag::note_constexpr_ltor_non_integral, 1)
<< VD << VD->getType();
NoteLValueLocation(Info, Base);
}
return false;
}

The comment here says "The DeclRefExpr is not value-dependent" - but it is:

(lldb) p Init->isValueDependent()
(bool) $0 = true
(lldb) p E->isValueDependent()
(bool) $1 = true
(lldb)

@tbaederr
Copy link
Contributor

So, this fixes the reproducer:

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 04a751f1b4d0..a3a9ccdab523 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3306,6 +3306,8 @@ static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E,
 static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
                                 const VarDecl *VD, CallStackFrame *Frame,
                                 unsigned Version, APValue *&Result) {
+  if (E->isValueDependent())
+    return false;
   APValue::LValueBase Base(VD, Frame ? Frame->Index : 0, Version);

   // If this is a local variable, dig out its value.

@shafik
Copy link
Collaborator

shafik commented Sep 29, 2023

How do we end up in HandleLValueComplexElement(...)?

@tbaederr
Copy link
Contributor

we aren't, this is in evaluateVarDeclInit

@cor3ntin
Copy link
Contributor

@tbaederr are you going to submit a patch?

tbaederr added a commit to tbaederr/llvm-project that referenced this issue Oct 5, 2023
The Expression here migth be value dependent, which makes us run into an
assertion later on. Just bail out early.

Fixes llvm#67690
tbaederr added a commit that referenced this issue Oct 5, 2023
…#67778)

The Expression here migth be value dependent, which makes us run into an
assertion later on. Just bail out early.

Fixes #67690
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party crash Prefer [crash-on-valid] or [crash-on-invalid]
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants