[clang] [Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer (PR #87933)
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Fri May 3 16:17:30 PDT 2024
================
@@ -711,6 +711,26 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
if (VerifyOnly)
return;
+ // Enter a lifetime extension context, then we can support lifetime
+ // extension of temporary created by aggregate initialization using a
+ // default member initializer (DR1815 https://wg21.link/CWG1815).
+ //
+ // In a lifetime extension context, BuildCXXDefaultInitExpr will clone the
+ // initializer expression on each use that would lifetime extend its
+ // temporaries.
+ EnterExpressionEvaluationContext LifetimeExtensionContext(
+ SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
+ /*LambdaContextDecl=*/nullptr,
+ Sema::ExpressionEvaluationContextRecord::EK_Other, true);
+
+ // Lifetime extension in default-member-init.
+ auto &LastRecord = SemaRef.ExprEvalContexts.back();
+
+ // Just copy previous record, make sure we haven't forget anything.
+ LastRecord =
+ SemaRef.ExprEvalContexts[SemaRef.ExprEvalContexts.size() - 2];
+ LastRecord.InLifetimeExtendingContext = true;
----------------
zygoloid wrote:
This doesn't look right -- this would lifetime-extend *all* temporaries in the initializer. Only those that are actually bound to a reference member should be extended here.
Perhaps instead of these changes involving `InLifetimeExtendedContext`, you could change `BuildCXXDefaultInitExpr` to always rebuild the initializer if it contains any temporaries (if the initializer expression is an `ExprWithCleanups`). Then make sure the normal lifetime extension code recurses into the default initializer and does lifetime extension when warranted.
https://github.com/llvm/llvm-project/pull/87933
More information about the cfe-commits
mailing list