llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Younan Zhang (zyn0217) <details> <summary>Changes</summary> The dependency of a lambda inside of a `RequiresExprBodyDecl` was previously affected by its parent, e.g., `ClassTemplateSpecializationDecl`. This made the lambda always dependent regardless of the template arguments we had, which caused some crashes on the constraint evaluation later. This fixes https://github.com/llvm/llvm-project/issues/56556, https://github.com/llvm/llvm-project/issues/82849 and a case demonstrated by https://github.com/llvm/llvm-project/issues/49570#issuecomment-1664966972. --- Full diff: https://github.com/llvm/llvm-project/pull/83997.diff 3 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+2) - (modified) clang/lib/Sema/TreeTransform.h (+21-2) - (modified) clang/test/SemaTemplate/concepts-lambda.cpp (+52) ``````````diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 5e0352a7eaf6cd..9c64cd2b5f6a10 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -311,6 +311,8 @@ Bug Fixes to C++ Support Fixes (#GH80630) - Fix a crash when an explicit template argument list is used with a name for which lookup finds a non-template function and a dependent using declarator. +- 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 7389a48fe56fcc..84348e13567e71 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -13649,10 +13649,29 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { // use evaluation contexts to distinguish the function parameter case. 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() || getSema().isConstantEvaluatedContext()) && - (getSema().CurContext->isFileContext() || - !getSema().CurContext->getParent()->isDependentContext())) + (DC->isFileContext() || !DC->getParent()->isDependentContext())) DependencyKind = CXXRecordDecl::LDK_NeverDependent; CXXRecordDecl *OldClass = E->getLambdaClass(); 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. `````````` </details> https://github.com/llvm/llvm-project/pull/83997 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits