[clang] [Clang] [Draft] Implement P0588R1 capture rules (PR #105953)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 24 10:57:36 PDT 2024
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
git-clang-format --diff 08acc3f73b64bed578d18812a04015cb537c9c82 afdff4e15c518984206da5b7cdbe9b14bb1b3bea --extensions cpp,h -- clang/include/clang/Sema/Sema.h clang/include/clang/Sema/SemaLambda.h clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaExprCXX.cpp clang/lib/Sema/SemaLambda.cpp clang/lib/Sema/SemaTemplateVariadic.cpp clang/lib/Sema/TreeTransform.h clang/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp clang/test/SemaTemplate/lambda-capture-pack.cpp
``````````
</details>
<details>
<summary>
View the diff from clang-format here.
</summary>
``````````diff
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 77f2f7e41d..3176f1c9c4 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14118,7 +14118,7 @@ public:
/// Collect decls expanded inside the lambda body.
/// e.g.
- ///
+ ///
/// \code
/// auto v = [](auto... c) {
/// sink([&](auto ...b) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index e99422e654..8bdc621ed7 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -19631,14 +19631,15 @@ static void DoMarkVarDeclReferenced(
case OdrUseContext::Dependent:
// If this is a dependent context, we don't need to mark variables as
// odr-used, but we may still need to track them for lambda capture.
- //
+ //
// If an expression potentially references a local entity within a
// declarative region in which it is odr-usable, and the expression would be
// potentially evaluated if the effect of any enclosing typeid expressions
// ([expr.typeid]) were ignored, the entity is said to be implicitly
// captured by each intervening lambda-expression with an associated
// capture-default that does not explicitly capture it.
- // TODO: How to determine if the current variable is within a typeid expression?
+ // TODO: How to determine if the current variable is within a typeid
+ // expression?
DoMarkPotentialCapture(SemaRef, Loc, Var, E);
break;
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index fd1b6d9f2d..caea1fc5b3 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -8663,7 +8663,6 @@ static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
if (!UnderlyingVar)
return;
-
// If the variable is clearly identified as non-odr-used and the full
// expression is not instantiation dependent, only then do we not
// need to check enclosing lambda's for speculative captures.
@@ -8695,30 +8694,29 @@ static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
}
}
-
- const bool IsVarNeverAConstantExpression =
- VariableCanNeverBeAConstantExpression(UnderlyingVar, S.Context);
- if (!IsFullExprInstantiationDependent || IsVarNeverAConstantExpression) {
- // This full expression is not instantiation dependent or the variable
- // can not be used in a constant expression - which means
- // this variable must be odr-used here, so diagnose a
- // capture violation early, if the variable is un-captureable.
- // This is purely for diagnosing errors early. Otherwise, this
- // error would get diagnosed when the lambda becomes capture ready.
- QualType CaptureType, DeclRefType;
- SourceLocation ExprLoc = VarExpr->getExprLoc();
- if (S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit,
- /*EllipsisLoc*/ SourceLocation(),
- /*BuildAndDiagnose*/ false, CaptureType,
- DeclRefType, nullptr)) {
- // We will never be able to capture this variable, and we need
- // to be able to in any and all instantiations, so diagnose it.
- S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit,
+ const bool IsVarNeverAConstantExpression =
+ VariableCanNeverBeAConstantExpression(UnderlyingVar, S.Context);
+ if (!IsFullExprInstantiationDependent || IsVarNeverAConstantExpression) {
+ // This full expression is not instantiation dependent or the variable
+ // can not be used in a constant expression - which means
+ // this variable must be odr-used here, so diagnose a
+ // capture violation early, if the variable is un-captureable.
+ // This is purely for diagnosing errors early. Otherwise, this
+ // error would get diagnosed when the lambda becomes capture ready.
+ QualType CaptureType, DeclRefType;
+ SourceLocation ExprLoc = VarExpr->getExprLoc();
+ if (S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit,
/*EllipsisLoc*/ SourceLocation(),
- /*BuildAndDiagnose*/ true, CaptureType,
- DeclRefType, nullptr);
- }
+ /*BuildAndDiagnose*/ false, CaptureType,
+ DeclRefType, nullptr)) {
+ // We will never be able to capture this variable, and we need
+ // to be able to in any and all instantiations, so diagnose it.
+ S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit,
+ /*EllipsisLoc*/ SourceLocation(),
+ /*BuildAndDiagnose*/ true, CaptureType,
+ DeclRefType, nullptr);
}
+ }
});
// Check if 'this' needs to be captured.
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index c6d3411618..0d46967a03 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -284,12 +284,11 @@ namespace {
}
};
-
class CollectExpandedParameterPacksVisitor
: public RecursiveASTVisitor<CollectExpandedParameterPacksVisitor> {
typedef RecursiveASTVisitor<CollectExpandedParameterPacksVisitor> inherited;
- SmallVectorImpl<Decl*> &Expanded;
+ SmallVectorImpl<Decl *> &Expanded;
bool UnderExpanded = false;
struct UnderExpandedRAII {
@@ -302,8 +301,7 @@ namespace {
~UnderExpandedRAII() { UnderExpanded = Old; }
};
-
- bool InLambda = false;
+ bool InLambda = false;
unsigned DepthLimit = (unsigned)-1;
void addExpanded(Decl *VD, SourceLocation Loc = SourceLocation()) {
@@ -354,11 +352,11 @@ namespace {
return true;
}
- bool TraversePackExpansionExpr(PackExpansionExpr *E) {
+ bool TraversePackExpansionExpr(PackExpansionExpr *E) {
UnderExpandedRAII UnderExpandedRAII{UnderExpanded};
return inherited::TraversePackExpansionExpr(E);
}
- bool TraverseCXXFoldExpr(CXXFoldExpr *E) {
+ bool TraverseCXXFoldExpr(CXXFoldExpr *E) {
UnderExpandedRAII UnderExpandedRAII{UnderExpanded};
return inherited::TraverseCXXFoldExpr(E);
}
@@ -387,11 +385,9 @@ namespace {
}
/// we don't need to traverse into lambdas
- bool TraverseLambdaExpr(LambdaExpr *Lambda) {
- return true;
- }
+ bool TraverseLambdaExpr(LambdaExpr *Lambda) { return true; }
};
- }
+ } // namespace
/// Determine whether it's possible for an unexpanded parameter pack to
/// be valid in this location. This only happens when we're in a declaration
@@ -689,7 +685,7 @@ void Sema::collectUnexpandedParameterPacksFromLambdaBody(
}
void Sema::collectExpandedParameterPacksFromLambdaBody(
- Stmt *Body, SmallVectorImpl<Decl *> &Expanded) {
+ Stmt *Body, SmallVectorImpl<Decl *> &Expanded) {
CollectExpandedParameterPacksVisitor visitor(Expanded);
visitor.TraverseStmt(Body);
}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 7d8861444f..378cc64524 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -14578,7 +14578,6 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
PacksExpandedInBody);
}
-
// Transform captures.
bool FinishedExplicitCaptures = false;
for (LambdaExpr::capture_iterator C = E->capture_begin(),
@@ -14672,17 +14671,14 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
bool ShouldExpand = false;
bool RetainExpansion = false;
std::optional<unsigned> NumExpansions;
- if (getDerived().TryExpandParameterPacks(IsImplicitCapturePack ? C->getLocation() : C->getEllipsisLoc(),
- C->getLocation(),
- Unexpanded,
- ShouldExpand, RetainExpansion,
- NumExpansions)) {
+ if (getDerived().TryExpandParameterPacks(
+ IsImplicitCapturePack ? C->getLocation() : C->getEllipsisLoc(),
+ C->getLocation(), Unexpanded, ShouldExpand, RetainExpansion,
+ NumExpansions)) {
Invalid = true;
continue;
}
-
-
if (ShouldExpand) {
// The transform has determined that we should perform an expansion;
// transform and capture each of the arguments.
@@ -14727,12 +14723,12 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
}
}
-
// FIXME: Retain a pack expansion if RetainExpansion is true.
continue;
}
- EllipsisLoc = IsImplicitCapturePack ? C->getLocation() : C->getEllipsisLoc();
+ EllipsisLoc =
+ IsImplicitCapturePack ? C->getLocation() : C->getEllipsisLoc();
}
// Transform the captured variable.
@@ -14755,7 +14751,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
if (!FinishedExplicitCaptures)
getSema().finishLambdaExplicitCaptures(LSI);
-
+
// Transform the template parameters, and add them to the current
// instantiation scope. The null case is handled correctly.
auto TPL = getDerived().TransformTemplateParameterList(
``````````
</details>
https://github.com/llvm/llvm-project/pull/105953
More information about the cfe-commits
mailing list