[clang] 98062d8 - Revert "[Clang] Add captures to the instantiation scope of lambda call operators"

Corentin Jabot via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 7 00:51:41 PDT 2023


Author: Corentin Jabot
Date: 2023-09-07T09:50:25+02:00
New Revision: 98062d8fefbd3539a63e7e6a85ff12a41543357c

URL: https://github.com/llvm/llvm-project/commit/98062d8fefbd3539a63e7e6a85ff12a41543357c
DIFF: https://github.com/llvm/llvm-project/commit/98062d8fefbd3539a63e7e6a85ff12a41543357c.diff

LOG: Revert "[Clang] Add captures to the instantiation scope of lambda call operators"

The change causes some libcxx regressions

This reverts commit eaf725bc9371a6699902d67d97662caaa3332799.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Sema/Sema.h
    clang/lib/Sema/SemaConcept.cpp
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaLambda.cpp
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/lib/Sema/TreeTransform.h
    clang/test/SemaCXX/lambda-capture-type-deduction.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5b2a6349a5b15b..acce35e231e714 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -268,11 +268,6 @@ Bug Fixes to C++ Support
 - Fix crash when parsing the requires clause of some generic lambdas.
   (`#64689 <https://github.com/llvm/llvm-project/issues/64689>`_)
 
-- Fix crash when the trailing return type of a generic and dependent
-  lambda refers to an init-capture.
-  (`#65067 <https://github.com/llvm/llvm-project/issues/65067>`_) and
-  (`#63675 <https://github.com/llvm/llvm-project/issues/63675>`_).
-
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 - Fixed an import failure of recursive friend class template.

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4fd0e6bd5982a7..5fdca93c66ab5c 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -7352,14 +7352,6 @@ class Sema final {
 
   sema::LambdaScopeInfo *RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator);
 
-  class LambdaScopeForCallOperatorInstantiationRAII
-      : private FunctionScopeRAII {
-  public:
-    LambdaScopeForCallOperatorInstantiationRAII(
-        Sema &SemasRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL,
-        LocalInstantiationScope &Scope);
-  };
-
   /// Check whether the given expression is a valid constraint expression.
   /// A diagnostic is emitted if it is not, false is returned, and
   /// PossibleNonPrimary will be set to true if the failure might be due to a

diff  --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index d1fa8e7831225b..fa3dadf68229ee 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -600,6 +600,11 @@ bool Sema::SetupConstraintScope(
       if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
                                            Scope, MLTAL))
         return true;
+      // Make sure the captures are also added to the instantiation scope.
+      if (isLambdaCallOperator(FD) &&
+          addInstantiatedCapturesToScope(FD, FromMemTempl->getTemplatedDecl(),
+                                         Scope, MLTAL))
+        return true;
     }
 
     return false;
@@ -624,6 +629,11 @@ bool Sema::SetupConstraintScope(
     // child-function.
     if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL))
       return true;
+
+    // Make sure the captures are also added to the instantiation scope.
+    if (isLambdaCallOperator(FD) &&
+        addInstantiatedCapturesToScope(FD, InstantiatedFrom, Scope, MLTAL))
+      return true;
   }
 
   return false;
@@ -702,8 +712,20 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
   }
   CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
 
-  LambdaScopeForCallOperatorInstantiationRAII LambdaScope(
-      *this, const_cast<FunctionDecl *>(FD), *MLTAL, Scope);
+  // When checking the constraints of a lambda, we need to restore a
+  // LambdaScopeInfo populated with correct capture information so that the type
+  // of a variable referring to a capture is correctly const-adjusted.
+  FunctionScopeRAII FuncScope(*this);
+  if (isLambdaCallOperator(FD)) {
+    LambdaScopeInfo *LSI = RebuildLambdaScopeInfo(
+        const_cast<CXXMethodDecl *>(cast<CXXMethodDecl>(FD)));
+    // Constraints are checked from the parent context of the lambda, so we set
+    // AfterParameterList to false, so that `tryCaptureVariable` finds
+    // explicit captures in the appropriate context.
+    LSI->AfterParameterList = false;
+  } else {
+    FuncScope.disable();
+  }
 
   return CheckConstraintSatisfaction(
       FD, {FD->getTrailingRequiresClause()}, *MLTAL,
@@ -891,10 +913,15 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints(
     ThisQuals = Method->getMethodQualifiers();
     Record = Method->getParent();
   }
-
   CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
-  LambdaScopeForCallOperatorInstantiationRAII LambdaScope(
-      *this, const_cast<FunctionDecl *>(Decl), *MLTAL, Scope);
+  FunctionScopeRAII FuncScope(*this);
+
+  if (isLambdaCallOperator(Decl)) {
+    LambdaScopeInfo *LSI = RebuildLambdaScopeInfo(cast<CXXMethodDecl>(Decl));
+    LSI->AfterParameterList = false;
+  } else {
+    FuncScope.disable();
+  }
 
   llvm::SmallVector<Expr *, 1> Converted;
   return CheckConstraintSatisfaction(Template, TemplateAC, Converted, *MLTAL,

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d6e090ee496eb3..d94366dac102a2 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15380,10 +15380,6 @@ LambdaScopeInfo *Sema::RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator) {
   LSI->CallOperator = CallOperator;
   LSI->Lambda = LambdaClass;
   LSI->ReturnType = CallOperator->getReturnType();
-  // This function in calls in situation where the context of the call operator
-  // is not entered, so we set AfterParameterList to false, so that
-  // `tryCaptureVariable` finds explicit captures in the appropriate context.
-  LSI->AfterParameterList = false;
   const LambdaCaptureDefault LCD = LambdaClass->getLambdaCaptureDefault();
 
   if (LCD == LCD_None)

diff  --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 1702ddb3ee0fbf..5256d91a19a0d0 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -20,7 +20,6 @@
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaLambda.h"
-#include "clang/Sema/Template.h"
 #include "llvm/ADT/STLExtras.h"
 #include <optional>
 using namespace clang;
@@ -2255,34 +2254,3 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
 
   return BuildBlock;
 }
-
-Sema::LambdaScopeForCallOperatorInstantiationRAII::
-    LambdaScopeForCallOperatorInstantiationRAII(
-        Sema &SemasRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL,
-        LocalInstantiationScope &Scope)
-    : FunctionScopeRAII(SemasRef) {
-  if (!isLambdaCallOperator(FD)) {
-    FunctionScopeRAII::disable();
-    return;
-  }
-
-  if (FD->isTemplateInstantiation() && FD->getPrimaryTemplate()) {
-    FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate();
-    if (const auto *FromMemTempl =
-            PrimaryTemplate->getInstantiatedFromMemberTemplate()) {
-      SemasRef.addInstantiatedCapturesToScope(
-          FD, FromMemTempl->getTemplatedDecl(), Scope, MLTAL);
-    }
-  }
-
-  else if (FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization ||
-           FD->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate) {
-    FunctionDecl *InstantiatedFrom =
-        FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization
-            ? FD->getInstantiatedFromMemberFunction()
-            : FD->getInstantiatedFromDecl();
-    SemasRef.addInstantiatedCapturesToScope(FD, InstantiatedFrom, Scope, MLTAL);
-  }
-
-  SemasRef.RebuildLambdaScopeInfo(cast<CXXMethodDecl>(FD));
-}

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 37a7d6204413a3..63f022d5c2ff09 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2426,9 +2426,6 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
       cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
   LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
 
-  Sema::LambdaScopeForCallOperatorInstantiationRAII LambdaScope(
-      SemaRef, const_cast<CXXMethodDecl *>(D), TemplateArgs, Scope);
-
   // Instantiate enclosing template arguments for friends.
   SmallVector<TemplateParameterList *, 4> TempParamLists;
   unsigned NumTempParamLists = 0;

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index a075ade1adb7bb..7323140bc336bc 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -12325,7 +12325,7 @@ TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
-  QualType T = getDerived().TransformType(E->getType());
+  QualType T = getSema().getCurrentThisType();
 
   if (!getDerived().AlwaysRebuild() && T == E->getType()) {
     // Mark it referenced in the new context regardless.

diff  --git a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
index 7bf36a6a9cab73..9855122c962722 100644
--- a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
+++ b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
@@ -260,40 +260,3 @@ void f(int) {
 void test() { f<int>(0);  }
 
 }
-
-namespace GH65067 {
-
-template <typename> class a {
-public:
-  template <typename b> void c(b f) { d<int>(f)(0); }
-  template <typename, typename b> auto d(b f) {
-    return [f = f](auto arg) -> a<decltype(f(arg))> { return {}; };
-  }
-};
-a<void> e;
-auto fn1() {
-  e.c([](int) {});
-}
-
-}
-
-namespace GH63675 {
-
-template <class _Tp> _Tp __declval();
-struct __get_tag {
-  template <class _Tag> void operator()(_Tag);
-};
-template <class _ImplFn> struct __basic_sender {
-  using __tag_t = decltype(__declval<_ImplFn>()(__declval<__get_tag>()));
-  _ImplFn __impl_;
-};
-auto __make_basic_sender = []<class... _Children>(
-                               _Children... __children) {
-  return __basic_sender{[... __children = __children]<class _Fun>(
-                     _Fun __fun) -> decltype(__fun(__children...)) {}};
-};
-void __trans_tmp_1() {
-  __make_basic_sender(__trans_tmp_1);
-}
-
-}


        


More information about the cfe-commits mailing list