xref: /freebsd/contrib/llvm-project/clang/lib/Sema/CheckExprLifetime.cpp (revision 52418fc2be8efa5172b90a3a9e617017173612c4)
1 //===--- CheckExprLifetime.cpp --------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "CheckExprLifetime.h"
10 #include "clang/AST/Decl.h"
11 #include "clang/AST/Expr.h"
12 #include "clang/Basic/DiagnosticSema.h"
13 #include "clang/Sema/Initialization.h"
14 #include "clang/Sema/Sema.h"
15 #include "llvm/ADT/PointerIntPair.h"
16 
17 namespace clang::sema {
18 namespace {
19 enum LifetimeKind {
20   /// The lifetime of a temporary bound to this entity ends at the end of the
21   /// full-expression, and that's (probably) fine.
22   LK_FullExpression,
23 
24   /// The lifetime of a temporary bound to this entity is extended to the
25   /// lifeitme of the entity itself.
26   LK_Extended,
27 
28   /// The lifetime of a temporary bound to this entity probably ends too soon,
29   /// because the entity is allocated in a new-expression.
30   LK_New,
31 
32   /// The lifetime of a temporary bound to this entity ends too soon, because
33   /// the entity is a return object.
34   LK_Return,
35 
36   /// The lifetime of a temporary bound to this entity ends too soon, because
37   /// the entity is the result of a statement expression.
38   LK_StmtExprResult,
39 
40   /// This is a mem-initializer: if it would extend a temporary (other than via
41   /// a default member initializer), the program is ill-formed.
42   LK_MemInitializer,
43 
44   /// The lifetime of a temporary bound to this entity probably ends too soon,
45   /// because the entity is a pointer and we assign the address of a temporary
46   /// object to it.
47   LK_Assignment,
48 };
49 using LifetimeResult =
50     llvm::PointerIntPair<const InitializedEntity *, 3, LifetimeKind>;
51 } // namespace
52 
53 /// Determine the declaration which an initialized entity ultimately refers to,
54 /// for the purpose of lifetime-extending a temporary bound to a reference in
55 /// the initialization of \p Entity.
56 static LifetimeResult
getEntityLifetime(const InitializedEntity * Entity,const InitializedEntity * InitField=nullptr)57 getEntityLifetime(const InitializedEntity *Entity,
58                   const InitializedEntity *InitField = nullptr) {
59   // C++11 [class.temporary]p5:
60   switch (Entity->getKind()) {
61   case InitializedEntity::EK_Variable:
62     //   The temporary [...] persists for the lifetime of the reference
63     return {Entity, LK_Extended};
64 
65   case InitializedEntity::EK_Member:
66     // For subobjects, we look at the complete object.
67     if (Entity->getParent())
68       return getEntityLifetime(Entity->getParent(), Entity);
69 
70     //   except:
71     // C++17 [class.base.init]p8:
72     //   A temporary expression bound to a reference member in a
73     //   mem-initializer is ill-formed.
74     // C++17 [class.base.init]p11:
75     //   A temporary expression bound to a reference member from a
76     //   default member initializer is ill-formed.
77     //
78     // The context of p11 and its example suggest that it's only the use of a
79     // default member initializer from a constructor that makes the program
80     // ill-formed, not its mere existence, and that it can even be used by
81     // aggregate initialization.
82     return {Entity, Entity->isDefaultMemberInitializer() ? LK_Extended
83                                                          : LK_MemInitializer};
84 
85   case InitializedEntity::EK_Binding:
86     // Per [dcl.decomp]p3, the binding is treated as a variable of reference
87     // type.
88     return {Entity, LK_Extended};
89 
90   case InitializedEntity::EK_Parameter:
91   case InitializedEntity::EK_Parameter_CF_Audited:
92     //   -- A temporary bound to a reference parameter in a function call
93     //      persists until the completion of the full-expression containing
94     //      the call.
95     return {nullptr, LK_FullExpression};
96 
97   case InitializedEntity::EK_TemplateParameter:
98     // FIXME: This will always be ill-formed; should we eagerly diagnose it
99     // here?
100     return {nullptr, LK_FullExpression};
101 
102   case InitializedEntity::EK_Result:
103     //   -- The lifetime of a temporary bound to the returned value in a
104     //      function return statement is not extended; the temporary is
105     //      destroyed at the end of the full-expression in the return statement.
106     return {nullptr, LK_Return};
107 
108   case InitializedEntity::EK_StmtExprResult:
109     // FIXME: Should we lifetime-extend through the result of a statement
110     // expression?
111     return {nullptr, LK_StmtExprResult};
112 
113   case InitializedEntity::EK_New:
114     //   -- A temporary bound to a reference in a new-initializer persists
115     //      until the completion of the full-expression containing the
116     //      new-initializer.
117     return {nullptr, LK_New};
118 
119   case InitializedEntity::EK_Temporary:
120   case InitializedEntity::EK_CompoundLiteralInit:
121   case InitializedEntity::EK_RelatedResult:
122     // We don't yet know the storage duration of the surrounding temporary.
123     // Assume it's got full-expression duration for now, it will patch up our
124     // storage duration if that's not correct.
125     return {nullptr, LK_FullExpression};
126 
127   case InitializedEntity::EK_ArrayElement:
128     // For subobjects, we look at the complete object.
129     return getEntityLifetime(Entity->getParent(), InitField);
130 
131   case InitializedEntity::EK_Base:
132     // For subobjects, we look at the complete object.
133     if (Entity->getParent())
134       return getEntityLifetime(Entity->getParent(), InitField);
135     return {InitField, LK_MemInitializer};
136 
137   case InitializedEntity::EK_Delegating:
138     // We can reach this case for aggregate initialization in a constructor:
139     //   struct A { int &&r; };
140     //   struct B : A { B() : A{0} {} };
141     // In this case, use the outermost field decl as the context.
142     return {InitField, LK_MemInitializer};
143 
144   case InitializedEntity::EK_BlockElement:
145   case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
146   case InitializedEntity::EK_LambdaCapture:
147   case InitializedEntity::EK_VectorElement:
148   case InitializedEntity::EK_ComplexElement:
149     return {nullptr, LK_FullExpression};
150 
151   case InitializedEntity::EK_Exception:
152     // FIXME: Can we diagnose lifetime problems with exceptions?
153     return {nullptr, LK_FullExpression};
154 
155   case InitializedEntity::EK_ParenAggInitMember:
156     //   -- A temporary object bound to a reference element of an aggregate of
157     //      class type initialized from a parenthesized expression-list
158     //      [dcl.init, 9.3] persists until the completion of the full-expression
159     //      containing the expression-list.
160     return {nullptr, LK_FullExpression};
161   }
162 
163   llvm_unreachable("unknown entity kind");
164 }
165 
166 namespace {
167 enum ReferenceKind {
168   /// Lifetime would be extended by a reference binding to a temporary.
169   RK_ReferenceBinding,
170   /// Lifetime would be extended by a std::initializer_list object binding to
171   /// its backing array.
172   RK_StdInitializerList,
173 };
174 
175 /// A temporary or local variable. This will be one of:
176 ///  * A MaterializeTemporaryExpr.
177 ///  * A DeclRefExpr whose declaration is a local.
178 ///  * An AddrLabelExpr.
179 ///  * A BlockExpr for a block with captures.
180 using Local = Expr *;
181 
182 /// Expressions we stepped over when looking for the local state. Any steps
183 /// that would inhibit lifetime extension or take us out of subexpressions of
184 /// the initializer are included.
185 struct IndirectLocalPathEntry {
186   enum EntryKind {
187     DefaultInit,
188     AddressOf,
189     VarInit,
190     LValToRVal,
191     LifetimeBoundCall,
192     TemporaryCopy,
193     LambdaCaptureInit,
194     GslReferenceInit,
195     GslPointerInit,
196     GslPointerAssignment,
197   } Kind;
198   Expr *E;
199   union {
200     const Decl *D = nullptr;
201     const LambdaCapture *Capture;
202   };
IndirectLocalPathEntryclang::sema::__anone4608efb0211::IndirectLocalPathEntry203   IndirectLocalPathEntry() {}
IndirectLocalPathEntryclang::sema::__anone4608efb0211::IndirectLocalPathEntry204   IndirectLocalPathEntry(EntryKind K, Expr *E) : Kind(K), E(E) {}
IndirectLocalPathEntryclang::sema::__anone4608efb0211::IndirectLocalPathEntry205   IndirectLocalPathEntry(EntryKind K, Expr *E, const Decl *D)
206       : Kind(K), E(E), D(D) {}
IndirectLocalPathEntryclang::sema::__anone4608efb0211::IndirectLocalPathEntry207   IndirectLocalPathEntry(EntryKind K, Expr *E, const LambdaCapture *Capture)
208       : Kind(K), E(E), Capture(Capture) {}
209 };
210 
211 using IndirectLocalPath = llvm::SmallVectorImpl<IndirectLocalPathEntry>;
212 
213 struct RevertToOldSizeRAII {
214   IndirectLocalPath &Path;
215   unsigned OldSize = Path.size();
RevertToOldSizeRAIIclang::sema::__anone4608efb0211::RevertToOldSizeRAII216   RevertToOldSizeRAII(IndirectLocalPath &Path) : Path(Path) {}
~RevertToOldSizeRAIIclang::sema::__anone4608efb0211::RevertToOldSizeRAII217   ~RevertToOldSizeRAII() { Path.resize(OldSize); }
218 };
219 
220 using LocalVisitor = llvm::function_ref<bool(IndirectLocalPath &Path, Local L,
221                                              ReferenceKind RK)>;
222 } // namespace
223 
isVarOnPath(IndirectLocalPath & Path,VarDecl * VD)224 static bool isVarOnPath(IndirectLocalPath &Path, VarDecl *VD) {
225   for (auto E : Path)
226     if (E.Kind == IndirectLocalPathEntry::VarInit && E.D == VD)
227       return true;
228   return false;
229 }
230 
pathContainsInit(IndirectLocalPath & Path)231 static bool pathContainsInit(IndirectLocalPath &Path) {
232   return llvm::any_of(Path, [=](IndirectLocalPathEntry E) {
233     return E.Kind == IndirectLocalPathEntry::DefaultInit ||
234            E.Kind == IndirectLocalPathEntry::VarInit;
235   });
236 }
237 
238 static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
239                                              Expr *Init, LocalVisitor Visit,
240                                              bool RevisitSubinits,
241                                              bool EnableLifetimeWarnings);
242 
243 static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
244                                                   Expr *Init, ReferenceKind RK,
245                                                   LocalVisitor Visit,
246                                                   bool EnableLifetimeWarnings);
247 
isRecordWithAttr(QualType Type)248 template <typename T> static bool isRecordWithAttr(QualType Type) {
249   if (auto *RD = Type->getAsCXXRecordDecl())
250     return RD->hasAttr<T>();
251   return false;
252 }
253 
254 // Decl::isInStdNamespace will return false for iterators in some STL
255 // implementations due to them being defined in a namespace outside of the std
256 // namespace.
isInStlNamespace(const Decl * D)257 static bool isInStlNamespace(const Decl *D) {
258   const DeclContext *DC = D->getDeclContext();
259   if (!DC)
260     return false;
261   if (const auto *ND = dyn_cast<NamespaceDecl>(DC))
262     if (const IdentifierInfo *II = ND->getIdentifier()) {
263       StringRef Name = II->getName();
264       if (Name.size() >= 2 && Name.front() == '_' &&
265           (Name[1] == '_' || isUppercase(Name[1])))
266         return true;
267     }
268 
269   return DC->isStdNamespace();
270 }
271 
shouldTrackImplicitObjectArg(const CXXMethodDecl * Callee)272 static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
273   if (auto *Conv = dyn_cast_or_null<CXXConversionDecl>(Callee))
274     if (isRecordWithAttr<PointerAttr>(Conv->getConversionType()))
275       return true;
276   if (!isInStlNamespace(Callee->getParent()))
277     return false;
278   if (!isRecordWithAttr<PointerAttr>(
279           Callee->getFunctionObjectParameterType()) &&
280       !isRecordWithAttr<OwnerAttr>(Callee->getFunctionObjectParameterType()))
281     return false;
282   if (Callee->getReturnType()->isPointerType() ||
283       isRecordWithAttr<PointerAttr>(Callee->getReturnType())) {
284     if (!Callee->getIdentifier())
285       return false;
286     return llvm::StringSwitch<bool>(Callee->getName())
287         .Cases("begin", "rbegin", "cbegin", "crbegin", true)
288         .Cases("end", "rend", "cend", "crend", true)
289         .Cases("c_str", "data", "get", true)
290         // Map and set types.
291         .Cases("find", "equal_range", "lower_bound", "upper_bound", true)
292         .Default(false);
293   } else if (Callee->getReturnType()->isReferenceType()) {
294     if (!Callee->getIdentifier()) {
295       auto OO = Callee->getOverloadedOperator();
296       return OO == OverloadedOperatorKind::OO_Subscript ||
297              OO == OverloadedOperatorKind::OO_Star;
298     }
299     return llvm::StringSwitch<bool>(Callee->getName())
300         .Cases("front", "back", "at", "top", "value", true)
301         .Default(false);
302   }
303   return false;
304 }
305 
shouldTrackFirstArgument(const FunctionDecl * FD)306 static bool shouldTrackFirstArgument(const FunctionDecl *FD) {
307   if (!FD->getIdentifier() || FD->getNumParams() != 1)
308     return false;
309   const auto *RD = FD->getParamDecl(0)->getType()->getPointeeCXXRecordDecl();
310   if (!FD->isInStdNamespace() || !RD || !RD->isInStdNamespace())
311     return false;
312   if (!RD->hasAttr<PointerAttr>() && !RD->hasAttr<OwnerAttr>())
313     return false;
314   if (FD->getReturnType()->isPointerType() ||
315       isRecordWithAttr<PointerAttr>(FD->getReturnType())) {
316     return llvm::StringSwitch<bool>(FD->getName())
317         .Cases("begin", "rbegin", "cbegin", "crbegin", true)
318         .Cases("end", "rend", "cend", "crend", true)
319         .Case("data", true)
320         .Default(false);
321   } else if (FD->getReturnType()->isReferenceType()) {
322     return llvm::StringSwitch<bool>(FD->getName())
323         .Cases("get", "any_cast", true)
324         .Default(false);
325   }
326   return false;
327 }
328 
handleGslAnnotatedTypes(IndirectLocalPath & Path,Expr * Call,LocalVisitor Visit)329 static void handleGslAnnotatedTypes(IndirectLocalPath &Path, Expr *Call,
330                                     LocalVisitor Visit) {
331   auto VisitPointerArg = [&](const Decl *D, Expr *Arg, bool Value) {
332     // We are not interested in the temporary base objects of gsl Pointers:
333     //   Temp().ptr; // Here ptr might not dangle.
334     if (isa<MemberExpr>(Arg->IgnoreImpCasts()))
335       return;
336     // Once we initialized a value with a reference, it can no longer dangle.
337     if (!Value) {
338       for (const IndirectLocalPathEntry &PE : llvm::reverse(Path)) {
339         if (PE.Kind == IndirectLocalPathEntry::GslReferenceInit)
340           continue;
341         if (PE.Kind == IndirectLocalPathEntry::GslPointerInit ||
342             PE.Kind == IndirectLocalPathEntry::GslPointerAssignment)
343           return;
344         break;
345       }
346     }
347     Path.push_back({Value ? IndirectLocalPathEntry::GslPointerInit
348                           : IndirectLocalPathEntry::GslReferenceInit,
349                     Arg, D});
350     if (Arg->isGLValue())
351       visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding,
352                                             Visit,
353                                             /*EnableLifetimeWarnings=*/true);
354     else
355       visitLocalsRetainedByInitializer(Path, Arg, Visit, true,
356                                        /*EnableLifetimeWarnings=*/true);
357     Path.pop_back();
358   };
359 
360   if (auto *MCE = dyn_cast<CXXMemberCallExpr>(Call)) {
361     const auto *MD = cast_or_null<CXXMethodDecl>(MCE->getDirectCallee());
362     if (MD && shouldTrackImplicitObjectArg(MD))
363       VisitPointerArg(MD, MCE->getImplicitObjectArgument(),
364                       !MD->getReturnType()->isReferenceType());
365     return;
366   } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(Call)) {
367     FunctionDecl *Callee = OCE->getDirectCallee();
368     if (Callee && Callee->isCXXInstanceMember() &&
369         shouldTrackImplicitObjectArg(cast<CXXMethodDecl>(Callee)))
370       VisitPointerArg(Callee, OCE->getArg(0),
371                       !Callee->getReturnType()->isReferenceType());
372     return;
373   } else if (auto *CE = dyn_cast<CallExpr>(Call)) {
374     FunctionDecl *Callee = CE->getDirectCallee();
375     if (Callee && shouldTrackFirstArgument(Callee))
376       VisitPointerArg(Callee, CE->getArg(0),
377                       !Callee->getReturnType()->isReferenceType());
378     return;
379   }
380 
381   if (auto *CCE = dyn_cast<CXXConstructExpr>(Call)) {
382     const auto *Ctor = CCE->getConstructor();
383     const CXXRecordDecl *RD = Ctor->getParent();
384     if (CCE->getNumArgs() > 0 && RD->hasAttr<PointerAttr>())
385       VisitPointerArg(Ctor->getParamDecl(0), CCE->getArgs()[0], true);
386   }
387 }
388 
implicitObjectParamIsLifetimeBound(const FunctionDecl * FD)389 static bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) {
390   const TypeSourceInfo *TSI = FD->getTypeSourceInfo();
391   if (!TSI)
392     return false;
393   // Don't declare this variable in the second operand of the for-statement;
394   // GCC miscompiles that by ending its lifetime before evaluating the
395   // third operand. See gcc.gnu.org/PR86769.
396   AttributedTypeLoc ATL;
397   for (TypeLoc TL = TSI->getTypeLoc();
398        (ATL = TL.getAsAdjusted<AttributedTypeLoc>());
399        TL = ATL.getModifiedLoc()) {
400     if (ATL.getAttrAs<LifetimeBoundAttr>())
401       return true;
402   }
403 
404   // Assume that all assignment operators with a "normal" return type return
405   // *this, that is, an lvalue reference that is the same type as the implicit
406   // object parameter (or the LHS for a non-member operator$=).
407   OverloadedOperatorKind OO = FD->getDeclName().getCXXOverloadedOperator();
408   if (OO == OO_Equal || isCompoundAssignmentOperator(OO)) {
409     QualType RetT = FD->getReturnType();
410     if (RetT->isLValueReferenceType()) {
411       ASTContext &Ctx = FD->getASTContext();
412       QualType LHST;
413       auto *MD = dyn_cast<CXXMethodDecl>(FD);
414       if (MD && MD->isCXXInstanceMember())
415         LHST = Ctx.getLValueReferenceType(MD->getFunctionObjectParameterType());
416       else
417         LHST = MD->getParamDecl(0)->getType();
418       if (Ctx.hasSameType(RetT, LHST))
419         return true;
420     }
421   }
422 
423   return false;
424 }
425 
visitLifetimeBoundArguments(IndirectLocalPath & Path,Expr * Call,LocalVisitor Visit)426 static void visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
427                                         LocalVisitor Visit) {
428   const FunctionDecl *Callee;
429   ArrayRef<Expr *> Args;
430 
431   if (auto *CE = dyn_cast<CallExpr>(Call)) {
432     Callee = CE->getDirectCallee();
433     Args = llvm::ArrayRef(CE->getArgs(), CE->getNumArgs());
434   } else {
435     auto *CCE = cast<CXXConstructExpr>(Call);
436     Callee = CCE->getConstructor();
437     Args = llvm::ArrayRef(CCE->getArgs(), CCE->getNumArgs());
438   }
439   if (!Callee)
440     return;
441 
442   Expr *ObjectArg = nullptr;
443   if (isa<CXXOperatorCallExpr>(Call) && Callee->isCXXInstanceMember()) {
444     ObjectArg = Args[0];
445     Args = Args.slice(1);
446   } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(Call)) {
447     ObjectArg = MCE->getImplicitObjectArgument();
448   }
449 
450   auto VisitLifetimeBoundArg = [&](const Decl *D, Expr *Arg) {
451     Path.push_back({IndirectLocalPathEntry::LifetimeBoundCall, Arg, D});
452     if (Arg->isGLValue())
453       visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding,
454                                             Visit,
455                                             /*EnableLifetimeWarnings=*/false);
456     else
457       visitLocalsRetainedByInitializer(Path, Arg, Visit, true,
458                                        /*EnableLifetimeWarnings=*/false);
459     Path.pop_back();
460   };
461 
462   bool CheckCoroCall = false;
463   if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
464     CheckCoroCall = RD->hasAttr<CoroLifetimeBoundAttr>() &&
465                     RD->hasAttr<CoroReturnTypeAttr>() &&
466                     !Callee->hasAttr<CoroDisableLifetimeBoundAttr>();
467   }
468 
469   if (ObjectArg) {
470     bool CheckCoroObjArg = CheckCoroCall;
471     // Coroutine lambda objects with empty capture list are not lifetimebound.
472     if (auto *LE = dyn_cast<LambdaExpr>(ObjectArg->IgnoreImplicit());
473         LE && LE->captures().empty())
474       CheckCoroObjArg = false;
475     // Allow `get_return_object()` as the object param (__promise) is not
476     // lifetimebound.
477     if (Sema::CanBeGetReturnObject(Callee))
478       CheckCoroObjArg = false;
479     if (implicitObjectParamIsLifetimeBound(Callee) || CheckCoroObjArg)
480       VisitLifetimeBoundArg(Callee, ObjectArg);
481   }
482 
483   for (unsigned I = 0,
484                 N = std::min<unsigned>(Callee->getNumParams(), Args.size());
485        I != N; ++I) {
486     if (CheckCoroCall || Callee->getParamDecl(I)->hasAttr<LifetimeBoundAttr>())
487       VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
488   }
489 }
490 
491 /// Visit the locals that would be reachable through a reference bound to the
492 /// glvalue expression \c Init.
visitLocalsRetainedByReferenceBinding(IndirectLocalPath & Path,Expr * Init,ReferenceKind RK,LocalVisitor Visit,bool EnableLifetimeWarnings)493 static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
494                                                   Expr *Init, ReferenceKind RK,
495                                                   LocalVisitor Visit,
496                                                   bool EnableLifetimeWarnings) {
497   RevertToOldSizeRAII RAII(Path);
498 
499   // Walk past any constructs which we can lifetime-extend across.
500   Expr *Old;
501   do {
502     Old = Init;
503 
504     if (auto *FE = dyn_cast<FullExpr>(Init))
505       Init = FE->getSubExpr();
506 
507     if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
508       // If this is just redundant braces around an initializer, step over it.
509       if (ILE->isTransparent())
510         Init = ILE->getInit(0);
511     }
512 
513     // Step over any subobject adjustments; we may have a materialized
514     // temporary inside them.
515     Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments());
516 
517     // Per current approach for DR1376, look through casts to reference type
518     // when performing lifetime extension.
519     if (CastExpr *CE = dyn_cast<CastExpr>(Init))
520       if (CE->getSubExpr()->isGLValue())
521         Init = CE->getSubExpr();
522 
523     // Per the current approach for DR1299, look through array element access
524     // on array glvalues when performing lifetime extension.
525     if (auto *ASE = dyn_cast<ArraySubscriptExpr>(Init)) {
526       Init = ASE->getBase();
527       auto *ICE = dyn_cast<ImplicitCastExpr>(Init);
528       if (ICE && ICE->getCastKind() == CK_ArrayToPointerDecay)
529         Init = ICE->getSubExpr();
530       else
531         // We can't lifetime extend through this but we might still find some
532         // retained temporaries.
533         return visitLocalsRetainedByInitializer(Path, Init, Visit, true,
534                                                 EnableLifetimeWarnings);
535     }
536 
537     // Step into CXXDefaultInitExprs so we can diagnose cases where a
538     // constructor inherits one as an implicit mem-initializer.
539     if (auto *DIE = dyn_cast<CXXDefaultInitExpr>(Init)) {
540       Path.push_back(
541           {IndirectLocalPathEntry::DefaultInit, DIE, DIE->getField()});
542       Init = DIE->getExpr();
543     }
544   } while (Init != Old);
545 
546   if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Init)) {
547     if (Visit(Path, Local(MTE), RK))
548       visitLocalsRetainedByInitializer(Path, MTE->getSubExpr(), Visit, true,
549                                        EnableLifetimeWarnings);
550   }
551 
552   if (auto *M = dyn_cast<MemberExpr>(Init)) {
553     // Lifetime of a non-reference type field is same as base object.
554     if (auto *F = dyn_cast<FieldDecl>(M->getMemberDecl());
555         F && !F->getType()->isReferenceType())
556       visitLocalsRetainedByInitializer(Path, M->getBase(), Visit, true,
557                                        EnableLifetimeWarnings);
558   }
559 
560   if (isa<CallExpr>(Init)) {
561     if (EnableLifetimeWarnings)
562       handleGslAnnotatedTypes(Path, Init, Visit);
563     return visitLifetimeBoundArguments(Path, Init, Visit);
564   }
565 
566   switch (Init->getStmtClass()) {
567   case Stmt::DeclRefExprClass: {
568     // If we find the name of a local non-reference parameter, we could have a
569     // lifetime problem.
570     auto *DRE = cast<DeclRefExpr>(Init);
571     auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
572     if (VD && VD->hasLocalStorage() &&
573         !DRE->refersToEnclosingVariableOrCapture()) {
574       if (!VD->getType()->isReferenceType()) {
575         Visit(Path, Local(DRE), RK);
576       } else if (isa<ParmVarDecl>(DRE->getDecl())) {
577         // The lifetime of a reference parameter is unknown; assume it's OK
578         // for now.
579         break;
580       } else if (VD->getInit() && !isVarOnPath(Path, VD)) {
581         Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
582         visitLocalsRetainedByReferenceBinding(Path, VD->getInit(),
583                                               RK_ReferenceBinding, Visit,
584                                               EnableLifetimeWarnings);
585       }
586     }
587     break;
588   }
589 
590   case Stmt::UnaryOperatorClass: {
591     // The only unary operator that make sense to handle here
592     // is Deref.  All others don't resolve to a "name."  This includes
593     // handling all sorts of rvalues passed to a unary operator.
594     const UnaryOperator *U = cast<UnaryOperator>(Init);
595     if (U->getOpcode() == UO_Deref)
596       visitLocalsRetainedByInitializer(Path, U->getSubExpr(), Visit, true,
597                                        EnableLifetimeWarnings);
598     break;
599   }
600 
601   case Stmt::ArraySectionExprClass: {
602     visitLocalsRetainedByInitializer(Path,
603                                      cast<ArraySectionExpr>(Init)->getBase(),
604                                      Visit, true, EnableLifetimeWarnings);
605     break;
606   }
607 
608   case Stmt::ConditionalOperatorClass:
609   case Stmt::BinaryConditionalOperatorClass: {
610     auto *C = cast<AbstractConditionalOperator>(Init);
611     if (!C->getTrueExpr()->getType()->isVoidType())
612       visitLocalsRetainedByReferenceBinding(Path, C->getTrueExpr(), RK, Visit,
613                                             EnableLifetimeWarnings);
614     if (!C->getFalseExpr()->getType()->isVoidType())
615       visitLocalsRetainedByReferenceBinding(Path, C->getFalseExpr(), RK, Visit,
616                                             EnableLifetimeWarnings);
617     break;
618   }
619 
620   case Stmt::CompoundLiteralExprClass: {
621     if (auto *CLE = dyn_cast<CompoundLiteralExpr>(Init)) {
622       if (!CLE->isFileScope())
623         Visit(Path, Local(CLE), RK);
624     }
625     break;
626   }
627 
628     // FIXME: Visit the left-hand side of an -> or ->*.
629 
630   default:
631     break;
632   }
633 }
634 
635 /// Visit the locals that would be reachable through an object initialized by
636 /// the prvalue expression \c Init.
visitLocalsRetainedByInitializer(IndirectLocalPath & Path,Expr * Init,LocalVisitor Visit,bool RevisitSubinits,bool EnableLifetimeWarnings)637 static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
638                                              Expr *Init, LocalVisitor Visit,
639                                              bool RevisitSubinits,
640                                              bool EnableLifetimeWarnings) {
641   RevertToOldSizeRAII RAII(Path);
642 
643   Expr *Old;
644   do {
645     Old = Init;
646 
647     // Step into CXXDefaultInitExprs so we can diagnose cases where a
648     // constructor inherits one as an implicit mem-initializer.
649     if (auto *DIE = dyn_cast<CXXDefaultInitExpr>(Init)) {
650       Path.push_back(
651           {IndirectLocalPathEntry::DefaultInit, DIE, DIE->getField()});
652       Init = DIE->getExpr();
653     }
654 
655     if (auto *FE = dyn_cast<FullExpr>(Init))
656       Init = FE->getSubExpr();
657 
658     // Dig out the expression which constructs the extended temporary.
659     Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments());
660 
661     if (CXXBindTemporaryExpr *BTE = dyn_cast<CXXBindTemporaryExpr>(Init))
662       Init = BTE->getSubExpr();
663 
664     Init = Init->IgnoreParens();
665 
666     // Step over value-preserving rvalue casts.
667     if (auto *CE = dyn_cast<CastExpr>(Init)) {
668       switch (CE->getCastKind()) {
669       case CK_LValueToRValue:
670         // If we can match the lvalue to a const object, we can look at its
671         // initializer.
672         Path.push_back({IndirectLocalPathEntry::LValToRVal, CE});
673         return visitLocalsRetainedByReferenceBinding(
674             Path, Init, RK_ReferenceBinding,
675             [&](IndirectLocalPath &Path, Local L, ReferenceKind RK) -> bool {
676               if (auto *DRE = dyn_cast<DeclRefExpr>(L)) {
677                 auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
678                 if (VD && VD->getType().isConstQualified() && VD->getInit() &&
679                     !isVarOnPath(Path, VD)) {
680                   Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
681                   visitLocalsRetainedByInitializer(
682                       Path, VD->getInit(), Visit, true, EnableLifetimeWarnings);
683                 }
684               } else if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L)) {
685                 if (MTE->getType().isConstQualified())
686                   visitLocalsRetainedByInitializer(Path, MTE->getSubExpr(),
687                                                    Visit, true,
688                                                    EnableLifetimeWarnings);
689               }
690               return false;
691             },
692             EnableLifetimeWarnings);
693 
694         // We assume that objects can be retained by pointers cast to integers,
695         // but not if the integer is cast to floating-point type or to _Complex.
696         // We assume that casts to 'bool' do not preserve enough information to
697         // retain a local object.
698       case CK_NoOp:
699       case CK_BitCast:
700       case CK_BaseToDerived:
701       case CK_DerivedToBase:
702       case CK_UncheckedDerivedToBase:
703       case CK_Dynamic:
704       case CK_ToUnion:
705       case CK_UserDefinedConversion:
706       case CK_ConstructorConversion:
707       case CK_IntegralToPointer:
708       case CK_PointerToIntegral:
709       case CK_VectorSplat:
710       case CK_IntegralCast:
711       case CK_CPointerToObjCPointerCast:
712       case CK_BlockPointerToObjCPointerCast:
713       case CK_AnyPointerToBlockPointerCast:
714       case CK_AddressSpaceConversion:
715         break;
716 
717       case CK_ArrayToPointerDecay:
718         // Model array-to-pointer decay as taking the address of the array
719         // lvalue.
720         Path.push_back({IndirectLocalPathEntry::AddressOf, CE});
721         return visitLocalsRetainedByReferenceBinding(Path, CE->getSubExpr(),
722                                                      RK_ReferenceBinding, Visit,
723                                                      EnableLifetimeWarnings);
724 
725       default:
726         return;
727       }
728 
729       Init = CE->getSubExpr();
730     }
731   } while (Old != Init);
732 
733   // C++17 [dcl.init.list]p6:
734   //   initializing an initializer_list object from the array extends the
735   //   lifetime of the array exactly like binding a reference to a temporary.
736   if (auto *ILE = dyn_cast<CXXStdInitializerListExpr>(Init))
737     return visitLocalsRetainedByReferenceBinding(Path, ILE->getSubExpr(),
738                                                  RK_StdInitializerList, Visit,
739                                                  EnableLifetimeWarnings);
740 
741   if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
742     // We already visited the elements of this initializer list while
743     // performing the initialization. Don't visit them again unless we've
744     // changed the lifetime of the initialized entity.
745     if (!RevisitSubinits)
746       return;
747 
748     if (ILE->isTransparent())
749       return visitLocalsRetainedByInitializer(Path, ILE->getInit(0), Visit,
750                                               RevisitSubinits,
751                                               EnableLifetimeWarnings);
752 
753     if (ILE->getType()->isArrayType()) {
754       for (unsigned I = 0, N = ILE->getNumInits(); I != N; ++I)
755         visitLocalsRetainedByInitializer(Path, ILE->getInit(I), Visit,
756                                          RevisitSubinits,
757                                          EnableLifetimeWarnings);
758       return;
759     }
760 
761     if (CXXRecordDecl *RD = ILE->getType()->getAsCXXRecordDecl()) {
762       assert(RD->isAggregate() && "aggregate init on non-aggregate");
763 
764       // If we lifetime-extend a braced initializer which is initializing an
765       // aggregate, and that aggregate contains reference members which are
766       // bound to temporaries, those temporaries are also lifetime-extended.
767       if (RD->isUnion() && ILE->getInitializedFieldInUnion() &&
768           ILE->getInitializedFieldInUnion()->getType()->isReferenceType())
769         visitLocalsRetainedByReferenceBinding(Path, ILE->getInit(0),
770                                               RK_ReferenceBinding, Visit,
771                                               EnableLifetimeWarnings);
772       else {
773         unsigned Index = 0;
774         for (; Index < RD->getNumBases() && Index < ILE->getNumInits(); ++Index)
775           visitLocalsRetainedByInitializer(Path, ILE->getInit(Index), Visit,
776                                            RevisitSubinits,
777                                            EnableLifetimeWarnings);
778         for (const auto *I : RD->fields()) {
779           if (Index >= ILE->getNumInits())
780             break;
781           if (I->isUnnamedBitField())
782             continue;
783           Expr *SubInit = ILE->getInit(Index);
784           if (I->getType()->isReferenceType())
785             visitLocalsRetainedByReferenceBinding(Path, SubInit,
786                                                   RK_ReferenceBinding, Visit,
787                                                   EnableLifetimeWarnings);
788           else
789             // This might be either aggregate-initialization of a member or
790             // initialization of a std::initializer_list object. Regardless,
791             // we should recursively lifetime-extend that initializer.
792             visitLocalsRetainedByInitializer(
793                 Path, SubInit, Visit, RevisitSubinits, EnableLifetimeWarnings);
794           ++Index;
795         }
796       }
797     }
798     return;
799   }
800 
801   // The lifetime of an init-capture is that of the closure object constructed
802   // by a lambda-expression.
803   if (auto *LE = dyn_cast<LambdaExpr>(Init)) {
804     LambdaExpr::capture_iterator CapI = LE->capture_begin();
805     for (Expr *E : LE->capture_inits()) {
806       assert(CapI != LE->capture_end());
807       const LambdaCapture &Cap = *CapI++;
808       if (!E)
809         continue;
810       if (Cap.capturesVariable())
811         Path.push_back({IndirectLocalPathEntry::LambdaCaptureInit, E, &Cap});
812       if (E->isGLValue())
813         visitLocalsRetainedByReferenceBinding(Path, E, RK_ReferenceBinding,
814                                               Visit, EnableLifetimeWarnings);
815       else
816         visitLocalsRetainedByInitializer(Path, E, Visit, true,
817                                          EnableLifetimeWarnings);
818       if (Cap.capturesVariable())
819         Path.pop_back();
820     }
821   }
822 
823   // Assume that a copy or move from a temporary references the same objects
824   // that the temporary does.
825   if (auto *CCE = dyn_cast<CXXConstructExpr>(Init)) {
826     if (CCE->getConstructor()->isCopyOrMoveConstructor()) {
827       if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(CCE->getArg(0))) {
828         // assert(false && "hit temporary copy path");
829         Expr *Arg = MTE->getSubExpr();
830         Path.push_back({IndirectLocalPathEntry::TemporaryCopy, Arg,
831                         CCE->getConstructor()});
832         visitLocalsRetainedByInitializer(Path, Arg, Visit, true,
833                                          /*EnableLifetimeWarnings*/ false);
834         Path.pop_back();
835       }
836     }
837   }
838 
839   if (isa<CallExpr>(Init) || isa<CXXConstructExpr>(Init)) {
840     if (EnableLifetimeWarnings)
841       handleGslAnnotatedTypes(Path, Init, Visit);
842     return visitLifetimeBoundArguments(Path, Init, Visit);
843   }
844 
845   switch (Init->getStmtClass()) {
846   case Stmt::UnaryOperatorClass: {
847     auto *UO = cast<UnaryOperator>(Init);
848     // If the initializer is the address of a local, we could have a lifetime
849     // problem.
850     if (UO->getOpcode() == UO_AddrOf) {
851       // If this is &rvalue, then it's ill-formed and we have already diagnosed
852       // it. Don't produce a redundant warning about the lifetime of the
853       // temporary.
854       if (isa<MaterializeTemporaryExpr>(UO->getSubExpr()))
855         return;
856 
857       Path.push_back({IndirectLocalPathEntry::AddressOf, UO});
858       visitLocalsRetainedByReferenceBinding(Path, UO->getSubExpr(),
859                                             RK_ReferenceBinding, Visit,
860                                             EnableLifetimeWarnings);
861     }
862     break;
863   }
864 
865   case Stmt::BinaryOperatorClass: {
866     // Handle pointer arithmetic.
867     auto *BO = cast<BinaryOperator>(Init);
868     BinaryOperatorKind BOK = BO->getOpcode();
869     if (!BO->getType()->isPointerType() || (BOK != BO_Add && BOK != BO_Sub))
870       break;
871 
872     if (BO->getLHS()->getType()->isPointerType())
873       visitLocalsRetainedByInitializer(Path, BO->getLHS(), Visit, true,
874                                        EnableLifetimeWarnings);
875     else if (BO->getRHS()->getType()->isPointerType())
876       visitLocalsRetainedByInitializer(Path, BO->getRHS(), Visit, true,
877                                        EnableLifetimeWarnings);
878     break;
879   }
880 
881   case Stmt::ConditionalOperatorClass:
882   case Stmt::BinaryConditionalOperatorClass: {
883     auto *C = cast<AbstractConditionalOperator>(Init);
884     // In C++, we can have a throw-expression operand, which has 'void' type
885     // and isn't interesting from a lifetime perspective.
886     if (!C->getTrueExpr()->getType()->isVoidType())
887       visitLocalsRetainedByInitializer(Path, C->getTrueExpr(), Visit, true,
888                                        EnableLifetimeWarnings);
889     if (!C->getFalseExpr()->getType()->isVoidType())
890       visitLocalsRetainedByInitializer(Path, C->getFalseExpr(), Visit, true,
891                                        EnableLifetimeWarnings);
892     break;
893   }
894 
895   case Stmt::BlockExprClass:
896     if (cast<BlockExpr>(Init)->getBlockDecl()->hasCaptures()) {
897       // This is a local block, whose lifetime is that of the function.
898       Visit(Path, Local(cast<BlockExpr>(Init)), RK_ReferenceBinding);
899     }
900     break;
901 
902   case Stmt::AddrLabelExprClass:
903     // We want to warn if the address of a label would escape the function.
904     Visit(Path, Local(cast<AddrLabelExpr>(Init)), RK_ReferenceBinding);
905     break;
906 
907   default:
908     break;
909   }
910 }
911 
912 /// Whether a path to an object supports lifetime extension.
913 enum PathLifetimeKind {
914   /// Lifetime-extend along this path.
915   Extend,
916   /// We should lifetime-extend, but we don't because (due to technical
917   /// limitations) we can't. This happens for default member initializers,
918   /// which we don't clone for every use, so we don't have a unique
919   /// MaterializeTemporaryExpr to update.
920   ShouldExtend,
921   /// Do not lifetime extend along this path.
922   NoExtend
923 };
924 
925 /// Determine whether this is an indirect path to a temporary that we are
926 /// supposed to lifetime-extend along.
927 static PathLifetimeKind
shouldLifetimeExtendThroughPath(const IndirectLocalPath & Path)928 shouldLifetimeExtendThroughPath(const IndirectLocalPath &Path) {
929   PathLifetimeKind Kind = PathLifetimeKind::Extend;
930   for (auto Elem : Path) {
931     if (Elem.Kind == IndirectLocalPathEntry::DefaultInit)
932       Kind = PathLifetimeKind::ShouldExtend;
933     else if (Elem.Kind != IndirectLocalPathEntry::LambdaCaptureInit)
934       return PathLifetimeKind::NoExtend;
935   }
936   return Kind;
937 }
938 
939 /// Find the range for the first interesting entry in the path at or after I.
nextPathEntryRange(const IndirectLocalPath & Path,unsigned I,Expr * E)940 static SourceRange nextPathEntryRange(const IndirectLocalPath &Path, unsigned I,
941                                       Expr *E) {
942   for (unsigned N = Path.size(); I != N; ++I) {
943     switch (Path[I].Kind) {
944     case IndirectLocalPathEntry::AddressOf:
945     case IndirectLocalPathEntry::LValToRVal:
946     case IndirectLocalPathEntry::LifetimeBoundCall:
947     case IndirectLocalPathEntry::TemporaryCopy:
948     case IndirectLocalPathEntry::GslReferenceInit:
949     case IndirectLocalPathEntry::GslPointerInit:
950     case IndirectLocalPathEntry::GslPointerAssignment:
951       // These exist primarily to mark the path as not permitting or
952       // supporting lifetime extension.
953       break;
954 
955     case IndirectLocalPathEntry::VarInit:
956       if (cast<VarDecl>(Path[I].D)->isImplicit())
957         return SourceRange();
958       [[fallthrough]];
959     case IndirectLocalPathEntry::DefaultInit:
960       return Path[I].E->getSourceRange();
961 
962     case IndirectLocalPathEntry::LambdaCaptureInit:
963       if (!Path[I].Capture->capturesVariable())
964         continue;
965       return Path[I].E->getSourceRange();
966     }
967   }
968   return E->getSourceRange();
969 }
970 
pathOnlyHandlesGslPointer(IndirectLocalPath & Path)971 static bool pathOnlyHandlesGslPointer(IndirectLocalPath &Path) {
972   for (const auto &It : llvm::reverse(Path)) {
973     switch (It.Kind) {
974     case IndirectLocalPathEntry::VarInit:
975     case IndirectLocalPathEntry::AddressOf:
976     case IndirectLocalPathEntry::LifetimeBoundCall:
977       continue;
978     case IndirectLocalPathEntry::GslPointerInit:
979     case IndirectLocalPathEntry::GslReferenceInit:
980     case IndirectLocalPathEntry::GslPointerAssignment:
981       return true;
982     default:
983       return false;
984     }
985   }
986   return false;
987 }
988 
checkExprLifetimeImpl(Sema & SemaRef,const InitializedEntity * InitEntity,const InitializedEntity * ExtendingEntity,LifetimeKind LK,const AssignedEntity * AEntity,Expr * Init,bool EnableLifetimeWarnings)989 static void checkExprLifetimeImpl(Sema &SemaRef,
990                                   const InitializedEntity *InitEntity,
991                                   const InitializedEntity *ExtendingEntity,
992                                   LifetimeKind LK,
993                                   const AssignedEntity *AEntity, Expr *Init,
994                                   bool EnableLifetimeWarnings) {
995   assert((AEntity && LK == LK_Assignment) ||
996          (InitEntity && LK != LK_Assignment));
997   // If this entity doesn't have an interesting lifetime, don't bother looking
998   // for temporaries within its initializer.
999   if (LK == LK_FullExpression)
1000     return;
1001 
1002   // FIXME: consider moving the TemporaryVisitor and visitLocalsRetained*
1003   // functions to a dedicated class.
1004   auto TemporaryVisitor = [&](IndirectLocalPath &Path, Local L,
1005                               ReferenceKind RK) -> bool {
1006     SourceRange DiagRange = nextPathEntryRange(Path, 0, L);
1007     SourceLocation DiagLoc = DiagRange.getBegin();
1008 
1009     auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L);
1010 
1011     bool IsGslPtrValueFromGslTempOwner = false;
1012     bool IsLocalGslOwner = false;
1013     if (pathOnlyHandlesGslPointer(Path)) {
1014       if (isa<DeclRefExpr>(L)) {
1015         // We do not want to follow the references when returning a pointer
1016         // originating from a local owner to avoid the following false positive:
1017         //   int &p = *localUniquePtr;
1018         //   someContainer.add(std::move(localUniquePtr));
1019         //   return p;
1020         IsLocalGslOwner = isRecordWithAttr<OwnerAttr>(L->getType());
1021         if (pathContainsInit(Path) || !IsLocalGslOwner)
1022           return false;
1023       } else {
1024         IsGslPtrValueFromGslTempOwner =
1025             MTE && !MTE->getExtendingDecl() &&
1026             isRecordWithAttr<OwnerAttr>(MTE->getType());
1027         // Skipping a chain of initializing gsl::Pointer annotated objects.
1028         // We are looking only for the final source to find out if it was
1029         // a local or temporary owner or the address of a local variable/param.
1030         if (!IsGslPtrValueFromGslTempOwner)
1031           return true;
1032       }
1033     }
1034 
1035     switch (LK) {
1036     case LK_FullExpression:
1037       llvm_unreachable("already handled this");
1038 
1039     case LK_Extended: {
1040       if (!MTE) {
1041         // The initialized entity has lifetime beyond the full-expression,
1042         // and the local entity does too, so don't warn.
1043         //
1044         // FIXME: We should consider warning if a static / thread storage
1045         // duration variable retains an automatic storage duration local.
1046         return false;
1047       }
1048 
1049       if (IsGslPtrValueFromGslTempOwner && DiagLoc.isValid()) {
1050         SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer)
1051             << DiagRange;
1052         return false;
1053       }
1054 
1055       switch (shouldLifetimeExtendThroughPath(Path)) {
1056       case PathLifetimeKind::Extend:
1057         // Update the storage duration of the materialized temporary.
1058         // FIXME: Rebuild the expression instead of mutating it.
1059         MTE->setExtendingDecl(ExtendingEntity->getDecl(),
1060                               ExtendingEntity->allocateManglingNumber());
1061         // Also visit the temporaries lifetime-extended by this initializer.
1062         return true;
1063 
1064       case PathLifetimeKind::ShouldExtend:
1065         // We're supposed to lifetime-extend the temporary along this path (per
1066         // the resolution of DR1815), but we don't support that yet.
1067         //
1068         // FIXME: Properly handle this situation. Perhaps the easiest approach
1069         // would be to clone the initializer expression on each use that would
1070         // lifetime extend its temporaries.
1071         SemaRef.Diag(DiagLoc, diag::warn_unsupported_lifetime_extension)
1072             << RK << DiagRange;
1073         break;
1074 
1075       case PathLifetimeKind::NoExtend:
1076         // If the path goes through the initialization of a variable or field,
1077         // it can't possibly reach a temporary created in this full-expression.
1078         // We will have already diagnosed any problems with the initializer.
1079         if (pathContainsInit(Path))
1080           return false;
1081 
1082         SemaRef.Diag(DiagLoc, diag::warn_dangling_variable)
1083             << RK << !InitEntity->getParent()
1084             << ExtendingEntity->getDecl()->isImplicit()
1085             << ExtendingEntity->getDecl() << Init->isGLValue() << DiagRange;
1086         break;
1087       }
1088       break;
1089     }
1090 
1091     case LK_Assignment: {
1092       if (!MTE || pathContainsInit(Path))
1093         return false;
1094       assert(shouldLifetimeExtendThroughPath(Path) ==
1095                  PathLifetimeKind::NoExtend &&
1096              "No lifetime extension for assignments");
1097       SemaRef.Diag(DiagLoc,
1098                    IsGslPtrValueFromGslTempOwner
1099                        ? diag::warn_dangling_lifetime_pointer_assignment
1100                        : diag::warn_dangling_pointer_assignment)
1101           << AEntity->LHS << DiagRange;
1102       return false;
1103     }
1104     case LK_MemInitializer: {
1105       if (MTE) {
1106         // Under C++ DR1696, if a mem-initializer (or a default member
1107         // initializer used by the absence of one) would lifetime-extend a
1108         // temporary, the program is ill-formed.
1109         if (auto *ExtendingDecl =
1110                 ExtendingEntity ? ExtendingEntity->getDecl() : nullptr) {
1111           if (IsGslPtrValueFromGslTempOwner) {
1112             SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer_member)
1113                 << ExtendingDecl << DiagRange;
1114             SemaRef.Diag(ExtendingDecl->getLocation(),
1115                          diag::note_ref_or_ptr_member_declared_here)
1116                 << true;
1117             return false;
1118           }
1119           bool IsSubobjectMember = ExtendingEntity != InitEntity;
1120           SemaRef.Diag(DiagLoc, shouldLifetimeExtendThroughPath(Path) !=
1121                                         PathLifetimeKind::NoExtend
1122                                     ? diag::err_dangling_member
1123                                     : diag::warn_dangling_member)
1124               << ExtendingDecl << IsSubobjectMember << RK << DiagRange;
1125           // Don't bother adding a note pointing to the field if we're inside
1126           // its default member initializer; our primary diagnostic points to
1127           // the same place in that case.
1128           if (Path.empty() ||
1129               Path.back().Kind != IndirectLocalPathEntry::DefaultInit) {
1130             SemaRef.Diag(ExtendingDecl->getLocation(),
1131                          diag::note_lifetime_extending_member_declared_here)
1132                 << RK << IsSubobjectMember;
1133           }
1134         } else {
1135           // We have a mem-initializer but no particular field within it; this
1136           // is either a base class or a delegating initializer directly
1137           // initializing the base-class from something that doesn't live long
1138           // enough.
1139           //
1140           // FIXME: Warn on this.
1141           return false;
1142         }
1143       } else {
1144         // Paths via a default initializer can only occur during error recovery
1145         // (there's no other way that a default initializer can refer to a
1146         // local). Don't produce a bogus warning on those cases.
1147         if (pathContainsInit(Path))
1148           return false;
1149 
1150         // Suppress false positives for code like the one below:
1151         //   Ctor(unique_ptr<T> up) : member(*up), member2(move(up)) {}
1152         if (IsLocalGslOwner && pathOnlyHandlesGslPointer(Path))
1153           return false;
1154 
1155         auto *DRE = dyn_cast<DeclRefExpr>(L);
1156         auto *VD = DRE ? dyn_cast<VarDecl>(DRE->getDecl()) : nullptr;
1157         if (!VD) {
1158           // A member was initialized to a local block.
1159           // FIXME: Warn on this.
1160           return false;
1161         }
1162 
1163         if (auto *Member =
1164                 ExtendingEntity ? ExtendingEntity->getDecl() : nullptr) {
1165           bool IsPointer = !Member->getType()->isReferenceType();
1166           SemaRef.Diag(DiagLoc,
1167                        IsPointer ? diag::warn_init_ptr_member_to_parameter_addr
1168                                  : diag::warn_bind_ref_member_to_parameter)
1169               << Member << VD << isa<ParmVarDecl>(VD) << DiagRange;
1170           SemaRef.Diag(Member->getLocation(),
1171                        diag::note_ref_or_ptr_member_declared_here)
1172               << (unsigned)IsPointer;
1173         }
1174       }
1175       break;
1176     }
1177 
1178     case LK_New:
1179       if (isa<MaterializeTemporaryExpr>(L)) {
1180         if (IsGslPtrValueFromGslTempOwner)
1181           SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer)
1182               << DiagRange;
1183         else
1184           SemaRef.Diag(DiagLoc, RK == RK_ReferenceBinding
1185                                     ? diag::warn_new_dangling_reference
1186                                     : diag::warn_new_dangling_initializer_list)
1187               << !InitEntity->getParent() << DiagRange;
1188       } else {
1189         // We can't determine if the allocation outlives the local declaration.
1190         return false;
1191       }
1192       break;
1193 
1194     case LK_Return:
1195     case LK_StmtExprResult:
1196       if (auto *DRE = dyn_cast<DeclRefExpr>(L)) {
1197         // We can't determine if the local variable outlives the statement
1198         // expression.
1199         if (LK == LK_StmtExprResult)
1200           return false;
1201         SemaRef.Diag(DiagLoc, diag::warn_ret_stack_addr_ref)
1202             << InitEntity->getType()->isReferenceType() << DRE->getDecl()
1203             << isa<ParmVarDecl>(DRE->getDecl()) << DiagRange;
1204       } else if (isa<BlockExpr>(L)) {
1205         SemaRef.Diag(DiagLoc, diag::err_ret_local_block) << DiagRange;
1206       } else if (isa<AddrLabelExpr>(L)) {
1207         // Don't warn when returning a label from a statement expression.
1208         // Leaving the scope doesn't end its lifetime.
1209         if (LK == LK_StmtExprResult)
1210           return false;
1211         SemaRef.Diag(DiagLoc, diag::warn_ret_addr_label) << DiagRange;
1212       } else if (auto *CLE = dyn_cast<CompoundLiteralExpr>(L)) {
1213         SemaRef.Diag(DiagLoc, diag::warn_ret_stack_addr_ref)
1214             << InitEntity->getType()->isReferenceType() << CLE->getInitializer()
1215             << 2 << DiagRange;
1216       } else {
1217         // P2748R5: Disallow Binding a Returned Glvalue to a Temporary.
1218         // [stmt.return]/p6: In a function whose return type is a reference,
1219         // other than an invented function for std::is_convertible ([meta.rel]),
1220         // a return statement that binds the returned reference to a temporary
1221         // expression ([class.temporary]) is ill-formed.
1222         if (SemaRef.getLangOpts().CPlusPlus26 &&
1223             InitEntity->getType()->isReferenceType())
1224           SemaRef.Diag(DiagLoc, diag::err_ret_local_temp_ref)
1225               << InitEntity->getType()->isReferenceType() << DiagRange;
1226         else
1227           SemaRef.Diag(DiagLoc, diag::warn_ret_local_temp_addr_ref)
1228               << InitEntity->getType()->isReferenceType() << DiagRange;
1229       }
1230       break;
1231     }
1232 
1233     for (unsigned I = 0; I != Path.size(); ++I) {
1234       auto Elem = Path[I];
1235 
1236       switch (Elem.Kind) {
1237       case IndirectLocalPathEntry::AddressOf:
1238       case IndirectLocalPathEntry::LValToRVal:
1239         // These exist primarily to mark the path as not permitting or
1240         // supporting lifetime extension.
1241         break;
1242 
1243       case IndirectLocalPathEntry::LifetimeBoundCall:
1244       case IndirectLocalPathEntry::TemporaryCopy:
1245       case IndirectLocalPathEntry::GslPointerInit:
1246       case IndirectLocalPathEntry::GslReferenceInit:
1247       case IndirectLocalPathEntry::GslPointerAssignment:
1248         // FIXME: Consider adding a note for these.
1249         break;
1250 
1251       case IndirectLocalPathEntry::DefaultInit: {
1252         auto *FD = cast<FieldDecl>(Elem.D);
1253         SemaRef.Diag(FD->getLocation(),
1254                      diag::note_init_with_default_member_initializer)
1255             << FD << nextPathEntryRange(Path, I + 1, L);
1256         break;
1257       }
1258 
1259       case IndirectLocalPathEntry::VarInit: {
1260         const VarDecl *VD = cast<VarDecl>(Elem.D);
1261         SemaRef.Diag(VD->getLocation(), diag::note_local_var_initializer)
1262             << VD->getType()->isReferenceType() << VD->isImplicit()
1263             << VD->getDeclName() << nextPathEntryRange(Path, I + 1, L);
1264         break;
1265       }
1266 
1267       case IndirectLocalPathEntry::LambdaCaptureInit:
1268         if (!Elem.Capture->capturesVariable())
1269           break;
1270         // FIXME: We can't easily tell apart an init-capture from a nested
1271         // capture of an init-capture.
1272         const ValueDecl *VD = Elem.Capture->getCapturedVar();
1273         SemaRef.Diag(Elem.Capture->getLocation(),
1274                      diag::note_lambda_capture_initializer)
1275             << VD << VD->isInitCapture() << Elem.Capture->isExplicit()
1276             << (Elem.Capture->getCaptureKind() == LCK_ByRef) << VD
1277             << nextPathEntryRange(Path, I + 1, L);
1278         break;
1279       }
1280     }
1281 
1282     // We didn't lifetime-extend, so don't go any further; we don't need more
1283     // warnings or errors on inner temporaries within this one's initializer.
1284     return false;
1285   };
1286 
1287   llvm::SmallVector<IndirectLocalPathEntry, 8> Path;
1288   if (EnableLifetimeWarnings && LK == LK_Assignment &&
1289       isRecordWithAttr<PointerAttr>(AEntity->LHS->getType()))
1290     Path.push_back({IndirectLocalPathEntry::GslPointerAssignment, Init});
1291 
1292   if (Init->isGLValue())
1293     visitLocalsRetainedByReferenceBinding(Path, Init, RK_ReferenceBinding,
1294                                           TemporaryVisitor,
1295                                           EnableLifetimeWarnings);
1296   else
1297     visitLocalsRetainedByInitializer(
1298         Path, Init, TemporaryVisitor,
1299         // Don't revisit the sub inits for the intialization case.
1300         /*RevisitSubinits=*/!InitEntity, EnableLifetimeWarnings);
1301 }
1302 
checkExprLifetime(Sema & SemaRef,const InitializedEntity & Entity,Expr * Init)1303 void checkExprLifetime(Sema &SemaRef, const InitializedEntity &Entity,
1304                        Expr *Init) {
1305   auto LTResult = getEntityLifetime(&Entity);
1306   LifetimeKind LK = LTResult.getInt();
1307   const InitializedEntity *ExtendingEntity = LTResult.getPointer();
1308   bool EnableLifetimeWarnings = !SemaRef.getDiagnostics().isIgnored(
1309       diag::warn_dangling_lifetime_pointer, SourceLocation());
1310   checkExprLifetimeImpl(SemaRef, &Entity, ExtendingEntity, LK,
1311                         /*AEntity*/ nullptr, Init, EnableLifetimeWarnings);
1312 }
1313 
checkExprLifetime(Sema & SemaRef,const AssignedEntity & Entity,Expr * Init)1314 void checkExprLifetime(Sema &SemaRef, const AssignedEntity &Entity,
1315                        Expr *Init) {
1316   bool EnableLifetimeWarnings = !SemaRef.getDiagnostics().isIgnored(
1317       diag::warn_dangling_lifetime_pointer, SourceLocation());
1318   bool RunAnalysis = Entity.LHS->getType()->isPointerType() ||
1319                      (EnableLifetimeWarnings &&
1320                       isRecordWithAttr<PointerAttr>(Entity.LHS->getType()));
1321 
1322   if (!RunAnalysis)
1323     return;
1324 
1325   checkExprLifetimeImpl(SemaRef, /*InitEntity=*/nullptr,
1326                         /*ExtendingEntity=*/nullptr, LK_Assignment, &Entity,
1327                         Init, EnableLifetimeWarnings);
1328 }
1329 
1330 } // namespace clang::sema
1331