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 16 & trunk][c++20] Crash when mixing iterator concepts, ADL and using-declarations in a requires expression #63808

Closed
octurion opened this issue Jul 11, 2023 · 3 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

@octurion
Copy link

octurion commented Jul 11, 2023

After drawing some inspiration from this StackOverflow answer, I decided to write up the following code that checks the presence of begin() and end() via ADL:

#include <concepts>
#include <iterator>
#include <vector>

template <typename T>
concept HasBeginEnd = []{
    using std::begin;
    using std::end;

    return requires(T& t)
    {
        {begin(t)} -> std::input_iterator;
        {end(t)} -> std::input_iterator;
    };
}();
static_assert(HasBeginEnd<std::vector<int>>);

This, however, crashes Clang 16 and trunk on Godbolt. Surprisingly, it appears that Clang 15 and older are not affected.

Godbolt link: https://godbolt.org/z/zndsGP63Y

Stacktrace generated: stacktrace.txt

@octurion octurion changed the title [clang 16 & trunk][c++20] Crash when mixing iterator concepts and using-declarations in a requires expression [clang 16 & trunk][c++20] Crash when mixing iterator concepts, ADL and using-declarations in a requires expression Jul 11, 2023
@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 Jul 11, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Jul 11, 2023

@llvm/issue-subscribers-clang-frontend

@llvmbot
Copy link
Collaborator

llvmbot commented Jul 11, 2023

@llvm/issue-subscribers-c-20

@shafik
Copy link
Collaborator

shafik commented Jul 11, 2023

Confirmed: https://godbolt.org/z/9jzf1s8xc

Assertion

clang++: /root/llvm-project/clang/include/clang/AST/ExprConcepts.h:103:
bool clang::ConceptSpecializationExpr::isSatisfied() const:
Assertion `!isValueDependent() && "isSatisfied called on a dependent ConceptSpecializationExpr"' 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 <source>
1.	<source>:16:44: current parser token ')'
 #0 0x000055a42f3f077f llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3c4577f)
 #1 0x000055a42f3ee4ec llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3c434ec)
 #2 0x000055a42f338528 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007f24d026d420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007f24cfd3a00b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
 #5 0x00007f24cfd19859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
 #6 0x00007f24cfd19729 (/lib/x86_64-linux-gnu/libc.so.6+0x22729)
 #7 0x00007f24cfd2afd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #8 0x000055a43222b0b3 clang::Sema::BuildExprRequirement(clang::Expr*, bool, clang::SourceLocation, clang::concepts::ExprRequirement::ReturnTypeRequirement) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6a800b3)
 #9 0x000055a4326ffc48 (anonymous namespace)::TemplateInstantiator::TransformExprRequirement(clang::concepts::ExprRequirement*) SemaTemplateInstantiate.cpp:0:0
#10 0x000055a43271d5a9 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformRequiresExpr(clang::RequiresExpr*) SemaTemplateInstantiate.cpp:0:0
#11 0x000055a43271e4be (anonymous namespace)::TemplateInstantiator::TransformRequiresExpr(clang::RequiresExpr*) SemaTemplateInstantiate.cpp:0:0
#12 0x000055a4326f1643 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(clang::Expr*) SemaTemplateInstantiate.cpp:0:0
#13 0x000055a4326f2428 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformInitializer(clang::Expr*, bool) (.part.0) SemaTemplateInstantiate.cpp:0:0
#14 0x000055a4326f27ac clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformReturnStmt(clang::ReturnStmt*) SemaTemplateInstantiate.cpp:0:0
#15 0x000055a43272b779 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCompoundStmt(clang::CompoundStmt*, bool) SemaTemplateInstantiate.cpp:0:0
#16 0x000055a4326f0cda clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformLambdaExpr(clang::LambdaExpr*) SemaTemplateInstantiate.cpp:0:0
#17 0x000055a4326f191c clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(clang::Expr*) SemaTemplateInstantiate.cpp:0:0
#18 0x000055a4326fbbd6 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCallExpr(clang::CallExpr*) SemaTemplateInstantiate.cpp:0:0
#19 0x000055a4326f1aea clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformExpr(clang::Expr*) SemaTemplateInstantiate.cpp:0:0
#20 0x000055a43272ef5c clang::Sema::SubstConstraintExpr(clang::Expr*, clang::MultiLevelTemplateArgumentList const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6f83f5c)
#21 0x000055a431e5d6df 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
#22 0x000055a431e5ebc0 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
#23 0x000055a431e5f352 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
#24 0x000055a431e5f994 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+++0x66b4994)
#25 0x000055a43259f8ac clang::Sema::CheckConceptTemplateId(clang::CXXScopeSpec const&, clang::SourceLocation, clang::DeclarationNameInfo const&, clang::NamedDecl*, clang::ConceptDecl*, clang::TemplateArgumentListInfo const*) (.constprop.0) SemaTemplate.cpp:0:0
#26 0x000055a4325a1927 clang::Sema::BuildTemplateIdExpr(clang::CXXScopeSpec const&, clang::SourceLocation, clang::LookupResult&, bool, clang::TemplateArgumentListInfo const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6df6927)
#27 0x000055a43214eebd 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+++0x69a3ebd)
#28 0x000055a431c2e05a clang::Parser::tryParseCXXIdExpression(clang::CXXScopeSpec&, bool, clang::Token&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x648305a)
#29 0x000055a431c2e2bb clang::Parser::ParseCXXIdExpression(bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x64832bb)
#30 0x000055a431c0e35c clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x646335c)
#31 0x000055a431c0ea1c clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6463a1c)
#32 0x000055a431c1b64b clang::Parser::ParseConstantExpressionInExprEvalContext(clang::Parser::TypeCastState) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x647064b)
#33 0x000055a431bf537b clang::Parser::ParseStaticAssertDeclaration(clang::SourceLocation&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x644a37b)
#34 0x000055a431be6a57 clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x643ba57)
#35 0x000055a431bb1634 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6406634)
#36 0x000055a431bb2bf6 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6407bf6)
#37 0x000055a431ba6eca clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x63fbeca)
#38 0x000055a430678e88 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4ecde88)
#39 0x000055a42febb1b9 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x47101b9)
#40 0x000055a42fe401e6 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x46951e6)
#41 0x000055a42ffa0556 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x47f5556)
#42 0x000055a42c8bed64 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x1113d64)
#43 0x000055a42c8baa8a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#44 0x000055a42fc99ced 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
#45 0x000055a42f338a30 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3b8da30)
#46 0x000055a42fc9a30f 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
#47 0x000055a42fc60eec clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x44b5eec)
#48 0x000055a42fc6197d 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+++0x44b697d)
#49 0x000055a42fc69a5d clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x44bea5d)
#50 0x000055a42c8bcfda clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x1111fda)
#51 0x000055a42c7c3625 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x1018625)
#52 0x00007f24cfd1b083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#53 0x000055a42c8b586e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x110a86e)
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 Jul 11, 2023
@LYP951018 LYP951018 self-assigned this Dec 26, 2023
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
Status: Done
Development

Successfully merging a pull request may close this issue.

5 participants