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][concepts] Clang may fail to match the appropriate partial specialization if contrained by a requires expression containing lambdas #62516

Closed
erinacio opened this issue May 3, 2023 · 5 comments
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts

Comments

@erinacio
Copy link

erinacio commented May 3, 2023

This issue is first found on clangd 17 shipped with CLion 2023.1.2 (22d9828), and reproduced on x86_64 clang trunk on compiler explorer (0a02f76) and clang-17 from apt.llvm.org (6875424).

This issue seems to only occur when:

  1. There's a class template (template <class T> struct A).
  2. There's a constrained partial specialization (template <C T> struct A<T>).
  3. That is effectively contrained by a requires expression (template <class T> concept C = requires ...;).
  4. That requires expression contains a lambda expression.
  5. That contraint is not tested before.

Given a type T which satisfies that constraint (i.e. static_assert(C<T>)), clang trunk will fail to match the partial specialization template <C T> struct A<T> if the constraint is not explicitly tested before (including static_assert(C<T>)), and any test to the constraint will fail afterwards.

MRE#1: https://godbolt.org/z/rEfP7PcPc, lambda used as a simple requirement.
MRE#2: https://godbolt.org/z/GhqdnqMGb, lambda used inside parameter list with decltype.

A slightly longer but more meaningful example: https://godbolt.org/z/xfGjrq7db.

@erinacio
Copy link
Author

erinacio commented May 3, 2023

Note that this may not be a Clang 17 regression. The same code would trigger an assertion failure with Clang 15 if enable all debug assertions. Taking MRE#1 as example:

