https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/83997
>From 69414d7352b170f6fcff22c6f5dfa91cc76b0b58 Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Tue, 5 Mar 2024 19:56:59 +0800 Subject: [PATCH 1/2] gh56556 --- clang/lib/Sema/TreeTransform.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 7389a48fe56fcc..c96ffcb97a7591 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -13649,10 +13649,12 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { // use evaluation contexts to distinguish the function parameter case. CXXRecordDecl::LambdaDependencyKind DependencyKind = CXXRecordDecl::LDK_Unknown; + DeclContext *DC = getSema().CurContext; + if (DC->getDeclKind() == Decl::Kind::RequiresExprBody) + DC = DC->getParent(); if ((getSema().isUnevaluatedContext() || getSema().isConstantEvaluatedContext()) && - (getSema().CurContext->isFileContext() || - !getSema().CurContext->getParent()->isDependentContext())) + (DC->isFileContext() || !DC->getParent()->isDependentContext())) DependencyKind = CXXRecordDecl::LDK_NeverDependent; CXXRecordDecl *OldClass = E->getLambdaClass(); >From b905083e5d5186ad08ac3d553be3e8f47dabc1b6 Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Wed, 6 Mar 2024 13:46:43 +0800 Subject: [PATCH 2/2] Tests & release notes --- clang/docs/ReleaseNotes.rst | 2 + clang/lib/Sema/TreeTransform.h | 17 +++++++ clang/test/SemaTemplate/concepts-lambda.cpp | 52 +++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d4e6bcf661da1a..141099fb68a200 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -302,6 +302,8 @@ Bug Fixes to C++ Support our attention by an attempt to fix in (#GH77703). Fixes (#GH83385). - Fix evaluation of some immediate calls in default arguments. Fixes (#GH80630) +- Fixed an issue where the ``RequiresExprBody`` was involved in the lambda dependency + calculation. (#GH56556), (#GH82849). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index c96ffcb97a7591..84348e13567e71 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -13650,6 +13650,23 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { CXXRecordDecl::LambdaDependencyKind DependencyKind = CXXRecordDecl::LDK_Unknown; DeclContext *DC = getSema().CurContext; + // A RequiresExprBodyDecl is not interesting for dependencies. + // For the following case, + // + // template <typename> + // concept C = requires { [] {}; }; + // + // template <class F> + // struct Widget; + // + // template <C F> + // struct Widget<F> {}; + // + // While we are here in substitution for Widget<F>, the parent of DC would be + // the template specialization itself. Thus, the lambda expression + // will be deemed as dependent even if we have non-dependent template + // arguments. + // (A ClassTemplateSpecializationDecl is always a dependent context.) if (DC->getDeclKind() == Decl::Kind::RequiresExprBody) DC = DC->getParent(); if ((getSema().isUnevaluatedContext() || diff --git a/clang/test/SemaTemplate/concepts-lambda.cpp b/clang/test/SemaTemplate/concepts-lambda.cpp index 0b7580f91043c7..ef04cad4eef98b 100644 --- a/clang/test/SemaTemplate/concepts-lambda.cpp +++ b/clang/test/SemaTemplate/concepts-lambda.cpp @@ -90,6 +90,58 @@ struct Foo { static_assert(ConstructibleWithN<Foo>); +namespace GH56556 { + +template <typename It> +inline constexpr It declare (); + +template <typename It, template <typename> typename Template> +concept D = requires { + { [] <typename T1> (Template<T1> &) {}(declare<It &>()) }; +}; + +template <typename T> +struct B {}; + +template <typename T> +struct Adapter; + +template <D<B> T> +struct Adapter<T> {}; + +template struct Adapter<B<int>>; + +} // namespace GH56556 + +namespace GH82849 { + +template <class T> +concept C = requires(T t) { + [](T) {}(t); +}; + +template <class From> +struct Widget; + +template <C F> +struct Widget<F> { + static F create(F from) { + return from; + } +}; + +template <class> +bool foo() { + return C<int>; +} + +void bar() { + // https://github.com/llvm/llvm-project/issues/49570#issuecomment-1664966972 + Widget<char>::create(0); +} + +} // namespace GH82849 + } // GH60642 reported an assert being hit, make sure we don't assert. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits