Skip to content
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

Clang crashes with requires expression in lambda in concept constraints #64607

Closed
namniav opened this issue Aug 11, 2023 · 4 comments · Fixed by #76967
Closed

Clang crashes with requires expression in lambda in concept constraints #64607

namniav opened this issue Aug 11, 2023 · 4 comments · Fixed by #76967
Assignees
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts confirmed Verified by a second party crash Prefer [crash-on-valid] or [crash-on-invalid]

Comments

@namniav
Copy link

namniav commented Aug 11, 2023

https://godbolt.org/z/Kvr6afWd4

template<typename T> concept doesnt_matter = true;

template<class T>
concept test = 
    []{
        return requires(T t) {
            { t } -> doesnt_matter;
        };
    }();

static_assert(test<int>);

It is reduced from https://godbolt.org/z/5K6janbx5

#include <concepts>
#include <type_traits>
#include <utility>
#include <tuple>

template<class T>
concept tuple_like = 
    [] <std::size_t...I> (std::index_sequence<I...>) {
        return ((requires(T t) {
                    { std::get<I>(t) } -> std::convertible_to<std::tuple_element_t<I, T>&>;
                }) && ...);
    } (std::make_index_sequence<std::tuple_size_v<T>>{});

static_assert(tuple_like<std::tuple<int>>);

Both were accepted by Clang 15 and earlier. Clang 16 and current trunk on CompilerExplorer crashes on them(with either libc++ or libstdc++), but accepts the second if std::tuple_element_t<I, T>& is replaced with int&.

GCC also has this issue on the second example only: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105644.

MSVC accepts them.

@EugeneZelenko EugeneZelenko added c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts crash Prefer [crash-on-valid] or [crash-on-invalid] and removed new issue labels Aug 11, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Aug 11, 2023

@llvm/issue-subscribers-c-20

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 11, 2023

@llvm/issue-subscribers-clang-frontend

@shafik
Copy link
Collaborator

shafik commented Aug 11, 2023

Confirmed, using assertions build is usually preferred since any assertions hit usually points better to the underlying issue.

Assertion:

