llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
26.64k stars 10.91k forks source link

Assertion `!isValueDependent() && "Expression evaluator can't be called on a dependent expression."` #91566

Open Endilll opened 1 month ago

Endilll commented 1 month ago

@sam-mccall shared a crash reproducer in https://github.com/llvm/llvm-project/pull/89807#issuecomment-2100771884, but it was found to be not related to the PR. This is a separate filing for the crash he shared. Partial reduction made by C-Reduce (formatted): https://godbolt.org/z/MPnj9eoGP

llvmbot commented 1 month ago

@llvm/issue-subscribers-clang-frontend

Author: Vlad Serebrennikov (Endilll)

@sam-mccall shared a crash reproducer in https://github.com/llvm/llvm-project/pull/89807#issuecomment-2100771884, but it was found to be not related to the PR. This is a separate filing for the crash he shared. Partial reduction made by C-Reduce (formatted): https://godbolt.org/z/MPnj9eoGP
llvmbot commented 1 month ago

@llvm/issue-subscribers-c-20

Author: Vlad Serebrennikov (Endilll)

@sam-mccall shared a crash reproducer in https://github.com/llvm/llvm-project/pull/89807#issuecomment-2100771884, but it was found to be not related to the PR. This is a separate filing for the crash he shared. Partial reduction made by C-Reduce (formatted): https://godbolt.org/z/MPnj9eoGP
Endilll commented 1 month ago

Confirmed on Clang 19.0: https://godbolt.org/z/rb71sszh6 Reduced by me:

template <typename>
struct make_sexpr;

template <class Fun>
concept callable = requires(Fun fun) {
  fun();
};

template <typename>
concept Ok = true;

template <bool>
struct i;

template <typename, typename>
void for_all_sigs_();

template <typename T>
using for_all_sigs = i<Ok<decltype(for_all_sigs_<T>())>>;

struct foo {
  make_sexpr<for_all_sigs<int>> operator()();
};

bool b = requires { callable<foo>; };

Clang 19.0 crash:

<source>:19:36: error: no matching function for call to 'for_all_sigs_'
   19 | using for_all_sigs = i<Ok<decltype(for_all_sigs_<T>())>>;
      |                                    ^~~~~~~~~~~~~~~~
<source>:22:14: note: in instantiation of template type alias 'for_all_sigs' requested here
   22 |   make_sexpr<for_all_sigs<int>> operator()();
      |              ^
<source>:16:6: note: candidate template ignored: couldn't infer template argument ''
   16 | void for_all_sigs_();
      |      ^
