[llvm-branch-commits] [clang] a32c834 - Revert "[Clang] Only remove lambda scope after computing evaluation context (…"

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Aug 19 09:55:46 PDT 2025


Author: Younan Zhang
Date: 2025-08-20T00:55:43+08:00
New Revision: a32c83413bc68d00fa7431877856767828c7c217

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

LOG: Revert "[Clang] Only remove lambda scope after computing evaluation context (…"

This reverts commit 2b32ad1316059ac5fbb739684b92facef979dea1.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Sema/Sema.h
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaLambda.cpp
    clang/lib/Sema/TreeTransform.h
    clang/test/SemaCXX/cxx2b-consteval-propagate.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a8dc5352fcbb4..b86a9c437ffb1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -225,7 +225,6 @@ Bug Fixes to C++ Support
 - Diagnose binding a reference to ``*nullptr`` during constant evaluation. (#GH48665)
 - Suppress ``-Wdeprecated-declarations`` in implicitly generated functions. (#GH147293)
 - Fix a crash when deleting a pointer to an incomplete array (#GH150359).
-- Fixed a mismatched lambda scope bug when propagating up ``consteval`` within nested lambdas. (#GH145776)
 - Fix an assertion failure when expression in assumption attribute
   (``[[assume(expr)]]``) creates temporary objects.
 - Fix the dynamic_cast to final class optimization to correctly handle

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 098fe277c2b15..da9070842694e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4176,15 +4176,8 @@ class Sema final : public SemaBase {
   /// return statement in the scope of a variable has the same NRVO candidate,
   /// that candidate is an NRVO variable.
   void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope);
-
-  /// Performs semantic analysis at the end of a function body.
-  ///
-  /// \param RetainFunctionScopeInfo If \c true, the client is responsible for
-  /// releasing the associated \p FunctionScopeInfo. This is useful when
-  /// building e.g. LambdaExprs.
-  Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body,
-                                bool IsInstantiation = false,
-                                bool RetainFunctionScopeInfo = false);
+  Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body);
+  Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation);
   Decl *ActOnSkippedFunctionBody(Decl *Decl);
   void ActOnFinishInlineFunctionDef(FunctionDecl *D);
 
@@ -6881,23 +6874,23 @@ class Sema final : public SemaBase {
     assert(!ExprEvalContexts.empty() &&
            "Must be in an expression evaluation context");
     return ExprEvalContexts.back();
-  }
+  };
 
   ExpressionEvaluationContextRecord &currentEvaluationContext() {
     assert(!ExprEvalContexts.empty() &&
            "Must be in an expression evaluation context");
     return ExprEvalContexts.back();
-  }
+  };
 
   ExpressionEvaluationContextRecord &parentEvaluationContext() {
     assert(ExprEvalContexts.size() >= 2 &&
            "Must be in an expression evaluation context");
     return ExprEvalContexts[ExprEvalContexts.size() - 2];
-  }
+  };
 
   const ExpressionEvaluationContextRecord &parentEvaluationContext() const {
     return const_cast<Sema *>(this)->parentEvaluationContext();
-  }
+  };
 
   bool isAttrContext() const {
     return ExprEvalContexts.back().ExprContext ==
@@ -9147,7 +9140,8 @@ class Sema final : public SemaBase {
 
   /// Complete a lambda-expression having processed and attached the
   /// lambda body.
-  ExprResult BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc);
+  ExprResult BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
+                             sema::LambdaScopeInfo *LSI);
 
   /// Get the return type to use for a lambda's conversion function(s) to
   /// function pointer type, given the type of the call operator.

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5e62c0cf01510..98485cf9e72be 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -16228,6 +16228,10 @@ Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) {
   return Decl;
 }
 
+Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) {
+  return ActOnFinishFunctionBody(D, BodyArg, /*IsInstantiation=*/false);
+}
+
 /// RAII object that pops an ExpressionEvaluationContext when exiting a function
 /// body.
 class ExitFunctionBodyRAII {
@@ -16298,8 +16302,8 @@ void Sema::CheckCoroutineWrapper(FunctionDecl *FD) {
     Diag(FD->getLocation(), diag::err_coroutine_return_type) << RD;
 }
 
-Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation,
-                                    bool RetainFunctionScopeInfo) {
+Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
+                                    bool IsInstantiation) {
   FunctionScopeInfo *FSI = getCurFunction();
   FunctionDecl *FD = dcl ? dcl->getAsFunction() : nullptr;
 
@@ -16756,8 +16760,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation,
   if (!IsInstantiation)
     PopDeclContext();
 
-  if (!RetainFunctionScopeInfo)
-    PopFunctionScopeInfo(ActivePolicy, dcl);
+  PopFunctionScopeInfo(ActivePolicy, dcl);
   // If any errors have occurred, clear out any temporaries that may have
   // been leftover. This ensures that these temporaries won't be picked up for
   // deletion in some later function.

diff  --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index f09f1ad44ccec..0d891fc08c207 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1968,15 +1968,14 @@ ExprResult Sema::BuildCaptureInit(const Capture &Cap,
 }
 
 ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body) {
-  LambdaScopeInfo &LSI = *cast<LambdaScopeInfo>(FunctionScopes.back());
+  LambdaScopeInfo LSI = *cast<LambdaScopeInfo>(FunctionScopes.back());
 
   if (LSI.CallOperator->hasAttr<SYCLKernelEntryPointAttr>())
     SYCL().CheckSYCLEntryPointFunctionDecl(LSI.CallOperator);
 
-  ActOnFinishFunctionBody(LSI.CallOperator, Body, /*IsInstantiation=*/false,
-                          /*RetainFunctionScopeInfo=*/true);
+  ActOnFinishFunctionBody(LSI.CallOperator, Body);
 
-  return BuildLambdaExpr(StartLoc, Body->getEndLoc());
+  return BuildLambdaExpr(StartLoc, Body->getEndLoc(), &LSI);
 }
 
 static LambdaCaptureDefault
@@ -2133,9 +2132,8 @@ ConstructFixItRangeForUnusedCapture(Sema &S, SourceRange CaptureRange,
   return SourceRange(FixItStart, FixItEnd);
 }
 
-ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc,
-                                 SourceLocation EndLoc) {
-  LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(FunctionScopes.back());
+ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
+                                 LambdaScopeInfo *LSI) {
   // Collect information from the lambda scope.
   SmallVector<LambdaCapture, 4> Captures;
   SmallVector<Expr *, 4> CaptureInits;
@@ -2172,12 +2170,6 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc,
 
     PopExpressionEvaluationContext();
 
-    sema::AnalysisBasedWarnings::Policy WP =
-        AnalysisWarnings.getPolicyInEffectAt(EndLoc);
-    // We cannot release LSI until we finish computing captures, which
-    // requires the scope to be popped.
-    PoppedFunctionScopePtr _ = PopFunctionScopeInfo(&WP, LSI->CallOperator);
-
     // True if the current capture has a used capture or default before it.
     bool CurHasPreviousCapture = CaptureDefault != LCD_None;
     SourceLocation PrevCaptureLoc = CurHasPreviousCapture ?

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 7f0b24ecb7e20..51f58e35a1ef4 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4051,7 +4051,7 @@ class TreeTransform {
             PVD->getUninstantiatedDefaultArg()
                 ->containsUnexpandedParameterPack();
     }
-    return getSema().BuildLambdaExpr(StartLoc, EndLoc);
+    return getSema().BuildLambdaExpr(StartLoc, EndLoc, LSI);
   }
 
   /// Build an empty C++1z fold-expression with the given operator.
@@ -15712,9 +15712,12 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
     return ExprError();
   }
 
+  // Copy the LSI before ActOnFinishFunctionBody removes it.
+  // FIXME: This is dumb. Store the lambda information somewhere that outlives
+  // the call operator.
+  auto LSICopy = *LSI;
   getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
-                                    /*IsInstantiation=*/true,
-                                    /*RetainFunctionScopeInfo=*/true);
+                                    /*IsInstantiation*/ true);
   SavedContext.pop();
 
   // Recompute the dependency of the lambda so that we can defer the lambda call
@@ -15750,11 +15753,11 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
   // *after* the substitution in case we can't decide the dependency
   // so early, e.g. because we want to see if any of the *substituted*
   // parameters are dependent.
-  DependencyKind = getDerived().ComputeLambdaDependency(LSI);
+  DependencyKind = getDerived().ComputeLambdaDependency(&LSICopy);
   Class->setLambdaDependencyKind(DependencyKind);
 
   return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
-                                        Body.get()->getEndLoc(), LSI);
+                                        Body.get()->getEndLoc(), &LSICopy);
 }
 
 template<typename Derived>

diff  --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
index 6cf0e0251ab62..c4cfd9398920a 100644
--- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
+++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
@@ -610,19 +610,3 @@ namespace GH135281 {
   void (*ff)() = f2<B>; // expected-note {{instantiation of function template specialization}}
 }
 #endif
-
-namespace GH145776 {
-
-void runtime_only() {}
-consteval void comptime_only() {}
-
-void fn() {
-  []() {
-    runtime_only();
-    []() {
-      &comptime_only;
-    }();
-  }();
-}
-
-}


        


More information about the llvm-branch-commits mailing list