[clang] [clang][Sema] Skip the RequiresExprBodyDecls for lambda dependencies (PR #83997)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 5 22:02:18 PST 2024
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 <zyn7109 at 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 <zyn7109 at 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.
More information about the cfe-commits
mailing list