[clang] 61d1cce - PR45881: Properly use CXXThisOverride for templated lambda

Yuanfang Chen via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 7 17:02:53 PDT 2021


Author: Yuanfang Chen
Date: 2021-09-07T17:02:24-07:00
New Revision: 61d1cce2f83571c00f76144d42a2dea2cb3ab1ca

URL: https://github.com/llvm/llvm-project/commit/61d1cce2f83571c00f76144d42a2dea2cb3ab1ca
DIFF: https://github.com/llvm/llvm-project/commit/61d1cce2f83571c00f76144d42a2dea2cb3ab1ca.diff

LOG: PR45881: Properly use CXXThisOverride for templated lambda

- `this` used in lambda expression parameter declarations needs no capture.
- Set up CXXThisOverride for default template arguments of a lambda.

A similar fix to this is c3d2ebb60f604.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D102531

Added: 
    clang/test/SemaCXX/cxx20-lambda-decltype-this.cpp

Modified: 
    clang/lib/Sema/SemaExprCXX.cpp
    clang/lib/Sema/SemaTemplate.cpp
    clang/lib/Sema/SemaTemplateDeduction.cpp
    clang/test/SemaCXX/cxx1z-lambda-star-this.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index ba2e17c4a6313..e30e1bb7df786 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1137,11 +1137,10 @@ static QualType adjustCVQualifiersForCXXThisWithinLambda(
     }
   }
 
-  // 2) We've run out of ScopeInfos but check if CurDC is a lambda (which can
-  // happen during instantiation of its nested generic lambda call operator)
-  if (isLambdaCallOperator(CurDC)) {
-    assert(CurLSI && "While computing 'this' capture-type for a generic "
-                     "lambda, we must have a corresponding LambdaScopeInfo");
+  // 2) We've run out of ScopeInfos but check 1. if CurDC is a lambda (which
+  //    can happen during instantiation of its nested generic lambda call
+  //    operator); 2. if we're in a lambda scope (lambda body).
+  if (CurLSI && isLambdaCallOperator(CurDC)) {
     assert(isGenericLambdaCallOperatorSpecialization(CurLSI->CallOperator) &&
            "While computing 'this' capture-type for a generic lambda, when we "
            "run out of enclosing LSI's, yet the enclosing DC is a "

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 5d26f2d2c11a5..6682b17f4e146 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -5110,7 +5110,11 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
     for (unsigned i = 0, e = Param->getDepth(); i != e; ++i)
       TemplateArgLists.addOuterTemplateArguments(None);
 
-    Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext());
+    bool ForLambdaCallOperator = false;
+    if (const auto *Rec = dyn_cast<CXXRecordDecl>(Template->getDeclContext()))
+      ForLambdaCallOperator = Rec->isLambda();
+    Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext(),
+                                   !ForLambdaCallOperator);
     ArgType =
         SemaRef.SubstType(ArgType, TemplateArgLists,
                           Param->getDefaultArgumentLoc(), Param->getDeclName());

diff  --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 5d93a17922269..f0a9e820c028c 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2858,9 +2858,24 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments(
       return Sema::TDK_Incomplete;
     }
 
-    TemplateArgumentLoc DefArg = S.SubstDefaultTemplateArgumentIfAvailable(
-        TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param, Builder,
-        HasDefaultArg);
+    TemplateArgumentLoc DefArg;
+    {
+      Qualifiers ThisTypeQuals;
+      CXXRecordDecl *ThisContext = nullptr;
+      if (auto *Rec = dyn_cast<CXXRecordDecl>(TD->getDeclContext()))
+        if (Rec->isLambda())
+          if (auto *Method = dyn_cast<CXXMethodDecl>(Rec->getDeclContext())) {
+            ThisContext = Method->getParent();
+            ThisTypeQuals = Method->getMethodQualifiers();
+          }
+
+      Sema::CXXThisScopeRAII ThisScope(S, ThisContext, ThisTypeQuals,
+                                       S.getLangOpts().CPlusPlus17);
+
+      DefArg = S.SubstDefaultTemplateArgumentIfAvailable(
+          TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param, Builder,
+          HasDefaultArg);
+    }
 
     // If there was no default argument, deduction is incomplete.
     if (DefArg.getArgument().isNull()) {

diff  --git a/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp b/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp
index 2426e8f5a207f..5a471fd6b6940 100644
--- a/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp
+++ b/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp
@@ -298,3 +298,13 @@ class A {
 
 } // namespace PR32831
 
+namespace PR45881 {
+struct A {
+    void f();
+};
+int id(A*);
+void A::f() {
+    auto z = [*this](auto z2, decltype(z2(this)) z3){};
+    z(id,3);
+}
+} // namespace PR45881

diff  --git a/clang/test/SemaCXX/cxx20-lambda-decltype-this.cpp b/clang/test/SemaCXX/cxx20-lambda-decltype-this.cpp
new file mode 100644
index 0000000000000..161a2bcb25d72
--- /dev/null
+++ b/clang/test/SemaCXX/cxx20-lambda-decltype-this.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -emit-llvm-only %s
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fdelayed-template-parsing %s
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fms-extensions %s
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fdelayed-template-parsing -fms-extensions %s
+
+namespace PR45881 {
+struct A {
+    void f();
+};
+int id(A*);
+void A::f() {
+    auto z = [*this](auto z2, decltype(z2(this)) z3){};
+    z(id,3);
+}
+
+struct B {
+    void f();
+};
+void B::f() {
+    auto z = []<typename TT, typename TTT=decltype(TT()(this))>(){return 0;};
+    z.template operator()<int(*)(B*)>();
+}
+
+struct C {
+    void f();
+};
+void C::f() {
+    auto z = []<typename TT, decltype(TT()(this)) n>(){return 0;};
+    z.template operator()<int(*)(C*), 8>();
+}
+} // namespace PR45881


        


More information about the cfe-commits mailing list