[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 ¤tEvaluationContext() {
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