Clang 15 assertion failure stacktrace
clang: /tmp/build/src/llvm-project-15.0.7.src/clang/lib/AST/ExprConstant.cpp:15088: bool clang::Expr::EvaluateAsConstantExpr(EvalResult&, const clang::ASTContext&, 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: clang -std=c++20 -c test.cc
1.      test.cc:24:39: current parser token ')'
 #0 0x0000556d0680fc26 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/llvm15/bin/clang-15+0x3a8ec26)
 #1 0x0000556d0680d97f llvm::sys::RunSignalHandlers() (/opt/llvm15/bin/clang-15+0x3a8c97f)
 #2 0x0000556d06764409 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007f076f969f50 (/usr/lib/libc.so.6+0x38f50)
 #4 0x00007f076f9b88ec (/usr/lib/libc.so.6+0x878ec)
 #5 0x00007f076f969ea8 raise (/usr/lib/libc.so.6+0x38ea8)
 #6 0x00007f076f95353d abort (/usr/lib/libc.so.6+0x2253d)
 #7 0x00007f076f95345c (/usr/lib/libc.so.6+0x2245c)
 #8 0x00007f076f9629f6 (/usr/lib/libc.so.6+0x319f6)
 #9 0x0000556d0975a57c (/opt/llvm15/bin/clang-15+0x69d957c)
#10 0x0000556d08b1a80f bool calculateConstraintSatisfaction<calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceLocation, clang::MultiLevelTemplateArgumentList&, clang::Expr const*, clang::ConstraintSatisfaction&)::'lambda'(clang::Expr const*)>(clang::Sema&, clang::Expr const*, clang::ConstraintSatisfaction&, calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceLocation, clang::MultiLevelTemplateArgumentList&, clang::Expr const*, clang::ConstraintSatisfaction&)::'lambda'(clang::Expr const*)&&) SemaConcept.cpp:0:0
#11 0x0000556d08b1abbc CheckConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, llvm::ArrayRef<clang::Expr const*>, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceRange, clang::ConstraintSatisfaction&) SemaConcept.cpp:0:0
#12 0x0000556d08b1ad90 clang::Sema::CheckConstraintSatisfaction(clang::NamedDecl const*, llvm::ArrayRef<clang::Expr const*>, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceRange, clang::ConstraintSatisfaction&) (/opt/llvm15/bin/clang-15+0x5d99d90)
#13 0x0000556d0913a236 clang::Sema::CheckConceptTemplateId(clang::CXXScopeSpec const&, clang::SourceLocation, clang::DeclarationNameInfo const&, clang::NamedDecl*, clang::ConceptDecl*, clang::TemplateArgumentListInfo const*) (/opt/llvm15/bin/clang-15+0x63b9236)
#14 0x0000556d092577d8 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformConceptSpecializationExpr(clang::ConceptSpecializationExpr*) SemaTemplateInstantiate.cpp:0:0
#15 0x0000556d0924599c clang::Sema::SubstExpr(clang::Expr*, clang::MultiLevelTemplateArgumentList const&) (/opt/llvm15/bin/clang-15+0x64c499c)
#16 0x0000556d08b1950b calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceLocation, clang::MultiLevelTemplateArgumentList&, clang::Expr const*, clang::ConstraintSatisfaction&)::'lambda'(clang::Expr const*)::operator()(clang::Expr const*) const SemaConcept.cpp:0:0
#17 0x0000556d08b1a783 bool calculateConstraintSatisfaction<calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceLocation, clang::MultiLevelTemplateArgumentList&, clang::Expr const*, clang::ConstraintSatisfaction&)::'lambda'(clang::Expr const*)>(clang::Sema&, clang::Expr const*, clang::ConstraintSatisfaction&, calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceLocation, clang::MultiLevelTemplateArgumentList&, clang::Expr const*, clang::ConstraintSatisfaction&)::'lambda'(clang::Expr const*)&&) SemaConcept.cpp:0:0
#18 0x0000556d08b1abbc CheckConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, llvm::ArrayRef<clang::Expr const*>, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceRange, clang::ConstraintSatisfaction&) SemaConcept.cpp:0:0
#19 0x0000556d08b1ad90 clang::Sema::CheckConstraintSatisfaction(clang::NamedDecl const*, llvm::ArrayRef<clang::Expr const*>, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceRange, clang::ConstraintSatisfaction&) (/opt/llvm15/bin/clang-15+0x5d99d90)
#20 0x0000556d091cec7e _Z31FinishTemplateArgumentDeductionIN5clang38ClassTemplatePartialSpecializationDeclEENSt9enable_ifIXsr23IsPartialSpecializationIT_E5valueENS0_4Sema23TemplateDeductionResultEE4typeERS6_PS4_bRKNS0_20TemplateArgumentListERN4llvm15SmallVectorImplINS0_23DeducedTemplateArgumentEEERNS0_4sema21TemplateDeductionInfoE SemaTemplateDeduction.cpp:0:0
#21 0x0000556d091cedf9 void llvm::function_ref<void ()>::callback_fn<clang::Sema::DeduceTemplateArguments(clang::ClassTemplatePartialSpecializationDecl*, clang::TemplateArgumentList const&, clang::sema::TemplateDeductionInfo&)::'lambda'()>(long) SemaTemplateDeduction.cpp:0:0
#22 0x0000556d089e94e4 clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<void ()>) (/opt/llvm15/bin/clang-15+0x5c684e4)
#23 0x0000556d0920500f clang::Sema::DeduceTemplateArguments(clang::ClassTemplatePartialSpecializationDecl*, clang::TemplateArgumentList const&, clang::sema::TemplateDeductionInfo&) (/opt/llvm15/bin/clang-15+0x648400f)
#24 0x0000556d092325c9 getPatternForClassTemplateSpecialization(clang::Sema&, clang::SourceLocation, clang::ClassTemplateSpecializationDecl*, clang::TemplateSpecializationKind) (.constprop.0) SemaTemplateInstantiate.cpp:0:0
#25 0x0000556d0926e52b clang::Sema::InstantiateClassTemplateSpecialization(clang::SourceLocation, clang::ClassTemplateSpecializationDecl*, clang::TemplateSpecializationKind, bool) (/opt/llvm15/bin/clang-15+0x64ed52b)
#26 0x0000556d092ef504 void llvm::function_ref<void ()>::callback_fn<clang::Sema::RequireCompleteTypeImpl(clang::SourceLocation, clang::QualType, clang::Sema::CompleteTypeKind, clang::Sema::TypeDiagnoser*)::'lambda'()>(long) SemaType.cpp:0:0
#27 0x0000556d089e94e4 clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<void ()>) (/opt/llvm15/bin/clang-15+0x5c684e4)
#28 0x0000556d093014ae clang::Sema::RequireCompleteTypeImpl(clang::SourceLocation, clang::QualType, clang::Sema::CompleteTypeKind, clang::Sema::TypeDiagnoser*) (/opt/llvm15/bin/clang-15+0x65804ae)
#29 0x0000556d093017a9 clang::Sema::RequireCompleteType(clang::SourceLocation, clang::QualType, clang::Sema::CompleteTypeKind, clang::Sema::TypeDiagnoser&) (/opt/llvm15/bin/clang-15+0x65807a9)
#30 0x0000556d08a2e6f7 clang::Sema::RequireCompleteDeclContext(clang::CXXScopeSpec&, clang::DeclContext*) (/opt/llvm15/bin/clang-15+0x5cad6f7)
#31 0x0000556d091267ed clang::Sema::CheckTypenameType(clang::ElaboratedTypeKeyword, clang::SourceLocation, clang::NestedNameSpecifierLoc, clang::IdentifierInfo const&, clang::SourceLocation, bool) (/opt/llvm15/bin/clang-15+0x63a57ed)
#32 0x0000556d0922f2c9 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::RebuildDependentNameType(clang::ElaboratedTypeKeyword, clang::SourceLocation, clang::NestedNameSpecifierLoc, clang::IdentifierInfo const*, clang::SourceLocation, bool) SemaTemplateInstantiate.cpp:0:0
#33 0x0000556d0925820a clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformDependentNameType(clang::TypeLocBuilder&, clang::DependentNameTypeLoc, bool) SemaTemplateInstantiate.cpp:0:0
#34 0x0000556d0924b413 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformType(clang::TypeSourceInfo*) SemaTemplateInstantiate.cpp:0:0
#35 0x0000556d0924e813 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformRequiresExpr(clang::RequiresExpr*) SemaTemplateInstantiate.cpp:0:0
#36 0x0000556d0925102a (anonymous namespace)::TemplateInstantiator::TransformRequiresExpr(clang::RequiresExpr*) SemaTemplateInstantiate.cpp:0:0
#37 0x0000556d0924599c clang::Sema::SubstExpr(clang::Expr*, clang::MultiLevelTemplateArgumentList const&) (/opt/llvm15/bin/clang-15+0x64c499c)
#38 0x0000556d08b1950b calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceLocation, clang::MultiLevelTemplateArgumentList&, clang::Expr const*, clang::ConstraintSatisfaction&)::'lambda'(clang::Expr const*)::operator()(clang::Expr const*) const SemaConcept.cpp:0:0
#39 0x0000556d08b1a783 bool calculateConstraintSatisfaction<calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceLocation, clang::MultiLevelTemplateArgumentList&, clang::Expr const*, clang::ConstraintSatisfaction&)::'lambda'(clang::Expr const*)>(clang::Sema&, clang::Expr const*, clang::ConstraintSatisfaction&, calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceLocation, clang::MultiLevelTemplateArgumentList&, clang::Expr const*, clang::ConstraintSatisfaction&)::'lambda'(clang::Expr const*)&&) SemaConcept.cpp:0:0
#40 0x0000556d08b1abbc CheckConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, llvm::ArrayRef<clang::Expr const*>, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceRange, clang::ConstraintSatisfaction&) SemaConcept.cpp:0:0
#41 0x0000556d08b1ad90 clang::Sema::CheckConstraintSatisfaction(clang::NamedDecl const*, llvm::ArrayRef<clang::Expr const*>, llvm::ArrayRef<clang::TemplateArgument>, clang::SourceRange, clang::ConstraintSatisfaction&) (/opt/llvm15/bin/clang-15+0x5d99d90)
#42 0x0000556d0913a236 clang::Sema::CheckConceptTemplateId(clang::CXXScopeSpec const&, clang::SourceLocation, clang::DeclarationNameInfo const&, clang::NamedDecl*, clang::ConceptDecl*, clang::TemplateArgumentListInfo const*) (/opt/llvm15/bin/clang-15+0x63b9236)
#43 0x0000556d0913c246 clang::Sema::BuildTemplateIdExpr(clang::CXXScopeSpec const&, clang::SourceLocation, clang::LookupResult&, bool, clang::TemplateArgumentListInfo const*) (/opt/llvm15/bin/clang-15+0x63bb246)
#44 0x0000556d08d65169 clang::Sema::ActOnIdExpression(clang::Scope*, clang::CXXScopeSpec&, clang::SourceLocation, clang::UnqualifiedId&, bool, bool, clang::CorrectionCandidateCallback*, bool, clang::Token*) (/opt/llvm15/bin/clang-15+0x5fe4169)
#45 0x0000556d0894085c clang::Parser::tryParseCXXIdExpression(clang::CXXScopeSpec&, bool, clang::Token&) (/opt/llvm15/bin/clang-15+0x5bbf85c)
#46 0x0000556d08940b4a clang::Parser::ParseCXXIdExpression(bool) (/opt/llvm15/bin/clang-15+0x5bbfb4a)
#47 0x0000556d08926275 clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) (/opt/llvm15/bin/clang-15+0x5ba5275)
#48 0x0000556d08925bce clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) (/opt/llvm15/bin/clang-15+0x5ba4bce)
#49 0x0000556d0893269b clang::Parser::ParseConstantExpressionInExprEvalContext(clang::Parser::TypeCastState) (/opt/llvm15/bin/clang-15+0x5bb169b)
#50 0x0000556d0890ef3f clang::Parser::ParseStaticAssertDeclaration(clang::SourceLocation&) (/opt/llvm15/bin/clang-15+0x5b8df3f)
#51 0x0000556d088ffff7 clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, clang::SourceLocation*) (/opt/llvm15/bin/clang-15+0x5b7eff7)
#52 0x0000556d088d6d9a clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/llvm15/bin/clang-15+0x5b55d9a)
#53 0x0000556d088d815d clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/llvm15/bin/clang-15+0x5b5715d)
#54 0x0000556d088c9f7b clang::ParseAST(clang::Sema&, bool, bool) (/opt/llvm15/bin/clang-15+0x5b48f7b)
#55 0x0000556d07297079 clang::FrontendAction::Execute() (/opt/llvm15/bin/clang-15+0x4516079)
#56 0x0000556d07234ec6 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/llvm15/bin/clang-15+0x44b3ec6)
#57 0x0000556d0734fe84 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/llvm15/bin/clang-15+0x45cee84)
#58 0x0000556d040fc71c cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/llvm15/bin/clang-15+0x137b71c)
#59 0x0000556d040f5ba2 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0
#60 0x0000556d070bf409 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#61 0x0000556d0676458e llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/llvm15/bin/clang-15+0x39e358e)
#62 0x0000556d070bfe70 clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (.part.0) Job.cpp:0:0
#63 0x0000556d0708c714 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/llvm15/bin/clang-15+0x430b714)
#64 0x0000556d0708cf26 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/opt/llvm15/bin/clang-15+0x430bf26)
#65 0x0000556d070976ed clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/llvm15/bin/clang-15+0x43166ed)
#66 0x0000556d040fa9d2 clang_main(int, char**) (/opt/llvm15/bin/clang-15+0x13799d2)
#67 0x00007f076f954790 (/usr/lib/libc.so.6+0x23790)
#68 0x00007f076f95484a __libc_start_main (/usr/lib/libc.so.6+0x2384a)
#69 0x0000556d040f4ec5 _start (/opt/llvm15/bin/clang-15+0x1373ec5)
clang-15: error: clang frontend command failed with exit code 134 (use -v to see invocation)
clang version 15.0.7
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/llvm15/bin
Clang 15 associated run script
# Crash reproducer for clang version 15.0.7
# Driver args: "-std=c++20" "-c" "test.cc"
# Original command:  "/opt/llvm15/bin/clang-15" "-cc1" "-triple" "x86_64-unknown-linux-gnu" "-emit-obj" "-mrelax-all" "--mrelax-relocations" "-disable-free" "-clear-ast-before-backend" "-main-file-name" "test.cc" "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie" "-mframe-pointer=all" "-fmath-errno" "-ffp-contract=on" "-fno-rounding-math" "-mconstructor-aliases" "-funwind-tables=2" "-target-cpu" "x86-64" "-tune-cpu" "generic" "-mllvm" "-treat-scalable-fixed-error-as-warning" "-debugger-tuning=gdb" "-fcoverage-compilation-dir=/tmp" "-resource-dir" "/opt/llvm15/lib/clang/15.0.7" "-internal-isystem" "/usr/lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1" "-internal-isystem" "/usr/lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/x86_64-pc-linux-gnu" "-internal-isystem" "/usr/lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/backward" "-internal-isystem" "/opt/llvm15/lib/clang/15.0.7/include" "-internal-isystem" "/usr/local/include" "-internal-isystem" "/usr/lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../x86_64-pc-linux-gnu/include" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-std=c++20" "-fdeprecated-macro" "-fdebug-compilation-dir=/tmp" "-ferror-limit" "19" "-fgnuc-version=4.2.1" "-fno-implicit-modules" "-fcxx-exceptions" "-fexceptions" "-fcolor-diagnostics" "-faddrsig" "-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o" "test.o" "-x" "c++" "test.cc"
 "/opt/llvm15/bin/clang-15" "-cc1" "-triple" "x86_64-unknown-linux-gnu" "-emit-obj" "-mrelax-all" "--mrelax-relocations" "-disable-free" "-clear-ast-before-backend" "-main-file-name" "test.cc" "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie" "-mframe-pointer=all" "-fmath-errno" "-ffp-contract=on" "-fno-rounding-math" "-mconstructor-aliases" "-funwind-tables=2" "-target-cpu" "x86-64" "-tune-cpu" "generic" "-mllvm" "-treat-scalable-fixed-error-as-warning" "-debugger-tuning=gdb" "-fcoverage-compilation-dir=/tmp" "-std=c++20" "-fdeprecated-macro" "-fdebug-compilation-dir=/tmp" "-ferror-limit" "19" "-fgnuc-version=4.2.1" "-fno-implicit-modules" "-fcxx-exceptions" "-fexceptions" "-fcolor-diagnostics" "-faddrsig" "-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-x" "c++" "test-ecfebd.cpp"

@EugeneZelenko EugeneZelenko added c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts and removed new issue labels May 3, 2023
@llvmbot
Copy link

llvmbot commented May 3, 2023

@llvm/issue-subscribers-c-20

@llvmbot
Copy link

llvmbot commented May 3, 2023

@llvm/issue-subscribers-clang-frontend

@shafik
Copy link
Collaborator

shafik commented May 4, 2023

I believe this is: #58534

CC @erichkeane @usx95

@zyn0217
Copy link
Contributor

zyn0217 commented Mar 9, 2024

Fixed by #83997.
All the examples are now successfully compiled and don't cause crashes on the assertion trunk build. Closing.

https://godbolt.org/z/vezb5Kdxo

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
Projects
Status: Done
Development

No branches or pull requests

5 participants