clang++: /root/llvm-project/clang/lib/AST/ExprConstant.cpp:15952: bool clang::Expr::EvaluateAsConstantExpr(clang::Expr::EvalResult&, const clang::ASTContext&, clang::Expr::ConstantExprKind) const: Assertion `!isValueDependent() && "Expression evaluator can't be called on a dependent expression."' 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++20 -ferror-limit=0 <source>
1.  <source>:25:34: current parser token ';'
 #0 0x0000000003980898 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3980898)
 #1 0x000000000397e57c llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x397e57c)
 #2 0x00000000038cf5e8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x000072ac7b042520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x000072ac7b0969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #5 0x000072ac7b042476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #6 0x000072ac7b0287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #7 0x000072ac7b02871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
 #8 0x000072ac7b039e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
 #9 0x00000000075b92e8 clang::Expr::EvaluateAsConstantExpr(clang::Expr::EvalResult&, clang::ASTContext const&, clang::Expr::ConstantExprKind) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x75b92e8)
#10 0x000000000656881d clang::ActionResult<clang::Expr*, true> calculateConstraintSatisfaction<calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, clang::SourceLocation, clang::MultiLevelTemplateArgumentList const&, clang::Expr const*, clang::ConstraintSatisfaction&)::'lambda'(clang::Expr const*)>(clang::Sema&, clang::Expr const*, clang::ConstraintSatisfaction&, calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, clang::SourceLocation, clang::MultiLevelTemplateArgumentList const&, clang::Expr const*, clang::ConstraintSatisfaction&)::'lambda'(clang::Expr const*)&&) SemaConcept.cpp:0:0
#11 0x0000000006568e12 CheckConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, llvm::ArrayRef<clang::Expr const*>, llvm::SmallVectorImpl<clang::Expr*>&, clang::MultiLevelTemplateArgumentList const&, clang::SourceRange, clang::ConstraintSatisfaction&) SemaConcept.cpp:0:0
#12 0x000000000656944a clang::Sema::CheckConstraintSatisfaction(clang::NamedDecl const*, llvm::ArrayRef<clang::Expr const*>, llvm::SmallVectorImpl<clang::Expr*>&, clang::MultiLevelTemplateArgumentList const&, clang::SourceRange, clang::ConstraintSatisfaction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x656944a)
#13 0x0000000006cee719 clang::Sema::CheckConceptTemplateId(clang::CXXScopeSpec const&, clang::SourceLocation, clang::DeclarationNameInfo const&, clang::NamedDecl*, clang::ConceptDecl*, clang::TemplateArgumentListInfo const*) (.constprop.0) SemaTemplate.cpp:0:0
#14 0x0000000006cf0698 clang::Sema::BuildTemplateIdExpr(clang::CXXScopeSpec const&, clang::SourceLocation, clang::LookupResult&, bool, clang::TemplateArgumentListInfo const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6cf0698)
#15 0x000000000685e320 clang::Sema::ActOnIdExpression(clang::Scope*, clang::CXXScopeSpec&, clang::SourceLocation, clang::UnqualifiedId&, bool, bool, clang::CorrectionCandidateCallback*, bool, clang::Token*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x685e320)
#16 0x00000000063283d6 clang::Parser::tryParseCXXIdExpression(clang::CXXScopeSpec&, bool, clang::Token&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x63283d6)
#17 0x00000000063286f4 clang::Parser::ParseCXXIdExpression(bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x63286f4)
#18 0x000000000630a121 clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x630a121)
#19 0x0000000006309a7a clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6309a7a)
#20 0x000000000630caba clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x630caba)
#21 0x000000000630cc59 clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x630cc59)
#22 0x00000000063115c9 clang::Parser::ParseExpression(clang::Parser::TypeCastState) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x63115c9)
#23 0x000000000631cb60 clang::Parser::ParseRequiresExpression() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x631cb60)
#24 0x000000000630a13a clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x630a13a)
#25 0x000000000630caba clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x630caba)
#26 0x000000000630cc59 clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x630cc59)
#27 0x00000000062c90f7 clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::ForRangeInit*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x62c90f7)
#28 0x00000000062d7fda clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::Parser::ParsedTemplateInfo&, clang::SourceLocation*, clang::Parser::ForRangeInit*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x62d7fda)
#29 0x0000000006295d6e clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6295d6e)
#30 0x0000000006296563 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6296563)
#31 0x000000000629cb67 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x629cb67)
#32 0x000000000629da1f clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x629da1f)
#33 0x00000000062914da clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x62914da)
#34 0x000000000424ce68 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x424ce68)
#35 0x00000000044cf509 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x44cf509)
#36 0x0000000004456cbe clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4456cbe)
#37 0x00000000045b606e clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x45b606e)
#38 0x0000000000c511ac cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xc511ac)
#39 0x0000000000c4a50a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#40 0x0000000004290039 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
#41 0x00000000038cfa94 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x38cfa94)
#42 0x000000000429062f 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
#43 0x0000000004256725 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4256725)
#44 0x000000000425718d 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+++0x425718d)
#45 0x000000000425ee85 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x425ee85)
#46 0x0000000000c4e6b5 clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xc4e6b5)
#47 0x0000000000b301f4 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xb301f4)
#48 0x000072ac7b029d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#49 0x000072ac7b029e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#50 0x0000000000c49fbe _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xc49fbe)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
Compiler returned: 134
Endilll commented 1 month ago

CC @erichkeane

cor3ntin commented 1 month ago

@mizvekov

mizvekov commented 1 month ago

I have reduced other crashes stemming from bad error recovery producing dependent types / values. I suspect this example will be something similar to these:

https://github.com/llvm/llvm-project/issues/91564 https://github.com/llvm/llvm-project/issues/91696

The 'concepts' are unrelated here: the constraint provides an easy place we can assert value dependence is not expected, since they are supposed to be evaluated only when their context is fully instantiated. In most other places, that can't so easily be determined, and so we just skip further analysis.