Skip to content

Commit 7b9b28d

Browse files
authored
[Clang] Refactor implementation of "Lifetime extension in range-based for loops" (#87930)
This PR remove `InMaterializeTemporaryObjectContext` , because it's redundant, materialize non-cv void prvalue temporaries in discarded expressions can only appear under lifetime-extension context. Signed-off-by: yronglin <[email protected]>
1 parent a06073f commit 7b9b28d

File tree

6 files changed

+4
-62
lines changed

6 files changed

+4
-62
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5099,34 +5099,6 @@ class Sema final : public SemaBase {
50995099
/// example, in a for-range initializer).
51005100
bool InLifetimeExtendingContext = false;
51015101

5102-
/// Whether we are currently in a context in which all temporaries must be
5103-
/// materialized.
5104-
///
5105-
/// [class.temporary]/p2:
5106-
/// The materialization of a temporary object is generally delayed as long
5107-
/// as possible in order to avoid creating unnecessary temporary objects.
5108-
///
5109-
/// Temporary objects are materialized:
5110-
/// (2.1) when binding a reference to a prvalue ([dcl.init.ref],
5111-
/// [expr.type.conv], [expr.dynamic.cast], [expr.static.cast],
5112-
/// [expr.const.cast], [expr.cast]),
5113-
///
5114-
/// (2.2) when performing member access on a class prvalue ([expr.ref],
5115-
/// [expr.mptr.oper]),
5116-
///
5117-
/// (2.3) when performing an array-to-pointer conversion or subscripting
5118-
/// on an array prvalue ([conv.array], [expr.sub]),
5119-
///
5120-
/// (2.4) when initializing an object of type
5121-
/// std​::​initializer_list<T> from a braced-init-list
5122-
/// ([dcl.init.list]),
5123-
///
5124-
/// (2.5) for certain unevaluated operands ([expr.typeid], [expr.sizeof])
5125-
///
5126-
/// (2.6) when a prvalue that has type other than cv void appears as a
5127-
/// discarded-value expression ([expr.context]).
5128-
bool InMaterializeTemporaryObjectContext = false;
5129-
51305102
// When evaluating immediate functions in the initializer of a default
51315103
// argument or default member initializer, this is the declaration whose
51325104
// default initializer is being evaluated and the location of the call
@@ -6398,19 +6370,6 @@ class Sema final : public SemaBase {
63986370
}
63996371
}
64006372

6401-
/// keepInMaterializeTemporaryObjectContext - Pull down
6402-
/// InMaterializeTemporaryObjectContext flag from previous context.
6403-
void keepInMaterializeTemporaryObjectContext() {
6404-
if (ExprEvalContexts.size() > 2 &&
6405-
ExprEvalContexts[ExprEvalContexts.size() - 2]
6406-
.InMaterializeTemporaryObjectContext) {
6407-
auto &LastRecord = ExprEvalContexts.back();
6408-
auto &PrevRecord = ExprEvalContexts[ExprEvalContexts.size() - 2];
6409-
LastRecord.InMaterializeTemporaryObjectContext =
6410-
PrevRecord.InMaterializeTemporaryObjectContext;
6411-
}
6412-
}
6413-
64146373
DefaultedComparisonKind getDefaultedComparisonKind(const FunctionDecl *FD) {
64156374
return getDefaultedFunctionKind(FD).asComparison();
64166375
}
@@ -6554,12 +6513,6 @@ class Sema final : public SemaBase {
65546513
/// used in initializer of the field.
65556514
llvm::MapVector<FieldDecl *, DeleteLocs> DeleteExprs;
65566515

6557-
bool isInMaterializeTemporaryObjectContext() const {
6558-
assert(!ExprEvalContexts.empty() &&
6559-
"Must be in an expression evaluation context");
6560-
return ExprEvalContexts.back().InMaterializeTemporaryObjectContext;
6561-
}
6562-
65636516
ParsedType getInheritingConstructorName(CXXScopeSpec &SS,
65646517
SourceLocation NameLoc,
65656518
const IdentifierInfo &Name);

clang/lib/Parse/ParseDecl.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2380,10 +2380,6 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
23802380
if (getLangOpts().CPlusPlus23) {
23812381
auto &LastRecord = Actions.ExprEvalContexts.back();
23822382
LastRecord.InLifetimeExtendingContext = true;
2383-
2384-
// Materialize non-`cv void` prvalue temporaries in discarded
2385-
// expressions. These materialized temporaries may be lifetime-extented.
2386-
LastRecord.InMaterializeTemporaryObjectContext = true;
23872383
}
23882384

23892385
if (getLangOpts().OpenMP)

clang/lib/Sema/SemaExpr.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6314,7 +6314,6 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
63146314
// Pass down lifetime extending flag, and collect temporaries in
63156315
// CreateMaterializeTemporaryExpr when we rewrite the call argument.
63166316
keepInLifetimeExtendingContext();
6317-
keepInMaterializeTemporaryObjectContext();
63186317
EnsureImmediateInvocationInDefaultArgs Immediate(*this);
63196318
ExprResult Res;
63206319
runWithSufficientStackSpace(CallLoc, [&] {
@@ -18679,9 +18678,9 @@ void Sema::PopExpressionEvaluationContext() {
1867918678
// Append the collected materialized temporaries into previous context before
1868018679
// exit if the previous also is a lifetime extending context.
1868118680
auto &PrevRecord = ExprEvalContexts[ExprEvalContexts.size() - 2];
18682-
if (getLangOpts().CPlusPlus23 && isInLifetimeExtendingContext() &&
18683-
PrevRecord.InLifetimeExtendingContext && !ExprEvalContexts.empty()) {
18684-
auto &PrevRecord = ExprEvalContexts[ExprEvalContexts.size() - 2];
18681+
if (getLangOpts().CPlusPlus23 && Rec.InLifetimeExtendingContext &&
18682+
PrevRecord.InLifetimeExtendingContext &&
18683+
!Rec.ForRangeLifetimeExtendTemps.empty()) {
1868518684
PrevRecord.ForRangeLifetimeExtendTemps.append(
1868618685
Rec.ForRangeLifetimeExtendTemps);
1868718686
}

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8429,7 +8429,7 @@ ExprResult Sema::IgnoredValueConversions(Expr *E) {
84298429
// unnecessary temporary objects. If we skip this step, IR generation is
84308430
// able to synthesize the storage for itself in the aggregate case, and
84318431
// adding the extra node to the AST is just clutter.
8432-
if (isInMaterializeTemporaryObjectContext() && getLangOpts().CPlusPlus17 &&
8432+
if (isInLifetimeExtendingContext() && getLangOpts().CPlusPlus17 &&
84338433
E->isPRValue() && !E->getType()->isVoidType()) {
84348434
ExprResult Res = TemporaryMaterializationConversion(E);
84358435
if (Res.isInvalid())

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5483,7 +5483,6 @@ void Sema::InstantiateVariableInitializer(
54835483
*this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, Var);
54845484

54855485
keepInLifetimeExtendingContext();
5486-
keepInMaterializeTemporaryObjectContext();
54875486
// Instantiate the initializer.
54885487
ExprResult Init;
54895488

clang/lib/Sema/TreeTransform.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4177,7 +4177,6 @@ ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
41774177
getSema(), EnterExpressionEvaluationContext::InitList,
41784178
Construct->isListInitialization());
41794179

4180-
getSema().keepInLifetimeExtendingContext();
41814180
getSema().keepInLifetimeExtendingContext();
41824181
SmallVector<Expr*, 8> NewArgs;
41834182
bool ArgChanged = false;
@@ -8752,10 +8751,6 @@ TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
87528751
if (getSema().getLangOpts().CPlusPlus23) {
87538752
auto &LastRecord = getSema().ExprEvalContexts.back();
87548753
LastRecord.InLifetimeExtendingContext = true;
8755-
8756-
// Materialize non-`cv void` prvalue temporaries in discarded
8757-
// expressions. These materialized temporaries may be lifetime-extented.
8758-
LastRecord.InMaterializeTemporaryObjectContext = true;
87598754
}
87608755
StmtResult Init =
87618756
S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();

0 commit comments

Comments
 (0)