clang++: /root/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp:2224:
clang::QualType {anonymous}::TemplateInstantiator::TransformTemplateTypeParmType(clang::TypeLocBuilder&, clang::TemplateTypeParmTypeLoc, bool):
Assertion `Arg.getKind() == TemplateArgument::Type && "Template argument kind mismatch"' 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++20 -Wall <source>
1.	<source>:14:42: current parser token ')'
2.	<source>:8:5: instantiating function definition '(anonymous class)::operator()<0UL>'
 #0 0x000000000367eca8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x367eca8)
 #1 0x000000000367cb2c llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x367cb2c)
 #2 0x00000000035c8568 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007fe2d3ece420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007fe2d399100b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
 #5 0x00007fe2d3970859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
 #6 0x00007fe2d3970729 (/lib/x86_64-linux-gnu/libc.so.6+0x22729)
 #7 0x00007fe2d3981fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #8 0x0000000006893cd3 (anonymous namespace)::TemplateInstantiator::TransformTemplateTypeParmType(clang::TypeLocBuilder&, clang::TemplateTypeParmTypeLoc, bool) SemaTemplateInstantiate.cpp:0:0
 #9 0x00000000068b550e clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(clang::TypeLocBuilder&, clang::TypeLoc) SemaTemplateInstantiate.cpp:0:0
#10 0x00000000068bb1da clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(clang::TypeSourceInfo*) SemaTemplateInstantiate.cpp:0:0
#11 0x00000000068c04b8 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformTemplateArgument(clang::TemplateArgumentLoc const&, clang::TemplateArgumentLoc&, bool) SemaTemplateInstantiate.cpp:0:0
#12 0x00000000068c39d8 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformTemplateSpecializationType(clang::TypeLocBuilder&, clang::TemplateSpecializationTypeLoc, clang::TemplateName) SemaTemplateInstantiate.cpp:0:0
#13 0x00000000068b6452 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(clang::TypeLocBuilder&, clang::TypeLoc) SemaTemplateInstantiate.cpp:0:0
#14 0x00000000068cba0d clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformElaboratedType(clang::TypeLocBuilder&, clang::ElaboratedTypeLoc) SemaTemplateInstantiate.cpp:0:0
#15 0x00000000068b5d3f clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(clang::TypeLocBuilder&, clang::TypeLoc) SemaTemplateInstantiate.cpp:0:0
#16 0x00000000068baab2 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformReferenceType(clang::TypeLocBuilder&, clang::ReferenceTypeLoc) SemaTemplateInstantiate.cpp:0:0
#17 0x00000000068b52d9 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(clang::TypeLocBuilder&, clang::TypeLoc) SemaTemplateInstantiate.cpp:0:0
#18 0x00000000068bb1da clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(clang::TypeSourceInfo*) SemaTemplateInstantiate.cpp:0:0
#19 0x00000000068c04b8 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformTemplateArgument(clang::TemplateArgumentLoc const&, clang::TemplateArgumentLoc&, bool) SemaTemplateInstantiate.cpp:0:0
#20 0x00000000068c1d55 bool clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformTemplateArguments<clang::TemplateArgumentLoc const*>(clang::TemplateArgumentLoc const*, clang::TemplateArgumentLoc const*, clang::TemplateArgumentListInfo&, bool) (.constprop.0) SemaTemplateInstantiate.cpp:0:0
#21 0x00000000068c23fb clang::Sema::SubstTypeConstraint(clang::TemplateTypeParmDecl*, clang::TypeConstraint const*, clang::MultiLevelTemplateArgumentList const&, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x68c23fb)
#22 0x00000000068ec6d8 clang::TemplateDeclInstantiator::VisitTemplateTypeParmDecl(clang::TemplateTypeParmDecl*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x68ec6d8)
#23 0x000000000693e250 clang::TemplateDeclInstantiator::SubstTemplateParams(clang::TemplateParameterList*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x693e250)
#24 0x00000000068b3e89 (anonymous namespace)::TemplateInstantiator::TransformExprRequirement(clang::concepts::ExprRequirement*) SemaTemplateInstantiate.cpp:0:0
#25 0x00000000068d1299 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformRequiresExpr(clang::RequiresExpr*) SemaTemplateInstantiate.cpp:0:0
#26 0x00000000068d259e (anonymous namespace)::TemplateInstantiator::TransformRequiresExpr(clang::RequiresExpr*) SemaTemplateInstantiate.cpp:0:0
#27 0x00000000068a5232 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(clang::Expr*) SemaTemplateInstantiate.cpp:0:0
#28 0x00000000068b2588 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformParenExpr(clang::ParenExpr*) SemaTemplateInstantiate.cpp:0:0
#29 0x00000000068a52cb clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(clang::Expr*) SemaTemplateInstantiate.cpp:0:0
#30 0x00000000068ad910 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCXXFoldExpr(clang::CXXFoldExpr*) SemaTemplateInstantiate.cpp:0:0
#31 0x00000000068a5779 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(clang::Expr*) SemaTemplateInstantiate.cpp:0:0
#32 0x00000000068a6068 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformInitializer(clang::Expr*, bool) (.part.0) SemaTemplateInstantiate.cpp:0:0
#33 0x00000000068a63ec clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformReturnStmt(clang::ReturnStmt*) SemaTemplateInstantiate.cpp:0:0
#34 0x00000000068df859 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCompoundStmt(clang::CompoundStmt*, bool) SemaTemplateInstantiate.cpp:0:0
#35 0x00000000068e376a clang::Sema::SubstStmt(clang::Stmt*, clang::MultiLevelTemplateArgumentList const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x68e376a)
#36 0x00000000069336eb clang::Sema::InstantiateFunctionDefinition(clang::SourceLocation, clang::FunctionDecl*, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x69336eb)
#37 0x0000000005ee92c1 clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ee92c1)
#38 0x000000000681a9e2 clang::Sema::DeduceReturnType(clang::FunctionDecl*, clang::SourceLocation, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x681a9e2)
#39 0x00000000062cd142 clang::Sema::DiagnoseUseOfDecl(clang::NamedDecl*, llvm::ArrayRef<clang::SourceLocation>, clang::ObjCInterfaceDecl const*, bool, bool, clang::ObjCInterfaceDecl*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x62cd142)
#40 0x0000000006663397 CreateFunctionRefExpr(clang::Sema&, clang::FunctionDecl*, clang::NamedDecl*, clang::Expr const*, bool, clang::SourceLocation, clang::DeclarationNameLoc const&) SemaOverload.cpp:0:0
#41 0x00000000066a0759 clang::Sema::BuildCallToObjectOfClassType(clang::Scope*, clang::Expr*, clang::SourceLocation, llvm::MutableArrayRef<clang::Expr*>, clang::SourceLocation) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x66a0759)
#42 0x0000000006340e18 clang::Sema::BuildCallExpr(clang::Scope*, clang::Expr*, clang::SourceLocation, llvm::MutableArrayRef<clang::Expr*>, clang::SourceLocation, clang::Expr*, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6340e18)
#43 0x0000000006342c8c clang::Sema::ActOnCallExpr(clang::Scope*, clang::Expr*, clang::SourceLocation, llvm::MutableArrayRef<clang::Expr*>, clang::SourceLocation, clang::Expr*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6342c8c)
#44 0x00000000068af2d0 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCallExpr(clang::CallExpr*) SemaTemplateInstantiate.cpp:0:0
#45 0x00000000068a56d2 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(clang::Expr*) SemaTemplateInstantiate.cpp:0:0
#46 0x00000000068e3d58 clang::Sema::SubstConstraintExpr(clang::Expr*, clang::MultiLevelTemplateArgumentList const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x68e3d58)
#47 0x0000000006043e37 calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, clang::SourceLocation, clang::MultiLevelTemplateArgumentList const&, clang::Expr const*, clang::ConstraintSatisfaction&)::'lambda'(clang::Expr const*)::operator()(clang::Expr const*) const SemaConcept.cpp:0:0
#48 0x000000000604548b 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
#49 0x0000000006045c92 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
#50 0x00000000060462ca 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+++0x60462ca)
#51 0x000000000675cc0e clang::Sema::CheckConceptTemplateId(clang::CXXScopeSpec const&, clang::SourceLocation, clang::DeclarationNameInfo const&, clang::NamedDecl*, clang::ConceptDecl*, clang::TemplateArgumentListInfo const*) (.constprop.0) SemaTemplate.cpp:0:0
#52 0x000000000675eb87 clang::Sema::BuildTemplateIdExpr(clang::CXXScopeSpec const&, clang::SourceLocation, clang::LookupResult&, bool, clang::TemplateArgumentListInfo const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x675eb87)
#53 0x0000000006322a6c 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+++0x6322a6c)
#54 0x0000000005e19986 clang::Parser::tryParseCXXIdExpression(clang::CXXScopeSpec&, bool, clang::Token&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e19986)
#55 0x0000000005e19bd4 clang::Parser::ParseCXXIdExpression(bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e19bd4)
#56 0x0000000005dfd3da clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5dfd3da)
#57 0x0000000005dfdc85 clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5dfdc85)
#58 0x0000000005e0a1b3 clang::Parser::ParseConstantExpressionInExprEvalContext(clang::Parser::TypeCastState) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e0a1b3)
#59 0x0000000005de49e4 clang::Parser::ParseStaticAssertDeclaration(clang::SourceLocation&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5de49e4)
#60 0x0000000005dd63d9 clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5dd63d9)
#61 0x0000000005da2074 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5da2074)
#62 0x0000000005da2f3d clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5da2f3d)
#63 0x0000000005d972ca clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5d972ca)
#64 0x00000000048d7f18 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x48d7f18)
#65 0x000000000413f719 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x413f719)
#66 0x00000000040c36de clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x40c36de)
#67 0x000000000421fdb6 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x421fdb6)
#68 0x0000000000bce557 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbce557)
#69 0x0000000000bc6c0a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#70 0x0000000003f22a69 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
#71 0x00000000035c8a14 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x35c8a14)
#72 0x0000000003f2305f 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
#73 0x0000000003eeb925 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3eeb925)
#74 0x0000000003eec38d 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+++0x3eec38d)
#75 0x0000000003ef42e5 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3ef42e5)
#76 0x0000000000bcc7ec clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbcc7ec)
#77 0x0000000000ac59d1 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xac59d1)
#78 0x00007fe2d3972083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#79 0x0000000000bc66ee _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbc66ee)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
Compiler returned: 134

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

shafik commented Aug 11, 2023

CC @erichkeane

@LYP951018 LYP951018 self-assigned this Jan 4, 2024
LYP951018 added a commit that referenced this issue Jan 4, 2024
…odies (#76967)

Currently, due to the incomplete implementation of p0588r1, the
instantiation of lambda expressions leads to the instantiation of the
body. And `EvaluateConstraints` is false during the instantiation of the
body, which causes crashes during the instantiation of the return type
requirement:

```cpp
template<typename T> concept doesnt_matter = true;

template<class T>
concept test = 
    []{
        return requires(T t) {
            { t } -> doesnt_matter; // crash
        };
    }();

static_assert(test<int>);
```

Although a complete implementation of p0588r1 can solve these crashes,
it will take some time. Therefore, this pull request aims to fix these
crashes first.

Fixes #63808
Fixes #64607
Fixes #64086
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts 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