xref: /llvm-project/clang/lib/Sema/CheckExprLifetime.cpp (revision bd56950b9cd5b6b07e1ccb9b02c5d8a7125a23b6)
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/AST/Type.h"
13 #include "clang/Basic/DiagnosticSema.h"
14 #include "clang/Sema/Initialization.h"
15 #include "clang/Sema/Sema.h"
16 #include "llvm/ADT/PointerIntPair.h"
17 
18 namespace clang::sema {
19 namespace {
20 enum LifetimeKind {
21   /// The lifetime of a temporary bound to this entity ends at the end of the
22   /// full-expression, and that's (probably) fine.
23   LK_FullExpression,
24 
25   /// The lifetime of a temporary bound to this entity is extended to the
26   /// lifeitme of the entity itself.
27   LK_Extended,
28 
29   /// The lifetime of a temporary bound to this entity probably ends too soon,
30   /// because the entity is allocated in a new-expression.
31   LK_New,
32 
33   /// The lifetime of a temporary bound to this entity ends too soon, because
34   /// the entity is a return object.
35   LK_Return,
36 
37   /// The lifetime of a temporary bound to this entity ends too soon, because
38   /// the entity passed to a musttail function call.
39   LK_MustTail,
40 
41   /// The lifetime of a temporary bound to this entity ends too soon, because
42   /// the entity is the result of a statement expression.
43   LK_StmtExprResult,
44 
45   /// This is a mem-initializer: if it would extend a temporary (other than via
46   /// a default member initializer), the program is ill-formed.
47   LK_MemInitializer,
48 
49   /// The lifetime of a temporary bound to this entity may end too soon,
50   /// because the entity is a pointer and we assign the address of a temporary
51   /// object to it.
52   LK_Assignment,
53 
54   /// The lifetime of a temporary bound to this entity may end too soon,
55   /// because the entity may capture the reference to a temporary object.
56   LK_LifetimeCapture,
57 };
58 using LifetimeResult =
59     llvm::PointerIntPair<const InitializedEntity *, 3, LifetimeKind>;
60 } // namespace
61 
62 /// Determine the declaration which an initialized entity ultimately refers to,
63 /// for the purpose of lifetime-extending a temporary bound to a reference in
64 /// the initialization of \p Entity.
65 static LifetimeResult
66 getEntityLifetime(const InitializedEntity *Entity,
67                   const InitializedEntity *InitField = nullptr) {
68   // C++11 [class.temporary]p5:
69   switch (Entity->getKind()) {
70   case InitializedEntity::EK_Variable:
71     //   The temporary [...] persists for the lifetime of the reference
72     return {Entity, LK_Extended};
73 
74   case InitializedEntity::EK_Member:
75     // For subobjects, we look at the complete object.
76     if (Entity->getParent())
77       return getEntityLifetime(Entity->getParent(), Entity);
78 
79     //   except:
80     // C++17 [class.base.init]p8:
81     //   A temporary expression bound to a reference member in a
82     //   mem-initializer is ill-formed.
83     // C++17 [class.base.init]p11:
84     //   A temporary expression bound to a reference member from a
85     //   default member initializer is ill-formed.
86     //
87     // The context of p11 and its example suggest that it's only the use of a
88     // default member initializer from a constructor that makes the program
89     // ill-formed, not its mere existence, and that it can even be used by
90     // aggregate initialization.
91     return {Entity, Entity->isDefaultMemberInitializer() ? LK_Extended
92                                                          : LK_MemInitializer};
93 
94   case InitializedEntity::EK_Binding:
95     // Per [dcl.decomp]p3, the binding is treated as a variable of reference
96     // type.
97     return {Entity, LK_Extended};
98 
99   case InitializedEntity::EK_Parameter:
100   case InitializedEntity::EK_Parameter_CF_Audited:
101     //   -- A temporary bound to a reference parameter in a function call
102     //      persists until the completion of the full-expression containing
103     //      the call.
104     return {nullptr, LK_FullExpression};
105 
106   case InitializedEntity::EK_TemplateParameter:
107     // FIXME: This will always be ill-formed; should we eagerly diagnose it
108     // here?
109     return {nullptr, LK_FullExpression};
110 
111   case InitializedEntity::EK_Result:
112     //   -- The lifetime of a temporary bound to the returned value in a
113     //      function return statement is not extended; the temporary is
114     //      destroyed at the end of the full-expression in the return statement.
115     return {nullptr, LK_Return};
116 
117   case InitializedEntity::EK_StmtExprResult:
118     // FIXME: Should we lifetime-extend through the result of a statement
119     // expression?
120     return {nullptr, LK_StmtExprResult};
121 
122   case InitializedEntity::EK_New:
123     //   -- A temporary bound to a reference in a new-initializer persists
124     //      until the completion of the full-expression containing the
125     //      new-initializer.
126     return {nullptr, LK_New};
127 
128   case InitializedEntity::EK_Temporary:
129   case InitializedEntity::EK_CompoundLiteralInit:
130   case InitializedEntity::EK_RelatedResult:
131     // We don't yet know the storage duration of the surrounding temporary.
132     // Assume it's got full-expression duration for now, it will patch up our
133     // storage duration if that's not correct.
134     return {nullptr, LK_FullExpression};
135 
136   case InitializedEntity::EK_ArrayElement:
137     // For subobjects, we look at the complete object.
138     return getEntityLifetime(Entity->getParent(), InitField);
139 
140   case InitializedEntity::EK_Base:
141     // For subobjects, we look at the complete object.
142     if (Entity->getParent())
143       return getEntityLifetime(Entity->getParent(), InitField);
144     return {InitField, LK_MemInitializer};
145 
146   case InitializedEntity::EK_Delegating:
147     // We can reach this case for aggregate initialization in a constructor:
148     //   struct A { int &&r; };
149     //   struct B : A { B() : A{0} {} };
150     // In this case, use the outermost field decl as the context.
151     return {InitField, LK_MemInitializer};
152 
153   case InitializedEntity::EK_BlockElement:
154   case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
155   case InitializedEntity::EK_LambdaCapture:
156   case InitializedEntity::EK_VectorElement:
157   case InitializedEntity::EK_ComplexElement:
158     return {nullptr, LK_FullExpression};
159 
160   case InitializedEntity::EK_Exception:
161     // FIXME: Can we diagnose lifetime problems with exceptions?
162     return {nullptr, LK_FullExpression};
163 
164   case InitializedEntity::EK_ParenAggInitMember:
165     //   -- A temporary object bound to a reference element of an aggregate of
166     //      class type initialized from a parenthesized expression-list
167     //      [dcl.init, 9.3] persists until the completion of the full-expression
168     //      containing the expression-list.
169     return {nullptr, LK_FullExpression};
170   }
171 
172   llvm_unreachable("unknown entity kind");
173 }
174 
175 namespace {
176 enum ReferenceKind {
177   /// Lifetime would be extended by a reference binding to a temporary.
178   RK_ReferenceBinding,
179   /// Lifetime would be extended by a std::initializer_list object binding to
180   /// its backing array.
181   RK_StdInitializerList,
182 };
183 
184 /// A temporary or local variable. This will be one of:
185 ///  * A MaterializeTemporaryExpr.
186 ///  * A DeclRefExpr whose declaration is a local.
187 ///  * An AddrLabelExpr.
188 ///  * A BlockExpr for a block with captures.
189 using Local = Expr *;
190 
191 /// Expressions we stepped over when looking for the local state. Any steps
192 /// that would inhibit lifetime extension or take us out of subexpressions of
193 /// the initializer are included.
194 struct IndirectLocalPathEntry {
195   enum EntryKind {
196     DefaultInit,
197     AddressOf,
198     VarInit,
199     LValToRVal,
200     LifetimeBoundCall,
201     TemporaryCopy,
202     LambdaCaptureInit,
203     MemberExpr,
204     GslReferenceInit,
205     GslPointerInit,
206     GslPointerAssignment,
207     DefaultArg,
208     ParenAggInit,
209   } Kind;
210   Expr *E;
211   union {
212     const Decl *D = nullptr;
213     const LambdaCapture *Capture;
214   };
215   IndirectLocalPathEntry() {}
216   IndirectLocalPathEntry(EntryKind K, Expr *E) : Kind(K), E(E) {}
217   IndirectLocalPathEntry(EntryKind K, Expr *E, const Decl *D)
218       : Kind(K), E(E), D(D) {}
219   IndirectLocalPathEntry(EntryKind K, Expr *E, const LambdaCapture *Capture)
220       : Kind(K), E(E), Capture(Capture) {}
221 };
222 
223 using IndirectLocalPath = llvm::SmallVectorImpl<IndirectLocalPathEntry>;
224 
225 struct RevertToOldSizeRAII {
226   IndirectLocalPath &Path;
227   unsigned OldSize = Path.size();
228   RevertToOldSizeRAII(IndirectLocalPath &Path) : Path(Path) {}
229   ~RevertToOldSizeRAII() { Path.resize(OldSize); }
230 };
231 
232 using LocalVisitor = llvm::function_ref<bool(IndirectLocalPath &Path, Local L,
233                                              ReferenceKind RK)>;
234 } // namespace
235 
236 static bool isVarOnPath(const IndirectLocalPath &Path, VarDecl *VD) {
237   for (auto E : Path)
238     if (E.Kind == IndirectLocalPathEntry::VarInit && E.D == VD)
239       return true;
240   return false;
241 }
242 
243 static bool pathContainsInit(const IndirectLocalPath &Path) {
244   return llvm::any_of(Path, [=](IndirectLocalPathEntry E) {
245     return E.Kind == IndirectLocalPathEntry::DefaultInit ||
246            E.Kind == IndirectLocalPathEntry::VarInit;
247   });
248 }
249 
250 static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
251                                              Expr *Init, LocalVisitor Visit,
252                                              bool RevisitSubinits);
253 
254 static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
255                                                   Expr *Init, ReferenceKind RK,
256                                                   LocalVisitor Visit);
257 
258 template <typename T> static bool isRecordWithAttr(QualType Type) {
259   auto *RD = Type->getAsCXXRecordDecl();
260   if (!RD)
261     return false;
262   // Generally, if a primary template class declaration is annotated with an
263   // attribute, all its specializations generated from template instantiations
264   // should inherit the attribute.
265   //
266   // However, since lifetime analysis occurs during parsing, we may encounter
267   // cases where a full definition of the specialization is not required. In
268   // such cases, the specialization declaration remains incomplete and lacks the
269   // attribute. Therefore, we fall back to checking the primary template class.
270   //
271   // Note: it is possible for a specialization declaration to have an attribute
272   // even if the primary template does not.
273   //
274   // FIXME: What if the primary template and explicit specialization
275   // declarations have conflicting attributes? We should consider diagnosing
276   // this scenario.
277   bool Result = RD->hasAttr<T>();
278 
279   if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
280     Result |= CTSD->getSpecializedTemplate()->getTemplatedDecl()->hasAttr<T>();
281 
282   return Result;
283 }
284 
285 // Tells whether the type is annotated with [[gsl::Pointer]].
286 bool isGLSPointerType(QualType QT) { return isRecordWithAttr<PointerAttr>(QT); }
287 
288 static bool isPointerLikeType(QualType QT) {
289   return isGLSPointerType(QT) || QT->isPointerType() || QT->isNullPtrType();
290 }
291 
292 // Decl::isInStdNamespace will return false for iterators in some STL
293 // implementations due to them being defined in a namespace outside of the std
294 // namespace.
295 static bool isInStlNamespace(const Decl *D) {
296   const DeclContext *DC = D->getDeclContext();
297   if (!DC)
298     return false;
299   if (const auto *ND = dyn_cast<NamespaceDecl>(DC))
300     if (const IdentifierInfo *II = ND->getIdentifier()) {
301       StringRef Name = II->getName();
302       if (Name.size() >= 2 && Name.front() == '_' &&
303           (Name[1] == '_' || isUppercase(Name[1])))
304         return true;
305     }
306 
307   return DC->isStdNamespace();
308 }
309 
310 // Returns true if the given Record decl is a form of `GSLOwner<Pointer>`
311 // type, e.g. std::vector<string_view>, std::optional<string_view>.
312 static bool isContainerOfPointer(const RecordDecl *Container) {
313   if (const auto *CTSD =
314           dyn_cast_if_present<ClassTemplateSpecializationDecl>(Container)) {
315     if (!CTSD->hasAttr<OwnerAttr>()) // Container must be a GSL owner type.
316       return false;
317     const auto &TAs = CTSD->getTemplateArgs();
318     return TAs.size() > 0 && TAs[0].getKind() == TemplateArgument::Type &&
319            isPointerLikeType(TAs[0].getAsType());
320   }
321   return false;
322 }
323 static bool isContainerOfOwner(const RecordDecl *Container) {
324   const auto *CTSD =
325       dyn_cast_if_present<ClassTemplateSpecializationDecl>(Container);
326   if (!CTSD)
327     return false;
328   if (!CTSD->hasAttr<OwnerAttr>()) // Container must be a GSL owner type.
329     return false;
330   const auto &TAs = CTSD->getTemplateArgs();
331   return TAs.size() > 0 && TAs[0].getKind() == TemplateArgument::Type &&
332          isRecordWithAttr<OwnerAttr>(TAs[0].getAsType());
333 }
334 
335 // Returns true if the given Record is `std::initializer_list<pointer>`.
336 static bool isStdInitializerListOfPointer(const RecordDecl *RD) {
337   if (const auto *CTSD =
338           dyn_cast_if_present<ClassTemplateSpecializationDecl>(RD)) {
339     const auto &TAs = CTSD->getTemplateArgs();
340     return isInStlNamespace(RD) && RD->getIdentifier() &&
341            RD->getName() == "initializer_list" && TAs.size() > 0 &&
342            TAs[0].getKind() == TemplateArgument::Type &&
343            isPointerLikeType(TAs[0].getAsType());
344   }
345   return false;
346 }
347 
348 static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
349   if (auto *Conv = dyn_cast_or_null<CXXConversionDecl>(Callee))
350     if (isRecordWithAttr<PointerAttr>(Conv->getConversionType()) &&
351         Callee->getParent()->hasAttr<OwnerAttr>())
352       return true;
353   if (!isInStlNamespace(Callee->getParent()))
354     return false;
355   if (!isRecordWithAttr<PointerAttr>(
356           Callee->getFunctionObjectParameterType()) &&
357       !isRecordWithAttr<OwnerAttr>(Callee->getFunctionObjectParameterType()))
358     return false;
359   if (isPointerLikeType(Callee->getReturnType())) {
360     if (!Callee->getIdentifier())
361       return false;
362     return llvm::StringSwitch<bool>(Callee->getName())
363         .Cases("begin", "rbegin", "cbegin", "crbegin", true)
364         .Cases("end", "rend", "cend", "crend", true)
365         .Cases("c_str", "data", "get", true)
366         // Map and set types.
367         .Cases("find", "equal_range", "lower_bound", "upper_bound", true)
368         .Default(false);
369   }
370   if (Callee->getReturnType()->isReferenceType()) {
371     if (!Callee->getIdentifier()) {
372       auto OO = Callee->getOverloadedOperator();
373       if (!Callee->getParent()->hasAttr<OwnerAttr>())
374         return false;
375       return OO == OverloadedOperatorKind::OO_Subscript ||
376              OO == OverloadedOperatorKind::OO_Star;
377     }
378     return llvm::StringSwitch<bool>(Callee->getName())
379         .Cases("front", "back", "at", "top", "value", true)
380         .Default(false);
381   }
382   return false;
383 }
384 
385 static bool shouldTrackFirstArgument(const FunctionDecl *FD) {
386   if (!FD->getIdentifier() || FD->getNumParams() != 1)
387     return false;
388   const auto *RD = FD->getParamDecl(0)->getType()->getPointeeCXXRecordDecl();
389   if (!FD->isInStdNamespace() || !RD || !RD->isInStdNamespace())
390     return false;
391   if (!RD->hasAttr<PointerAttr>() && !RD->hasAttr<OwnerAttr>())
392     return false;
393   if (FD->getReturnType()->isPointerType() ||
394       isRecordWithAttr<PointerAttr>(FD->getReturnType())) {
395     return llvm::StringSwitch<bool>(FD->getName())
396         .Cases("begin", "rbegin", "cbegin", "crbegin", true)
397         .Cases("end", "rend", "cend", "crend", true)
398         .Case("data", true)
399         .Default(false);
400   }
401   if (FD->getReturnType()->isReferenceType()) {
402     return llvm::StringSwitch<bool>(FD->getName())
403         .Cases("get", "any_cast", true)
404         .Default(false);
405   }
406   return false;
407 }
408 
409 // Returns true if the given constructor is a copy-like constructor, such as
410 // `Ctor(Owner<U>&&)` or `Ctor(const Owner<U>&)`.
411 static bool isCopyLikeConstructor(const CXXConstructorDecl *Ctor) {
412   if (!Ctor || Ctor->param_size() != 1)
413     return false;
414   const auto *ParamRefType =
415       Ctor->getParamDecl(0)->getType()->getAs<ReferenceType>();
416   if (!ParamRefType)
417     return false;
418 
419   // Check if the first parameter type is "Owner<U>".
420   if (const auto *TST =
421           ParamRefType->getPointeeType()->getAs<TemplateSpecializationType>())
422     return TST->getTemplateName()
423         .getAsTemplateDecl()
424         ->getTemplatedDecl()
425         ->hasAttr<OwnerAttr>();
426   return false;
427 }
428 
429 // Returns true if we should perform the GSL analysis on the first argument for
430 // the given constructor.
431 static bool
432 shouldTrackFirstArgumentForConstructor(const CXXConstructExpr *Ctor) {
433   const auto *LHSRecordDecl = Ctor->getConstructor()->getParent();
434 
435   // Case 1, construct a GSL pointer, e.g. std::string_view
436   // Always inspect when LHS is a pointer.
437   if (LHSRecordDecl->hasAttr<PointerAttr>())
438     return true;
439 
440   if (Ctor->getConstructor()->param_empty() ||
441       !isContainerOfPointer(LHSRecordDecl))
442     return false;
443 
444   // Now, the LHS is an Owner<Pointer> type, e.g., std::vector<string_view>.
445   //
446   // At a high level, we cannot precisely determine what the nested pointer
447   // owns. However, by analyzing the RHS owner type, we can use heuristics to
448   // infer ownership information. These heuristics are designed to be
449   // conservative, minimizing false positives while still providing meaningful
450   // diagnostics.
451   //
452   // While this inference isn't perfect, it helps catch common use-after-free
453   // patterns.
454   auto RHSArgType = Ctor->getArg(0)->getType();
455   const auto *RHSRD = RHSArgType->getAsRecordDecl();
456   // LHS is constructed from an intializer_list.
457   //
458   // std::initializer_list is a proxy object that provides access to the backing
459   // array. We perform analysis on it to determine if there are any dangling
460   // temporaries in the backing array.
461   // E.g. std::vector<string_view> abc = {string()};
462   if (isStdInitializerListOfPointer(RHSRD))
463     return true;
464 
465   // RHS must be an owner.
466   if (!isRecordWithAttr<OwnerAttr>(RHSArgType))
467     return false;
468 
469   // Bail out if the RHS is Owner<Pointer>.
470   //
471   // We cannot reliably determine what the LHS nested pointer owns -- it could
472   // be the entire RHS or the nested pointer in RHS. To avoid false positives,
473   // we skip this case, such as:
474   //   std::stack<std::string_view> s(std::deque<std::string_view>{});
475   //
476   // TODO: this also has a false negative, it doesn't catch the case like:
477   //   std::optional<span<int*>> os = std::vector<int*>{}
478   if (isContainerOfPointer(RHSRD))
479     return false;
480 
481   // Assume that the nested Pointer is constructed from the nested Owner.
482   // E.g. std::optional<string_view> sv = std::optional<string>(s);
483   if (isContainerOfOwner(RHSRD))
484     return true;
485 
486   // Now, the LHS is an Owner<Pointer> and the RHS is an Owner<X>,  where X is
487   // neither an `Owner` nor a `Pointer`.
488   //
489   // Use the constructor's signature as a hint. If it is a copy-like constructor
490   // `Owner1<Pointer>(Owner2<X>&&)`, we assume that the nested pointer is
491   // constructed from X. In such cases, we do not diagnose, as `X` is not an
492   // owner, e.g.
493   //   std::optional<string_view> sv = std::optional<Foo>();
494   if (const auto *PrimaryCtorTemplate =
495           Ctor->getConstructor()->getPrimaryTemplate();
496       PrimaryCtorTemplate &&
497       isCopyLikeConstructor(dyn_cast_if_present<CXXConstructorDecl>(
498           PrimaryCtorTemplate->getTemplatedDecl()))) {
499     return false;
500   }
501   // Assume that the nested pointer is constructed from the whole RHS.
502   // E.g. optional<string_view> s = std::string();
503   return true;
504 }
505 
506 // Return true if this is an "normal" assignment operator.
507 // We assume that a normal assignment operator always returns *this, that is,
508 // an lvalue reference that is the same type as the implicit object parameter
509 // (or the LHS for a non-member operator$=).
510 static bool isNormalAssignmentOperator(const FunctionDecl *FD) {
511   OverloadedOperatorKind OO = FD->getDeclName().getCXXOverloadedOperator();
512   if (OO == OO_Equal || isCompoundAssignmentOperator(OO)) {
513     QualType RetT = FD->getReturnType();
514     if (RetT->isLValueReferenceType()) {
515       ASTContext &Ctx = FD->getASTContext();
516       QualType LHST;
517       auto *MD = dyn_cast<CXXMethodDecl>(FD);
518       if (MD && MD->isCXXInstanceMember())
519         LHST = Ctx.getLValueReferenceType(MD->getFunctionObjectParameterType());
520       else
521         LHST = FD->getParamDecl(0)->getType();
522       if (Ctx.hasSameType(RetT, LHST))
523         return true;
524     }
525   }
526   return false;
527 }
528 
529 static const FunctionDecl *
530 getDeclWithMergedLifetimeBoundAttrs(const FunctionDecl *FD) {
531   return FD != nullptr ? FD->getMostRecentDecl() : nullptr;
532 }
533 
534 static const CXXMethodDecl *
535 getDeclWithMergedLifetimeBoundAttrs(const CXXMethodDecl *CMD) {
536   const FunctionDecl *FD = CMD;
537   return cast_if_present<CXXMethodDecl>(
538       getDeclWithMergedLifetimeBoundAttrs(FD));
539 }
540 
541 bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) {
542   FD = getDeclWithMergedLifetimeBoundAttrs(FD);
543   const TypeSourceInfo *TSI = FD->getTypeSourceInfo();
544   if (!TSI)
545     return false;
546   // Don't declare this variable in the second operand of the for-statement;
547   // GCC miscompiles that by ending its lifetime before evaluating the
548   // third operand. See gcc.gnu.org/PR86769.
549   AttributedTypeLoc ATL;
550   for (TypeLoc TL = TSI->getTypeLoc();
551        (ATL = TL.getAsAdjusted<AttributedTypeLoc>());
552        TL = ATL.getModifiedLoc()) {
553     if (ATL.getAttrAs<LifetimeBoundAttr>())
554       return true;
555   }
556 
557   return isNormalAssignmentOperator(FD);
558 }
559 
560 // Visit lifetimebound or gsl-pointer arguments.
561 static void visitFunctionCallArguments(IndirectLocalPath &Path, Expr *Call,
562                                        LocalVisitor Visit) {
563   const FunctionDecl *Callee;
564   ArrayRef<Expr *> Args;
565 
566   if (auto *CE = dyn_cast<CallExpr>(Call)) {
567     Callee = CE->getDirectCallee();
568     Args = llvm::ArrayRef(CE->getArgs(), CE->getNumArgs());
569   } else {
570     auto *CCE = cast<CXXConstructExpr>(Call);
571     Callee = CCE->getConstructor();
572     Args = llvm::ArrayRef(CCE->getArgs(), CCE->getNumArgs());
573   }
574   if (!Callee)
575     return;
576 
577   bool EnableGSLAnalysis = !Callee->getASTContext().getDiagnostics().isIgnored(
578       diag::warn_dangling_lifetime_pointer, SourceLocation());
579   Expr *ObjectArg = nullptr;
580   if (isa<CXXOperatorCallExpr>(Call) && Callee->isCXXInstanceMember()) {
581     ObjectArg = Args[0];
582     Args = Args.slice(1);
583   } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(Call)) {
584     ObjectArg = MCE->getImplicitObjectArgument();
585   }
586 
587   auto VisitLifetimeBoundArg = [&](const Decl *D, Expr *Arg) {
588     Path.push_back({IndirectLocalPathEntry::LifetimeBoundCall, Arg, D});
589     if (Arg->isGLValue())
590       visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding,
591                                             Visit);
592     else
593       visitLocalsRetainedByInitializer(Path, Arg, Visit, true);
594     Path.pop_back();
595   };
596   auto VisitGSLPointerArg = [&](const FunctionDecl *Callee, Expr *Arg) {
597     auto ReturnType = Callee->getReturnType();
598 
599     // Once we initialized a value with a non gsl-owner reference, it can no
600     // longer dangle.
601     if (ReturnType->isReferenceType() &&
602         !isRecordWithAttr<OwnerAttr>(ReturnType->getPointeeType())) {
603       for (const IndirectLocalPathEntry &PE : llvm::reverse(Path)) {
604         if (PE.Kind == IndirectLocalPathEntry::GslReferenceInit ||
605             PE.Kind == IndirectLocalPathEntry::LifetimeBoundCall)
606           continue;
607         if (PE.Kind == IndirectLocalPathEntry::GslPointerInit ||
608             PE.Kind == IndirectLocalPathEntry::GslPointerAssignment)
609           return;
610         break;
611       }
612     }
613     Path.push_back({ReturnType->isReferenceType()
614                         ? IndirectLocalPathEntry::GslReferenceInit
615                         : IndirectLocalPathEntry::GslPointerInit,
616                     Arg, Callee});
617     if (Arg->isGLValue())
618       visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding,
619                                             Visit);
620     else
621       visitLocalsRetainedByInitializer(Path, Arg, Visit, true);
622     Path.pop_back();
623   };
624 
625   bool CheckCoroCall = false;
626   if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
627     CheckCoroCall = RD->hasAttr<CoroLifetimeBoundAttr>() &&
628                     RD->hasAttr<CoroReturnTypeAttr>() &&
629                     !Callee->hasAttr<CoroDisableLifetimeBoundAttr>();
630   }
631 
632   if (ObjectArg) {
633     bool CheckCoroObjArg = CheckCoroCall;
634     // Coroutine lambda objects with empty capture list are not lifetimebound.
635     if (auto *LE = dyn_cast<LambdaExpr>(ObjectArg->IgnoreImplicit());
636         LE && LE->captures().empty())
637       CheckCoroObjArg = false;
638     // Allow `get_return_object()` as the object param (__promise) is not
639     // lifetimebound.
640     if (Sema::CanBeGetReturnObject(Callee))
641       CheckCoroObjArg = false;
642     if (implicitObjectParamIsLifetimeBound(Callee) || CheckCoroObjArg)
643       VisitLifetimeBoundArg(Callee, ObjectArg);
644     else if (EnableGSLAnalysis) {
645       if (auto *CME = dyn_cast<CXXMethodDecl>(Callee);
646           CME && shouldTrackImplicitObjectArg(CME))
647         VisitGSLPointerArg(Callee, ObjectArg);
648     }
649   }
650 
651   const FunctionDecl *CanonCallee = getDeclWithMergedLifetimeBoundAttrs(Callee);
652   unsigned NP = std::min(Callee->getNumParams(), CanonCallee->getNumParams());
653   for (unsigned I = 0, N = std::min<unsigned>(NP, Args.size()); I != N; ++I) {
654     Expr *Arg = Args[I];
655     RevertToOldSizeRAII RAII(Path);
656     if (auto *DAE = dyn_cast<CXXDefaultArgExpr>(Arg)) {
657       Path.push_back(
658           {IndirectLocalPathEntry::DefaultArg, DAE, DAE->getParam()});
659       Arg = DAE->getExpr();
660     }
661     if (CheckCoroCall ||
662         CanonCallee->getParamDecl(I)->hasAttr<LifetimeBoundAttr>())
663       VisitLifetimeBoundArg(CanonCallee->getParamDecl(I), Arg);
664     else if (const auto *CaptureAttr =
665                  CanonCallee->getParamDecl(I)->getAttr<LifetimeCaptureByAttr>();
666              CaptureAttr && isa<CXXConstructorDecl>(CanonCallee) &&
667              llvm::any_of(CaptureAttr->params(), [](int ArgIdx) {
668                return ArgIdx == LifetimeCaptureByAttr::THIS;
669              }))
670       // `lifetime_capture_by(this)` in a class constructor has the same
671       // semantics as `lifetimebound`:
672       //
673       // struct Foo {
674       //   const int& a;
675       //   // Equivalent to Foo(const int& t [[clang::lifetimebound]])
676       //   Foo(const int& t [[clang::lifetime_capture_by(this)]]) : a(t) {}
677       // };
678       //
679       // In the implementation, `lifetime_capture_by` is treated as an alias for
680       // `lifetimebound` and shares the same code path. This implies the emitted
681       // diagnostics will be emitted under `-Wdangling`, not
682       // `-Wdangling-capture`.
683       VisitLifetimeBoundArg(CanonCallee->getParamDecl(I), Arg);
684     else if (EnableGSLAnalysis && I == 0) {
685       // Perform GSL analysis for the first argument
686       if (shouldTrackFirstArgument(CanonCallee)) {
687         VisitGSLPointerArg(CanonCallee, Arg);
688       } else if (auto *Ctor = dyn_cast<CXXConstructExpr>(Call);
689                  Ctor && shouldTrackFirstArgumentForConstructor(Ctor)) {
690         VisitGSLPointerArg(Ctor->getConstructor(), Arg);
691       }
692     }
693   }
694 }
695 
696 /// Visit the locals that would be reachable through a reference bound to the
697 /// glvalue expression \c Init.
698 static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
699                                                   Expr *Init, ReferenceKind RK,
700                                                   LocalVisitor Visit) {
701   RevertToOldSizeRAII RAII(Path);
702 
703   // Walk past any constructs which we can lifetime-extend across.
704   Expr *Old;
705   do {
706     Old = Init;
707 
708     if (auto *FE = dyn_cast<FullExpr>(Init))
709       Init = FE->getSubExpr();
710 
711     if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
712       // If this is just redundant braces around an initializer, step over it.
713       if (ILE->isTransparent())
714         Init = ILE->getInit(0);
715     }
716 
717     if (MemberExpr *ME = dyn_cast<MemberExpr>(Init->IgnoreImpCasts()))
718       Path.push_back(
719           {IndirectLocalPathEntry::MemberExpr, ME, ME->getMemberDecl()});
720     // Step over any subobject adjustments; we may have a materialized
721     // temporary inside them.
722     Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments());
723 
724     // Per current approach for DR1376, look through casts to reference type
725     // when performing lifetime extension.
726     if (CastExpr *CE = dyn_cast<CastExpr>(Init))
727       if (CE->getSubExpr()->isGLValue())
728         Init = CE->getSubExpr();
729 
730     // Per the current approach for DR1299, look through array element access
731     // on array glvalues when performing lifetime extension.
732     if (auto *ASE = dyn_cast<ArraySubscriptExpr>(Init)) {
733       Init = ASE->getBase();
734       auto *ICE = dyn_cast<ImplicitCastExpr>(Init);
735       if (ICE && ICE->getCastKind() == CK_ArrayToPointerDecay)
736         Init = ICE->getSubExpr();
737       else
738         // We can't lifetime extend through this but we might still find some
739         // retained temporaries.
740         return visitLocalsRetainedByInitializer(Path, Init, Visit, true);
741     }
742 
743     // Step into CXXDefaultInitExprs so we can diagnose cases where a
744     // constructor inherits one as an implicit mem-initializer.
745     if (auto *DIE = dyn_cast<CXXDefaultInitExpr>(Init)) {
746       Path.push_back(
747           {IndirectLocalPathEntry::DefaultInit, DIE, DIE->getField()});
748       Init = DIE->getExpr();
749     }
750   } while (Init != Old);
751 
752   if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Init)) {
753     if (Visit(Path, Local(MTE), RK))
754       visitLocalsRetainedByInitializer(Path, MTE->getSubExpr(), Visit, true);
755   }
756 
757   if (auto *M = dyn_cast<MemberExpr>(Init)) {
758     // Lifetime of a non-reference type field is same as base object.
759     if (auto *F = dyn_cast<FieldDecl>(M->getMemberDecl());
760         F && !F->getType()->isReferenceType())
761       visitLocalsRetainedByInitializer(Path, M->getBase(), Visit, true);
762   }
763 
764   if (isa<CallExpr>(Init))
765     return visitFunctionCallArguments(Path, Init, Visit);
766 
767   switch (Init->getStmtClass()) {
768   case Stmt::DeclRefExprClass: {
769     // If we find the name of a local non-reference parameter, we could have a
770     // lifetime problem.
771     auto *DRE = cast<DeclRefExpr>(Init);
772     auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
773     if (VD && VD->hasLocalStorage() &&
774         !DRE->refersToEnclosingVariableOrCapture()) {
775       if (!VD->getType()->isReferenceType()) {
776         Visit(Path, Local(DRE), RK);
777       } else if (isa<ParmVarDecl>(DRE->getDecl())) {
778         // The lifetime of a reference parameter is unknown; assume it's OK
779         // for now.
780         break;
781       } else if (VD->getInit() && !isVarOnPath(Path, VD)) {
782         Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
783         visitLocalsRetainedByReferenceBinding(Path, VD->getInit(),
784                                               RK_ReferenceBinding, Visit);
785       }
786     }
787     break;
788   }
789 
790   case Stmt::UnaryOperatorClass: {
791     // The only unary operator that make sense to handle here
792     // is Deref.  All others don't resolve to a "name."  This includes
793     // handling all sorts of rvalues passed to a unary operator.
794     const UnaryOperator *U = cast<UnaryOperator>(Init);
795     if (U->getOpcode() == UO_Deref)
796       visitLocalsRetainedByInitializer(Path, U->getSubExpr(), Visit, true);
797     break;
798   }
799 
800   case Stmt::ArraySectionExprClass: {
801     visitLocalsRetainedByInitializer(
802         Path, cast<ArraySectionExpr>(Init)->getBase(), Visit, true);
803     break;
804   }
805 
806   case Stmt::ConditionalOperatorClass:
807   case Stmt::BinaryConditionalOperatorClass: {
808     auto *C = cast<AbstractConditionalOperator>(Init);
809     if (!C->getTrueExpr()->getType()->isVoidType())
810       visitLocalsRetainedByReferenceBinding(Path, C->getTrueExpr(), RK, Visit);
811     if (!C->getFalseExpr()->getType()->isVoidType())
812       visitLocalsRetainedByReferenceBinding(Path, C->getFalseExpr(), RK, Visit);
813     break;
814   }
815 
816   case Stmt::CompoundLiteralExprClass: {
817     if (auto *CLE = dyn_cast<CompoundLiteralExpr>(Init)) {
818       if (!CLE->isFileScope())
819         Visit(Path, Local(CLE), RK);
820     }
821     break;
822   }
823 
824     // FIXME: Visit the left-hand side of an -> or ->*.
825 
826   default:
827     break;
828   }
829 }
830 
831 /// Visit the locals that would be reachable through an object initialized by
832 /// the prvalue expression \c Init.
833 static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
834                                              Expr *Init, LocalVisitor Visit,
835                                              bool RevisitSubinits) {
836   RevertToOldSizeRAII RAII(Path);
837 
838   Expr *Old;
839   do {
840     Old = Init;
841 
842     // Step into CXXDefaultInitExprs so we can diagnose cases where a
843     // constructor inherits one as an implicit mem-initializer.
844     if (auto *DIE = dyn_cast<CXXDefaultInitExpr>(Init)) {
845       Path.push_back(
846           {IndirectLocalPathEntry::DefaultInit, DIE, DIE->getField()});
847       Init = DIE->getExpr();
848     }
849 
850     if (auto *FE = dyn_cast<FullExpr>(Init))
851       Init = FE->getSubExpr();
852 
853     // Dig out the expression which constructs the extended temporary.
854     Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments());
855 
856     if (CXXBindTemporaryExpr *BTE = dyn_cast<CXXBindTemporaryExpr>(Init))
857       Init = BTE->getSubExpr();
858 
859     Init = Init->IgnoreParens();
860 
861     // Step over value-preserving rvalue casts.
862     if (auto *CE = dyn_cast<CastExpr>(Init)) {
863       switch (CE->getCastKind()) {
864       case CK_LValueToRValue:
865         // If we can match the lvalue to a const object, we can look at its
866         // initializer.
867         Path.push_back({IndirectLocalPathEntry::LValToRVal, CE});
868         return visitLocalsRetainedByReferenceBinding(
869             Path, Init, RK_ReferenceBinding,
870             [&](IndirectLocalPath &Path, Local L, ReferenceKind RK) -> bool {
871               if (auto *DRE = dyn_cast<DeclRefExpr>(L)) {
872                 auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
873                 if (VD && VD->getType().isConstQualified() && VD->getInit() &&
874                     !isVarOnPath(Path, VD)) {
875                   Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
876                   visitLocalsRetainedByInitializer(Path, VD->getInit(), Visit,
877                                                    true);
878                 }
879               } else if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L)) {
880                 if (MTE->getType().isConstQualified())
881                   visitLocalsRetainedByInitializer(Path, MTE->getSubExpr(),
882                                                    Visit, true);
883               }
884               return false;
885             });
886 
887         // We assume that objects can be retained by pointers cast to integers,
888         // but not if the integer is cast to floating-point type or to _Complex.
889         // We assume that casts to 'bool' do not preserve enough information to
890         // retain a local object.
891       case CK_NoOp:
892       case CK_BitCast:
893       case CK_BaseToDerived:
894       case CK_DerivedToBase:
895       case CK_UncheckedDerivedToBase:
896       case CK_Dynamic:
897       case CK_ToUnion:
898       case CK_UserDefinedConversion:
899       case CK_ConstructorConversion:
900       case CK_IntegralToPointer:
901       case CK_PointerToIntegral:
902       case CK_VectorSplat:
903       case CK_IntegralCast:
904       case CK_CPointerToObjCPointerCast:
905       case CK_BlockPointerToObjCPointerCast:
906       case CK_AnyPointerToBlockPointerCast:
907       case CK_AddressSpaceConversion:
908         break;
909 
910       case CK_ArrayToPointerDecay:
911         // Model array-to-pointer decay as taking the address of the array
912         // lvalue.
913         Path.push_back({IndirectLocalPathEntry::AddressOf, CE});
914         return visitLocalsRetainedByReferenceBinding(
915             Path, CE->getSubExpr(), RK_ReferenceBinding, Visit);
916 
917       default:
918         return;
919       }
920 
921       Init = CE->getSubExpr();
922     }
923   } while (Old != Init);
924 
925   // C++17 [dcl.init.list]p6:
926   //   initializing an initializer_list object from the array extends the
927   //   lifetime of the array exactly like binding a reference to a temporary.
928   if (auto *ILE = dyn_cast<CXXStdInitializerListExpr>(Init))
929     return visitLocalsRetainedByReferenceBinding(Path, ILE->getSubExpr(),
930                                                  RK_StdInitializerList, Visit);
931 
932   if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
933     // We already visited the elements of this initializer list while
934     // performing the initialization. Don't visit them again unless we've
935     // changed the lifetime of the initialized entity.
936     if (!RevisitSubinits)
937       return;
938 
939     if (ILE->isTransparent())
940       return visitLocalsRetainedByInitializer(Path, ILE->getInit(0), Visit,
941                                               RevisitSubinits);
942 
943     if (ILE->getType()->isArrayType()) {
944       for (unsigned I = 0, N = ILE->getNumInits(); I != N; ++I)
945         visitLocalsRetainedByInitializer(Path, ILE->getInit(I), Visit,
946                                          RevisitSubinits);
947       return;
948     }
949 
950     if (CXXRecordDecl *RD = ILE->getType()->getAsCXXRecordDecl()) {
951       assert(RD->isAggregate() && "aggregate init on non-aggregate");
952 
953       // If we lifetime-extend a braced initializer which is initializing an
954       // aggregate, and that aggregate contains reference members which are
955       // bound to temporaries, those temporaries are also lifetime-extended.
956       if (RD->isUnion() && ILE->getInitializedFieldInUnion() &&
957           ILE->getInitializedFieldInUnion()->getType()->isReferenceType())
958         visitLocalsRetainedByReferenceBinding(Path, ILE->getInit(0),
959                                               RK_ReferenceBinding, Visit);
960       else {
961         unsigned Index = 0;
962         for (; Index < RD->getNumBases() && Index < ILE->getNumInits(); ++Index)
963           visitLocalsRetainedByInitializer(Path, ILE->getInit(Index), Visit,
964                                            RevisitSubinits);
965         for (const auto *I : RD->fields()) {
966           if (Index >= ILE->getNumInits())
967             break;
968           if (I->isUnnamedBitField())
969             continue;
970           Expr *SubInit = ILE->getInit(Index);
971           if (I->getType()->isReferenceType())
972             visitLocalsRetainedByReferenceBinding(Path, SubInit,
973                                                   RK_ReferenceBinding, Visit);
974           else
975             // This might be either aggregate-initialization of a member or
976             // initialization of a std::initializer_list object. Regardless,
977             // we should recursively lifetime-extend that initializer.
978             visitLocalsRetainedByInitializer(Path, SubInit, Visit,
979                                              RevisitSubinits);
980           ++Index;
981         }
982       }
983     }
984     return;
985   }
986 
987   // The lifetime of an init-capture is that of the closure object constructed
988   // by a lambda-expression.
989   if (auto *LE = dyn_cast<LambdaExpr>(Init)) {
990     LambdaExpr::capture_iterator CapI = LE->capture_begin();
991     for (Expr *E : LE->capture_inits()) {
992       assert(CapI != LE->capture_end());
993       const LambdaCapture &Cap = *CapI++;
994       if (!E)
995         continue;
996       if (Cap.capturesVariable())
997         Path.push_back({IndirectLocalPathEntry::LambdaCaptureInit, E, &Cap});
998       if (E->isGLValue())
999         visitLocalsRetainedByReferenceBinding(Path, E, RK_ReferenceBinding,
1000                                               Visit);
1001       else
1002         visitLocalsRetainedByInitializer(Path, E, Visit, true);
1003       if (Cap.capturesVariable())
1004         Path.pop_back();
1005     }
1006   }
1007 
1008   // Assume that a copy or move from a temporary references the same objects
1009   // that the temporary does.
1010   if (auto *CCE = dyn_cast<CXXConstructExpr>(Init)) {
1011     if (CCE->getConstructor()->isCopyOrMoveConstructor()) {
1012       if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(CCE->getArg(0))) {
1013         Expr *Arg = MTE->getSubExpr();
1014         Path.push_back({IndirectLocalPathEntry::TemporaryCopy, Arg,
1015                         CCE->getConstructor()});
1016         visitLocalsRetainedByInitializer(Path, Arg, Visit, true);
1017         Path.pop_back();
1018       }
1019     }
1020   }
1021 
1022   if (isa<CallExpr>(Init) || isa<CXXConstructExpr>(Init))
1023     return visitFunctionCallArguments(Path, Init, Visit);
1024 
1025   if (auto *CPE = dyn_cast<CXXParenListInitExpr>(Init)) {
1026     RevertToOldSizeRAII RAII(Path);
1027     Path.push_back({IndirectLocalPathEntry::ParenAggInit, CPE});
1028     for (auto *I : CPE->getInitExprs()) {
1029       if (I->isGLValue())
1030         visitLocalsRetainedByReferenceBinding(Path, I, RK_ReferenceBinding,
1031                                               Visit);
1032       else
1033         visitLocalsRetainedByInitializer(Path, I, Visit, true);
1034     }
1035   }
1036   switch (Init->getStmtClass()) {
1037   case Stmt::UnaryOperatorClass: {
1038     auto *UO = cast<UnaryOperator>(Init);
1039     // If the initializer is the address of a local, we could have a lifetime
1040     // problem.
1041     if (UO->getOpcode() == UO_AddrOf) {
1042       // If this is &rvalue, then it's ill-formed and we have already diagnosed
1043       // it. Don't produce a redundant warning about the lifetime of the
1044       // temporary.
1045       if (isa<MaterializeTemporaryExpr>(UO->getSubExpr()))
1046         return;
1047 
1048       Path.push_back({IndirectLocalPathEntry::AddressOf, UO});
1049       visitLocalsRetainedByReferenceBinding(Path, UO->getSubExpr(),
1050                                             RK_ReferenceBinding, Visit);
1051     }
1052     break;
1053   }
1054 
1055   case Stmt::BinaryOperatorClass: {
1056     // Handle pointer arithmetic.
1057     auto *BO = cast<BinaryOperator>(Init);
1058     BinaryOperatorKind BOK = BO->getOpcode();
1059     if (!BO->getType()->isPointerType() || (BOK != BO_Add && BOK != BO_Sub))
1060       break;
1061 
1062     if (BO->getLHS()->getType()->isPointerType())
1063       visitLocalsRetainedByInitializer(Path, BO->getLHS(), Visit, true);
1064     else if (BO->getRHS()->getType()->isPointerType())
1065       visitLocalsRetainedByInitializer(Path, BO->getRHS(), Visit, true);
1066     break;
1067   }
1068 
1069   case Stmt::ConditionalOperatorClass:
1070   case Stmt::BinaryConditionalOperatorClass: {
1071     auto *C = cast<AbstractConditionalOperator>(Init);
1072     // In C++, we can have a throw-expression operand, which has 'void' type
1073     // and isn't interesting from a lifetime perspective.
1074     if (!C->getTrueExpr()->getType()->isVoidType())
1075       visitLocalsRetainedByInitializer(Path, C->getTrueExpr(), Visit, true);
1076     if (!C->getFalseExpr()->getType()->isVoidType())
1077       visitLocalsRetainedByInitializer(Path, C->getFalseExpr(), Visit, true);
1078     break;
1079   }
1080 
1081   case Stmt::BlockExprClass:
1082     if (cast<BlockExpr>(Init)->getBlockDecl()->hasCaptures()) {
1083       // This is a local block, whose lifetime is that of the function.
1084       Visit(Path, Local(cast<BlockExpr>(Init)), RK_ReferenceBinding);
1085     }
1086     break;
1087 
1088   case Stmt::AddrLabelExprClass:
1089     // We want to warn if the address of a label would escape the function.
1090     Visit(Path, Local(cast<AddrLabelExpr>(Init)), RK_ReferenceBinding);
1091     break;
1092 
1093   default:
1094     break;
1095   }
1096 }
1097 
1098 /// Whether a path to an object supports lifetime extension.
1099 enum PathLifetimeKind {
1100   /// Lifetime-extend along this path.
1101   Extend,
1102   /// Do not lifetime extend along this path.
1103   NoExtend
1104 };
1105 
1106 /// Determine whether this is an indirect path to a temporary that we are
1107 /// supposed to lifetime-extend along.
1108 static PathLifetimeKind
1109 shouldLifetimeExtendThroughPath(const IndirectLocalPath &Path) {
1110   for (auto Elem : Path) {
1111     if (Elem.Kind == IndirectLocalPathEntry::MemberExpr ||
1112         Elem.Kind == IndirectLocalPathEntry::LambdaCaptureInit)
1113       continue;
1114     return Elem.Kind == IndirectLocalPathEntry::DefaultInit
1115                ? PathLifetimeKind::Extend
1116                : PathLifetimeKind::NoExtend;
1117   }
1118   return PathLifetimeKind::Extend;
1119 }
1120 
1121 /// Find the range for the first interesting entry in the path at or after I.
1122 static SourceRange nextPathEntryRange(const IndirectLocalPath &Path, unsigned I,
1123                                       Expr *E) {
1124   for (unsigned N = Path.size(); I != N; ++I) {
1125     switch (Path[I].Kind) {
1126     case IndirectLocalPathEntry::AddressOf:
1127     case IndirectLocalPathEntry::LValToRVal:
1128     case IndirectLocalPathEntry::LifetimeBoundCall:
1129     case IndirectLocalPathEntry::TemporaryCopy:
1130     case IndirectLocalPathEntry::GslReferenceInit:
1131     case IndirectLocalPathEntry::GslPointerInit:
1132     case IndirectLocalPathEntry::GslPointerAssignment:
1133     case IndirectLocalPathEntry::ParenAggInit:
1134     case IndirectLocalPathEntry::MemberExpr:
1135       // These exist primarily to mark the path as not permitting or
1136       // supporting lifetime extension.
1137       break;
1138 
1139     case IndirectLocalPathEntry::VarInit:
1140       if (cast<VarDecl>(Path[I].D)->isImplicit())
1141         return SourceRange();
1142       [[fallthrough]];
1143     case IndirectLocalPathEntry::DefaultInit:
1144       return Path[I].E->getSourceRange();
1145 
1146     case IndirectLocalPathEntry::LambdaCaptureInit:
1147       if (!Path[I].Capture->capturesVariable())
1148         continue;
1149       return Path[I].E->getSourceRange();
1150 
1151     case IndirectLocalPathEntry::DefaultArg:
1152       return cast<CXXDefaultArgExpr>(Path[I].E)->getUsedLocation();
1153     }
1154   }
1155   return E->getSourceRange();
1156 }
1157 
1158 static bool pathOnlyHandlesGslPointer(const IndirectLocalPath &Path) {
1159   for (const auto &It : llvm::reverse(Path)) {
1160     switch (It.Kind) {
1161     case IndirectLocalPathEntry::VarInit:
1162     case IndirectLocalPathEntry::AddressOf:
1163     case IndirectLocalPathEntry::LifetimeBoundCall:
1164     case IndirectLocalPathEntry::MemberExpr:
1165       continue;
1166     case IndirectLocalPathEntry::GslPointerInit:
1167     case IndirectLocalPathEntry::GslReferenceInit:
1168     case IndirectLocalPathEntry::GslPointerAssignment:
1169       return true;
1170     default:
1171       return false;
1172     }
1173   }
1174   return false;
1175 }
1176 // Result of analyzing the Path for GSLPointer.
1177 enum AnalysisResult {
1178   // Path does not correspond to a GSLPointer.
1179   NotGSLPointer,
1180 
1181   // A relevant case was identified.
1182   Report,
1183   // Stop the entire traversal.
1184   Abandon,
1185   // Skip this step and continue traversing inner AST nodes.
1186   Skip,
1187 };
1188 // Analyze cases where a GSLPointer is initialized or assigned from a
1189 // temporary owner object.
1190 static AnalysisResult analyzePathForGSLPointer(const IndirectLocalPath &Path,
1191                                                Local L, LifetimeKind LK) {
1192   if (!pathOnlyHandlesGslPointer(Path))
1193     return NotGSLPointer;
1194 
1195   // At this point, Path represents a series of operations involving a
1196   // GSLPointer, either in the process of initialization or assignment.
1197 
1198   // Process  temporary base objects for MemberExpr cases, e.g. Temp().field.
1199   for (const auto &E : Path) {
1200     if (E.Kind == IndirectLocalPathEntry::MemberExpr) {
1201       // Avoid interfering  with the local base object.
1202       if (pathContainsInit(Path))
1203         return Abandon;
1204 
1205       // We are not interested in the temporary base objects of gsl Pointers:
1206       //   auto p1 = Temp().ptr; // Here p1 might not dangle.
1207       // However, we want to diagnose for gsl owner fields:
1208       //   auto p2 = Temp().owner; // Here p2 is dangling.
1209       if (const auto *FD = llvm::dyn_cast_or_null<FieldDecl>(E.D);
1210           FD && !FD->getType()->isReferenceType() &&
1211           isRecordWithAttr<OwnerAttr>(FD->getType()) &&
1212           LK != LK_MemInitializer) {
1213         return Report;
1214       }
1215       return Abandon;
1216     }
1217   }
1218 
1219   // Note: A LifetimeBoundCall can appear interleaved in this sequence.
1220   // For example:
1221   //    const std::string& Ref(const std::string& a [[clang::lifetimebound]]);
1222   //    string_view abc = Ref(std::string());
1223   // The "Path" is [GSLPointerInit, LifetimeboundCall], where "L" is the
1224   // temporary "std::string()" object. We need to check the return type of the
1225   // function with the lifetimebound attribute.
1226   if (Path.back().Kind == IndirectLocalPathEntry::LifetimeBoundCall) {
1227     // The lifetimebound applies to the implicit object parameter of a method.
1228     const FunctionDecl *FD =
1229         llvm::dyn_cast_or_null<FunctionDecl>(Path.back().D);
1230     // The lifetimebound applies to a function parameter.
1231     if (const auto *PD = llvm::dyn_cast<ParmVarDecl>(Path.back().D))
1232       FD = llvm::dyn_cast<FunctionDecl>(PD->getDeclContext());
1233 
1234     if (isa_and_present<CXXConstructorDecl>(FD)) {
1235       // Constructor case: the parameter is annotated with lifetimebound
1236       //   e.g., GSLPointer(const S& s [[clang::lifetimebound]])
1237       // We still respect this case even the type S is not an owner.
1238       return Report;
1239     }
1240     // Check the return type, e.g.
1241     //   const GSLOwner& func(const Foo& foo [[clang::lifetimebound]])
1242     //   GSLPointer func(const Foo& foo [[clang::lifetimebound]])
1243     if (FD &&
1244         ((FD->getReturnType()->isReferenceType() &&
1245           isRecordWithAttr<OwnerAttr>(FD->getReturnType()->getPointeeType())) ||
1246          isPointerLikeType(FD->getReturnType())))
1247       return Report;
1248 
1249     return Abandon;
1250   }
1251 
1252   if (isa<DeclRefExpr>(L)) {
1253     // We do not want to follow the references when returning a pointer
1254     // originating from a local owner to avoid the following false positive:
1255     //   int &p = *localUniquePtr;
1256     //   someContainer.add(std::move(localUniquePtr));
1257     //   return p;
1258     if (!pathContainsInit(Path) && isRecordWithAttr<OwnerAttr>(L->getType()))
1259       return Report;
1260     return Abandon;
1261   }
1262 
1263   // The GSLPointer is from a temporary object.
1264   auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L);
1265 
1266   bool IsGslPtrValueFromGslTempOwner =
1267       MTE && !MTE->getExtendingDecl() &&
1268       isRecordWithAttr<OwnerAttr>(MTE->getType());
1269   // Skipping a chain of initializing gsl::Pointer annotated objects.
1270   // We are looking only for the final source to find out if it was
1271   // a local or temporary owner or the address of a local
1272   // variable/param.
1273   if (!IsGslPtrValueFromGslTempOwner)
1274     return Skip;
1275   return Report;
1276 }
1277 
1278 static bool isAssignmentOperatorLifetimeBound(const CXXMethodDecl *CMD) {
1279   CMD = getDeclWithMergedLifetimeBoundAttrs(CMD);
1280   return CMD && isNormalAssignmentOperator(CMD) && CMD->param_size() == 1 &&
1281          CMD->getParamDecl(0)->hasAttr<LifetimeBoundAttr>();
1282 }
1283 
1284 static bool shouldRunGSLAssignmentAnalysis(const Sema &SemaRef,
1285                                            const AssignedEntity &Entity) {
1286   bool EnableGSLAssignmentWarnings = !SemaRef.getDiagnostics().isIgnored(
1287       diag::warn_dangling_lifetime_pointer_assignment, SourceLocation());
1288   return (EnableGSLAssignmentWarnings &&
1289           (isRecordWithAttr<PointerAttr>(Entity.LHS->getType()) ||
1290            isAssignmentOperatorLifetimeBound(Entity.AssignmentOperator)));
1291 }
1292 
1293 static void
1294 checkExprLifetimeImpl(Sema &SemaRef, const InitializedEntity *InitEntity,
1295                       const InitializedEntity *ExtendingEntity, LifetimeKind LK,
1296                       const AssignedEntity *AEntity,
1297                       const CapturingEntity *CapEntity, Expr *Init) {
1298   assert(!AEntity || LK == LK_Assignment);
1299   assert(!CapEntity || LK == LK_LifetimeCapture);
1300   assert(!InitEntity || (LK != LK_Assignment && LK != LK_LifetimeCapture));
1301   // If this entity doesn't have an interesting lifetime, don't bother looking
1302   // for temporaries within its initializer.
1303   if (LK == LK_FullExpression)
1304     return;
1305 
1306   // FIXME: consider moving the TemporaryVisitor and visitLocalsRetained*
1307   // functions to a dedicated class.
1308   auto TemporaryVisitor = [&](const IndirectLocalPath &Path, Local L,
1309                               ReferenceKind RK) -> bool {
1310     SourceRange DiagRange = nextPathEntryRange(Path, 0, L);
1311     SourceLocation DiagLoc = DiagRange.getBegin();
1312 
1313     auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L);
1314 
1315     bool IsGslPtrValueFromGslTempOwner = true;
1316     switch (analyzePathForGSLPointer(Path, L, LK)) {
1317     case Abandon:
1318       return false;
1319     case Skip:
1320       return true;
1321     case NotGSLPointer:
1322       IsGslPtrValueFromGslTempOwner = false;
1323       LLVM_FALLTHROUGH;
1324     case Report:
1325       break;
1326     }
1327 
1328     switch (LK) {
1329     case LK_FullExpression:
1330       llvm_unreachable("already handled this");
1331 
1332     case LK_Extended: {
1333       if (!MTE) {
1334         // The initialized entity has lifetime beyond the full-expression,
1335         // and the local entity does too, so don't warn.
1336         //
1337         // FIXME: We should consider warning if a static / thread storage
1338         // duration variable retains an automatic storage duration local.
1339         return false;
1340       }
1341 
1342       if (IsGslPtrValueFromGslTempOwner && DiagLoc.isValid()) {
1343         SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer)
1344             << DiagRange;
1345         return false;
1346       }
1347 
1348       switch (shouldLifetimeExtendThroughPath(Path)) {
1349       case PathLifetimeKind::Extend:
1350         // Update the storage duration of the materialized temporary.
1351         // FIXME: Rebuild the expression instead of mutating it.
1352         MTE->setExtendingDecl(ExtendingEntity->getDecl(),
1353                               ExtendingEntity->allocateManglingNumber());
1354         // Also visit the temporaries lifetime-extended by this initializer.
1355         return true;
1356 
1357       case PathLifetimeKind::NoExtend:
1358         // If the path goes through the initialization of a variable or field,
1359         // it can't possibly reach a temporary created in this full-expression.
1360         // We will have already diagnosed any problems with the initializer.
1361         if (pathContainsInit(Path))
1362           return false;
1363 
1364         SemaRef.Diag(DiagLoc, diag::warn_dangling_variable)
1365             << RK << !InitEntity->getParent()
1366             << ExtendingEntity->getDecl()->isImplicit()
1367             << ExtendingEntity->getDecl() << Init->isGLValue() << DiagRange;
1368         break;
1369       }
1370       break;
1371     }
1372 
1373     case LK_LifetimeCapture: {
1374       // The captured entity has lifetime beyond the full-expression,
1375       // and the capturing entity does too, so don't warn.
1376       if (!MTE)
1377         return false;
1378       if (CapEntity->Entity)
1379         SemaRef.Diag(DiagLoc, diag::warn_dangling_reference_captured)
1380             << CapEntity->Entity << DiagRange;
1381       else
1382         SemaRef.Diag(DiagLoc, diag::warn_dangling_reference_captured_by_unknown)
1383             << DiagRange;
1384       return false;
1385     }
1386 
1387     case LK_Assignment: {
1388       if (!MTE || pathContainsInit(Path))
1389         return false;
1390       if (IsGslPtrValueFromGslTempOwner)
1391         SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer_assignment)
1392             << AEntity->LHS << DiagRange;
1393       else
1394         SemaRef.Diag(DiagLoc, diag::warn_dangling_pointer_assignment)
1395             << AEntity->LHS->getType()->isPointerType() << AEntity->LHS
1396             << DiagRange;
1397       return false;
1398     }
1399     case LK_MemInitializer: {
1400       if (MTE) {
1401         // Under C++ DR1696, if a mem-initializer (or a default member
1402         // initializer used by the absence of one) would lifetime-extend a
1403         // temporary, the program is ill-formed.
1404         if (auto *ExtendingDecl =
1405                 ExtendingEntity ? ExtendingEntity->getDecl() : nullptr) {
1406           if (IsGslPtrValueFromGslTempOwner) {
1407             SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer_member)
1408                 << ExtendingDecl << DiagRange;
1409             SemaRef.Diag(ExtendingDecl->getLocation(),
1410                          diag::note_ref_or_ptr_member_declared_here)
1411                 << true;
1412             return false;
1413           }
1414           bool IsSubobjectMember = ExtendingEntity != InitEntity;
1415           SemaRef.Diag(DiagLoc, shouldLifetimeExtendThroughPath(Path) !=
1416                                         PathLifetimeKind::NoExtend
1417                                     ? diag::err_dangling_member
1418                                     : diag::warn_dangling_member)
1419               << ExtendingDecl << IsSubobjectMember << RK << DiagRange;
1420           // Don't bother adding a note pointing to the field if we're inside
1421           // its default member initializer; our primary diagnostic points to
1422           // the same place in that case.
1423           if (Path.empty() ||
1424               Path.back().Kind != IndirectLocalPathEntry::DefaultInit) {
1425             SemaRef.Diag(ExtendingDecl->getLocation(),
1426                          diag::note_lifetime_extending_member_declared_here)
1427                 << RK << IsSubobjectMember;
1428           }
1429         } else {
1430           // We have a mem-initializer but no particular field within it; this
1431           // is either a base class or a delegating initializer directly
1432           // initializing the base-class from something that doesn't live long
1433           // enough.
1434           //
1435           // FIXME: Warn on this.
1436           return false;
1437         }
1438       } else {
1439         // Paths via a default initializer can only occur during error recovery
1440         // (there's no other way that a default initializer can refer to a
1441         // local). Don't produce a bogus warning on those cases.
1442         if (pathContainsInit(Path))
1443           return false;
1444 
1445         auto *DRE = dyn_cast<DeclRefExpr>(L);
1446         // Suppress false positives for code like the one below:
1447         //   Ctor(unique_ptr<T> up) : pointer(up.get()), owner(move(up)) {}
1448         // FIXME: move this logic to analyzePathForGSLPointer.
1449         if (DRE && isRecordWithAttr<OwnerAttr>(DRE->getType()))
1450           return false;
1451 
1452         auto *VD = DRE ? dyn_cast<VarDecl>(DRE->getDecl()) : nullptr;
1453         if (!VD) {
1454           // A member was initialized to a local block.
1455           // FIXME: Warn on this.
1456           return false;
1457         }
1458 
1459         if (auto *Member =
1460                 ExtendingEntity ? ExtendingEntity->getDecl() : nullptr) {
1461           bool IsPointer = !Member->getType()->isReferenceType();
1462           SemaRef.Diag(DiagLoc,
1463                        IsPointer ? diag::warn_init_ptr_member_to_parameter_addr
1464                                  : diag::warn_bind_ref_member_to_parameter)
1465               << Member << VD << isa<ParmVarDecl>(VD) << DiagRange;
1466           SemaRef.Diag(Member->getLocation(),
1467                        diag::note_ref_or_ptr_member_declared_here)
1468               << (unsigned)IsPointer;
1469         }
1470       }
1471       break;
1472     }
1473 
1474     case LK_New:
1475       if (isa<MaterializeTemporaryExpr>(L)) {
1476         if (IsGslPtrValueFromGslTempOwner)
1477           SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer)
1478               << DiagRange;
1479         else
1480           SemaRef.Diag(DiagLoc, RK == RK_ReferenceBinding
1481                                     ? diag::warn_new_dangling_reference
1482                                     : diag::warn_new_dangling_initializer_list)
1483               << !InitEntity->getParent() << DiagRange;
1484       } else {
1485         // We can't determine if the allocation outlives the local declaration.
1486         return false;
1487       }
1488       break;
1489 
1490     case LK_Return:
1491     case LK_MustTail:
1492     case LK_StmtExprResult:
1493       if (auto *DRE = dyn_cast<DeclRefExpr>(L)) {
1494         // We can't determine if the local variable outlives the statement
1495         // expression.
1496         if (LK == LK_StmtExprResult)
1497           return false;
1498         SemaRef.Diag(DiagLoc, diag::warn_ret_stack_addr_ref)
1499             << InitEntity->getType()->isReferenceType() << DRE->getDecl()
1500             << isa<ParmVarDecl>(DRE->getDecl()) << (LK == LK_MustTail)
1501             << DiagRange;
1502       } else if (isa<BlockExpr>(L)) {
1503         SemaRef.Diag(DiagLoc, diag::err_ret_local_block) << DiagRange;
1504       } else if (isa<AddrLabelExpr>(L)) {
1505         // Don't warn when returning a label from a statement expression.
1506         // Leaving the scope doesn't end its lifetime.
1507         if (LK == LK_StmtExprResult)
1508           return false;
1509         SemaRef.Diag(DiagLoc, diag::warn_ret_addr_label) << DiagRange;
1510       } else if (auto *CLE = dyn_cast<CompoundLiteralExpr>(L)) {
1511         SemaRef.Diag(DiagLoc, diag::warn_ret_stack_addr_ref)
1512             << InitEntity->getType()->isReferenceType() << CLE->getInitializer()
1513             << 2 << (LK == LK_MustTail) << DiagRange;
1514       } else {
1515         // P2748R5: Disallow Binding a Returned Glvalue to a Temporary.
1516         // [stmt.return]/p6: In a function whose return type is a reference,
1517         // other than an invented function for std::is_convertible ([meta.rel]),
1518         // a return statement that binds the returned reference to a temporary
1519         // expression ([class.temporary]) is ill-formed.
1520         if (SemaRef.getLangOpts().CPlusPlus26 &&
1521             InitEntity->getType()->isReferenceType())
1522           SemaRef.Diag(DiagLoc, diag::err_ret_local_temp_ref)
1523               << InitEntity->getType()->isReferenceType() << DiagRange;
1524         else if (LK == LK_MustTail)
1525           SemaRef.Diag(DiagLoc, diag::warn_musttail_local_temp_addr_ref)
1526               << InitEntity->getType()->isReferenceType() << DiagRange;
1527         else
1528           SemaRef.Diag(DiagLoc, diag::warn_ret_local_temp_addr_ref)
1529               << InitEntity->getType()->isReferenceType() << DiagRange;
1530       }
1531       break;
1532     }
1533 
1534     for (unsigned I = 0; I != Path.size(); ++I) {
1535       auto Elem = Path[I];
1536 
1537       switch (Elem.Kind) {
1538       case IndirectLocalPathEntry::AddressOf:
1539       case IndirectLocalPathEntry::LValToRVal:
1540       case IndirectLocalPathEntry::ParenAggInit:
1541         // These exist primarily to mark the path as not permitting or
1542         // supporting lifetime extension.
1543         break;
1544 
1545       case IndirectLocalPathEntry::LifetimeBoundCall:
1546       case IndirectLocalPathEntry::TemporaryCopy:
1547       case IndirectLocalPathEntry::MemberExpr:
1548       case IndirectLocalPathEntry::GslPointerInit:
1549       case IndirectLocalPathEntry::GslReferenceInit:
1550       case IndirectLocalPathEntry::GslPointerAssignment:
1551         // FIXME: Consider adding a note for these.
1552         break;
1553 
1554       case IndirectLocalPathEntry::DefaultInit: {
1555         auto *FD = cast<FieldDecl>(Elem.D);
1556         SemaRef.Diag(FD->getLocation(),
1557                      diag::note_init_with_default_member_initializer)
1558             << FD << nextPathEntryRange(Path, I + 1, L);
1559         break;
1560       }
1561 
1562       case IndirectLocalPathEntry::VarInit: {
1563         const VarDecl *VD = cast<VarDecl>(Elem.D);
1564         SemaRef.Diag(VD->getLocation(), diag::note_local_var_initializer)
1565             << VD->getType()->isReferenceType() << VD->isImplicit()
1566             << VD->getDeclName() << nextPathEntryRange(Path, I + 1, L);
1567         break;
1568       }
1569 
1570       case IndirectLocalPathEntry::LambdaCaptureInit: {
1571         if (!Elem.Capture->capturesVariable())
1572           break;
1573         // FIXME: We can't easily tell apart an init-capture from a nested
1574         // capture of an init-capture.
1575         const ValueDecl *VD = Elem.Capture->getCapturedVar();
1576         SemaRef.Diag(Elem.Capture->getLocation(),
1577                      diag::note_lambda_capture_initializer)
1578             << VD << VD->isInitCapture() << Elem.Capture->isExplicit()
1579             << (Elem.Capture->getCaptureKind() == LCK_ByRef) << VD
1580             << nextPathEntryRange(Path, I + 1, L);
1581         break;
1582       }
1583 
1584       case IndirectLocalPathEntry::DefaultArg: {
1585         const auto *DAE = cast<CXXDefaultArgExpr>(Elem.E);
1586         const ParmVarDecl *Param = DAE->getParam();
1587         SemaRef.Diag(Param->getDefaultArgRange().getBegin(),
1588                      diag::note_init_with_default_argument)
1589             << Param << nextPathEntryRange(Path, I + 1, L);
1590         break;
1591       }
1592       }
1593     }
1594 
1595     // We didn't lifetime-extend, so don't go any further; we don't need more
1596     // warnings or errors on inner temporaries within this one's initializer.
1597     return false;
1598   };
1599 
1600   llvm::SmallVector<IndirectLocalPathEntry, 8> Path;
1601   switch (LK) {
1602   case LK_Assignment: {
1603     if (shouldRunGSLAssignmentAnalysis(SemaRef, *AEntity))
1604       Path.push_back(
1605           {isAssignmentOperatorLifetimeBound(AEntity->AssignmentOperator)
1606                ? IndirectLocalPathEntry::LifetimeBoundCall
1607                : IndirectLocalPathEntry::GslPointerAssignment,
1608            Init});
1609     break;
1610   }
1611   case LK_LifetimeCapture: {
1612     if (isPointerLikeType(Init->getType()))
1613       Path.push_back({IndirectLocalPathEntry::GslPointerInit, Init});
1614     break;
1615   }
1616   default:
1617     break;
1618   }
1619 
1620   if (Init->isGLValue())
1621     visitLocalsRetainedByReferenceBinding(Path, Init, RK_ReferenceBinding,
1622                                           TemporaryVisitor);
1623   else
1624     visitLocalsRetainedByInitializer(
1625         Path, Init, TemporaryVisitor,
1626         // Don't revisit the sub inits for the intialization case.
1627         /*RevisitSubinits=*/!InitEntity);
1628 }
1629 
1630 void checkInitLifetime(Sema &SemaRef, const InitializedEntity &Entity,
1631                        Expr *Init) {
1632   auto LTResult = getEntityLifetime(&Entity);
1633   LifetimeKind LK = LTResult.getInt();
1634   const InitializedEntity *ExtendingEntity = LTResult.getPointer();
1635   checkExprLifetimeImpl(SemaRef, &Entity, ExtendingEntity, LK,
1636                         /*AEntity=*/nullptr, /*CapEntity=*/nullptr, Init);
1637 }
1638 
1639 void checkExprLifetimeMustTailArg(Sema &SemaRef,
1640                                   const InitializedEntity &Entity, Expr *Init) {
1641   checkExprLifetimeImpl(SemaRef, &Entity, nullptr, LK_MustTail,
1642                         /*AEntity=*/nullptr, /*CapEntity=*/nullptr, Init);
1643 }
1644 
1645 void checkAssignmentLifetime(Sema &SemaRef, const AssignedEntity &Entity,
1646                              Expr *Init) {
1647   bool EnableDanglingPointerAssignment = !SemaRef.getDiagnostics().isIgnored(
1648       diag::warn_dangling_pointer_assignment, SourceLocation());
1649   bool RunAnalysis = (EnableDanglingPointerAssignment &&
1650                       Entity.LHS->getType()->isPointerType()) ||
1651                      shouldRunGSLAssignmentAnalysis(SemaRef, Entity);
1652 
1653   if (!RunAnalysis)
1654     return;
1655 
1656   checkExprLifetimeImpl(SemaRef, /*InitEntity=*/nullptr,
1657                         /*ExtendingEntity=*/nullptr, LK_Assignment, &Entity,
1658                         /*CapEntity=*/nullptr, Init);
1659 }
1660 
1661 void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity,
1662                             Expr *Init) {
1663   if (SemaRef.getDiagnostics().isIgnored(diag::warn_dangling_reference_captured,
1664                                          SourceLocation()) &&
1665       SemaRef.getDiagnostics().isIgnored(
1666           diag::warn_dangling_reference_captured_by_unknown, SourceLocation()))
1667     return;
1668   return checkExprLifetimeImpl(SemaRef, /*InitEntity=*/nullptr,
1669                                /*ExtendingEntity=*/nullptr, LK_LifetimeCapture,
1670                                /*AEntity=*/nullptr,
1671                                /*CapEntity=*/&Entity, Init);
1672 }
1673 
1674 } // namespace clang::sema
1675