[clang] Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (PR #97308)
Shafik Yaghmour via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 5 14:02:35 PDT 2024
================
@@ -5578,19 +5579,35 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) {
ImmediateCallVisitor V(getASTContext());
if (!NestedDefaultChecking)
V.TraverseDecl(Field);
- if (V.HasImmediateCalls) {
+
+ // CWG1815
+ // Support lifetime extension of temporary created by aggregate
+ // initialization using a default member initializer. We should always rebuild
+ // the initializer in a lifetime extension context (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.
+ bool ContainsAnyTemporaries =
+ isa_and_present<ExprWithCleanups>(Field->getInClassInitializer());
+ if (Field->getInClassInitializer() &&
+ !Field->getInClassInitializer()->containsErrors() &&
+ (V.HasImmediateCalls ||
+ (InLifetimeExtendingContext && ContainsAnyTemporaries))) {
ExprEvalContexts.back().DelayedDefaultInitializationContext = {Loc, Field,
CurContext};
ExprEvalContexts.back().IsCurrentlyCheckingDefaultArgumentOrInitializer =
NestedDefaultChecking;
-
+ // Pass down lifetime extending flag, and collect temporaries in
+ // CreateMaterializeTemporaryExpr when we rewrite the call argument.
+ keepInLifetimeExtendingContext();
EnsureImmediateInvocationInDefaultArgs Immediate(*this);
ExprResult Res;
+
runWithSufficientStackSpace(Loc, [&] {
Res = Immediate.TransformInitializer(Field->getInClassInitializer(),
/*CXXDirectInit=*/false);
});
- if (!Res.isInvalid())
+ if (Res.isUsable())
----------------
shafik wrote:
Can you explain what cases this makes a difference in?
https://github.com/llvm/llvm-project/pull/97308
More information about the cfe-commits
mailing list