clang  20.0.0git
CheckExprLifetime.cpp
Go to the documentation of this file.
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"
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
58  const InitializedEntity *InitField = nullptr) {
59  // C++11 [class.temporary]p5:
60  switch (Entity->getKind()) {
62  // The temporary [...] persists for the lifetime of the reference
63  return {Entity, LK_Extended};
64 
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 
86  // Per [dcl.decomp]p3, the binding is treated as a variable of reference
87  // type.
88  return {Entity, LK_Extended};
89 
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 
98  // FIXME: This will always be ill-formed; should we eagerly diagnose it
99  // here?
100  return {nullptr, LK_FullExpression};
101 
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 
109  // FIXME: Should we lifetime-extend through the result of a statement
110  // expression?
111  return {nullptr, LK_StmtExprResult};
112 
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 
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 
128  // For subobjects, we look at the complete object.
129  return getEntityLifetime(Entity->getParent(), InitField);
130 
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 
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 
149  return {nullptr, LK_FullExpression};
150 
152  // FIXME: Can we diagnose lifetime problems with exceptions?
153  return {nullptr, LK_FullExpression};
154 
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  };
203  IndirectLocalPathEntry() {}
204  IndirectLocalPathEntry(EntryKind K, Expr *E) : Kind(K), E(E) {}
205  IndirectLocalPathEntry(EntryKind K, Expr *E, const Decl *D)
206  : Kind(K), E(E), D(D) {}
207  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();
216  RevertToOldSizeRAII(IndirectLocalPath &Path) : Path(Path) {}
217  ~RevertToOldSizeRAII() { Path.resize(OldSize); }
218 };
219 
220 using LocalVisitor = llvm::function_ref<bool(IndirectLocalPath &Path, Local L,
221  ReferenceKind RK)>;
222 } // namespace
223 
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 
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 
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.
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 
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 
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 
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 
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$=).
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 
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.
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});
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: {
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.
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});
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});
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())
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())
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.
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
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  Expr *Arg = MTE->getSubExpr();
829  Path.push_back({IndirectLocalPathEntry::TemporaryCopy, Arg,
830  CCE->getConstructor()});
831  visitLocalsRetainedByInitializer(Path, Arg, Visit, true,
832  /*EnableLifetimeWarnings*/ false);
833  Path.pop_back();
834  }
835  }
836  }
837 
838  if (isa<CallExpr>(Init) || isa<CXXConstructExpr>(Init)) {
839  if (EnableLifetimeWarnings)
840  handleGslAnnotatedTypes(Path, Init, Visit);
841  return visitLifetimeBoundArguments(Path, Init, Visit);
842  }
843 
844  switch (Init->getStmtClass()) {
845  case Stmt::UnaryOperatorClass: {
846  auto *UO = cast<UnaryOperator>(Init);
847  // If the initializer is the address of a local, we could have a lifetime
848  // problem.
849  if (UO->getOpcode() == UO_AddrOf) {
850  // If this is &rvalue, then it's ill-formed and we have already diagnosed
851  // it. Don't produce a redundant warning about the lifetime of the
852  // temporary.
853  if (isa<MaterializeTemporaryExpr>(UO->getSubExpr()))
854  return;
855 
856  Path.push_back({IndirectLocalPathEntry::AddressOf, UO});
858  RK_ReferenceBinding, Visit,
859  EnableLifetimeWarnings);
860  }
861  break;
862  }
863 
864  case Stmt::BinaryOperatorClass: {
865  // Handle pointer arithmetic.
866  auto *BO = cast<BinaryOperator>(Init);
867  BinaryOperatorKind BOK = BO->getOpcode();
868  if (!BO->getType()->isPointerType() || (BOK != BO_Add && BOK != BO_Sub))
869  break;
870 
871  if (BO->getLHS()->getType()->isPointerType())
872  visitLocalsRetainedByInitializer(Path, BO->getLHS(), Visit, true,
873  EnableLifetimeWarnings);
874  else if (BO->getRHS()->getType()->isPointerType())
875  visitLocalsRetainedByInitializer(Path, BO->getRHS(), Visit, true,
876  EnableLifetimeWarnings);
877  break;
878  }
879 
880  case Stmt::ConditionalOperatorClass:
881  case Stmt::BinaryConditionalOperatorClass: {
882  auto *C = cast<AbstractConditionalOperator>(Init);
883  // In C++, we can have a throw-expression operand, which has 'void' type
884  // and isn't interesting from a lifetime perspective.
885  if (!C->getTrueExpr()->getType()->isVoidType())
886  visitLocalsRetainedByInitializer(Path, C->getTrueExpr(), Visit, true,
887  EnableLifetimeWarnings);
888  if (!C->getFalseExpr()->getType()->isVoidType())
889  visitLocalsRetainedByInitializer(Path, C->getFalseExpr(), Visit, true,
890  EnableLifetimeWarnings);
891  break;
892  }
893 
894  case Stmt::BlockExprClass:
895  if (cast<BlockExpr>(Init)->getBlockDecl()->hasCaptures()) {
896  // This is a local block, whose lifetime is that of the function.
897  Visit(Path, Local(cast<BlockExpr>(Init)), RK_ReferenceBinding);
898  }
899  break;
900 
901  case Stmt::AddrLabelExprClass:
902  // We want to warn if the address of a label would escape the function.
903  Visit(Path, Local(cast<AddrLabelExpr>(Init)), RK_ReferenceBinding);
904  break;
905 
906  default:
907  break;
908  }
909 }
910 
911 /// Whether a path to an object supports lifetime extension.
913  /// Lifetime-extend along this path.
915  /// We should lifetime-extend, but we don't because (due to technical
916  /// limitations) we can't. This happens for default member initializers,
917  /// which we don't clone for every use, so we don't have a unique
918  /// MaterializeTemporaryExpr to update.
920  /// Do not lifetime extend along this path.
921  NoExtend
922 };
923 
924 /// Determine whether this is an indirect path to a temporary that we are
925 /// supposed to lifetime-extend along.
926 static PathLifetimeKind
927 shouldLifetimeExtendThroughPath(const IndirectLocalPath &Path) {
929  for (auto Elem : Path) {
930  if (Elem.Kind == IndirectLocalPathEntry::DefaultInit)
932  else if (Elem.Kind != IndirectLocalPathEntry::LambdaCaptureInit)
934  }
935  return Kind;
936 }
937 
938 /// Find the range for the first interesting entry in the path at or after I.
939 static SourceRange nextPathEntryRange(const IndirectLocalPath &Path, unsigned I,
940  Expr *E) {
941  for (unsigned N = Path.size(); I != N; ++I) {
942  switch (Path[I].Kind) {
943  case IndirectLocalPathEntry::AddressOf:
944  case IndirectLocalPathEntry::LValToRVal:
945  case IndirectLocalPathEntry::LifetimeBoundCall:
946  case IndirectLocalPathEntry::TemporaryCopy:
947  case IndirectLocalPathEntry::GslReferenceInit:
948  case IndirectLocalPathEntry::GslPointerInit:
949  case IndirectLocalPathEntry::GslPointerAssignment:
950  // These exist primarily to mark the path as not permitting or
951  // supporting lifetime extension.
952  break;
953 
954  case IndirectLocalPathEntry::VarInit:
955  if (cast<VarDecl>(Path[I].D)->isImplicit())
956  return SourceRange();
957  [[fallthrough]];
958  case IndirectLocalPathEntry::DefaultInit:
959  return Path[I].E->getSourceRange();
960 
961  case IndirectLocalPathEntry::LambdaCaptureInit:
962  if (!Path[I].Capture->capturesVariable())
963  continue;
964  return Path[I].E->getSourceRange();
965  }
966  }
967  return E->getSourceRange();
968 }
969 
970 static bool pathOnlyHandlesGslPointer(IndirectLocalPath &Path) {
971  for (const auto &It : llvm::reverse(Path)) {
972  switch (It.Kind) {
973  case IndirectLocalPathEntry::VarInit:
974  case IndirectLocalPathEntry::AddressOf:
975  case IndirectLocalPathEntry::LifetimeBoundCall:
976  continue;
977  case IndirectLocalPathEntry::GslPointerInit:
978  case IndirectLocalPathEntry::GslReferenceInit:
979  case IndirectLocalPathEntry::GslPointerAssignment:
980  return true;
981  default:
982  return false;
983  }
984  }
985  return false;
986 }
987 
988 static void checkExprLifetimeImpl(Sema &SemaRef,
989  const InitializedEntity *InitEntity,
990  const InitializedEntity *ExtendingEntity,
991  LifetimeKind LK,
992  const AssignedEntity *AEntity, Expr *Init,
993  bool EnableLifetimeWarnings) {
994  assert((AEntity && LK == LK_Assignment) ||
995  (InitEntity && LK != LK_Assignment));
996  // If this entity doesn't have an interesting lifetime, don't bother looking
997  // for temporaries within its initializer.
998  if (LK == LK_FullExpression)
999  return;
1000 
1001  // FIXME: consider moving the TemporaryVisitor and visitLocalsRetained*
1002  // functions to a dedicated class.
1003  auto TemporaryVisitor = [&](IndirectLocalPath &Path, Local L,
1004  ReferenceKind RK) -> bool {
1005  SourceRange DiagRange = nextPathEntryRange(Path, 0, L);
1006  SourceLocation DiagLoc = DiagRange.getBegin();
1007 
1008  auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L);
1009 
1010  bool IsGslPtrValueFromGslTempOwner = false;
1011  bool IsLocalGslOwner = false;
1013  if (isa<DeclRefExpr>(L)) {
1014  // We do not want to follow the references when returning a pointer
1015  // originating from a local owner to avoid the following false positive:
1016  // int &p = *localUniquePtr;
1017  // someContainer.add(std::move(localUniquePtr));
1018  // return p;
1019  IsLocalGslOwner = isRecordWithAttr<OwnerAttr>(L->getType());
1020  if (pathContainsInit(Path) || !IsLocalGslOwner)
1021  return false;
1022  } else {
1023  IsGslPtrValueFromGslTempOwner =
1024  MTE && !MTE->getExtendingDecl() &&
1025  isRecordWithAttr<OwnerAttr>(MTE->getType());
1026  // Skipping a chain of initializing gsl::Pointer annotated objects.
1027  // We are looking only for the final source to find out if it was
1028  // a local or temporary owner or the address of a local variable/param.
1029  if (!IsGslPtrValueFromGslTempOwner)
1030  return true;
1031  }
1032  }
1033 
1034  switch (LK) {
1035  case LK_FullExpression:
1036  llvm_unreachable("already handled this");
1037 
1038  case LK_Extended: {
1039  if (!MTE) {
1040  // The initialized entity has lifetime beyond the full-expression,
1041  // and the local entity does too, so don't warn.
1042  //
1043  // FIXME: We should consider warning if a static / thread storage
1044  // duration variable retains an automatic storage duration local.
1045  return false;
1046  }
1047 
1048  if (IsGslPtrValueFromGslTempOwner && DiagLoc.isValid()) {
1049  SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer)
1050  << DiagRange;
1051  return false;
1052  }
1053 
1056  // Update the storage duration of the materialized temporary.
1057  // FIXME: Rebuild the expression instead of mutating it.
1058  MTE->setExtendingDecl(ExtendingEntity->getDecl(),
1059  ExtendingEntity->allocateManglingNumber());
1060  // Also visit the temporaries lifetime-extended by this initializer.
1061  return true;
1062 
1064  // We're supposed to lifetime-extend the temporary along this path (per
1065  // the resolution of DR1815), but we don't support that yet.
1066  //
1067  // FIXME: Properly handle this situation. Perhaps the easiest approach
1068  // would be to clone the initializer expression on each use that would
1069  // lifetime extend its temporaries.
1070  SemaRef.Diag(DiagLoc, diag::warn_unsupported_lifetime_extension)
1071  << RK << DiagRange;
1072  break;
1073 
1075  // If the path goes through the initialization of a variable or field,
1076  // it can't possibly reach a temporary created in this full-expression.
1077  // We will have already diagnosed any problems with the initializer.
1078  if (pathContainsInit(Path))
1079  return false;
1080 
1081  SemaRef.Diag(DiagLoc, diag::warn_dangling_variable)
1082  << RK << !InitEntity->getParent()
1083  << ExtendingEntity->getDecl()->isImplicit()
1084  << ExtendingEntity->getDecl() << Init->isGLValue() << DiagRange;
1085  break;
1086  }
1087  break;
1088  }
1089 
1090  case LK_Assignment: {
1091  if (!MTE || pathContainsInit(Path))
1092  return false;
1095  "No lifetime extension for assignments");
1096  SemaRef.Diag(DiagLoc,
1097  IsGslPtrValueFromGslTempOwner
1098  ? diag::warn_dangling_lifetime_pointer_assignment
1099  : diag::warn_dangling_pointer_assignment)
1100  << AEntity->LHS << DiagRange;
1101  return false;
1102  }
1103  case LK_MemInitializer: {
1104  if (MTE) {
1105  // Under C++ DR1696, if a mem-initializer (or a default member
1106  // initializer used by the absence of one) would lifetime-extend a
1107  // temporary, the program is ill-formed.
1108  if (auto *ExtendingDecl =
1109  ExtendingEntity ? ExtendingEntity->getDecl() : nullptr) {
1110  if (IsGslPtrValueFromGslTempOwner) {
1111  SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer_member)
1112  << ExtendingDecl << DiagRange;
1113  SemaRef.Diag(ExtendingDecl->getLocation(),
1114  diag::note_ref_or_ptr_member_declared_here)
1115  << true;
1116  return false;
1117  }
1118  bool IsSubobjectMember = ExtendingEntity != InitEntity;
1119  SemaRef.Diag(DiagLoc, shouldLifetimeExtendThroughPath(Path) !=
1121  ? diag::err_dangling_member
1122  : diag::warn_dangling_member)
1123  << ExtendingDecl << IsSubobjectMember << RK << DiagRange;
1124  // Don't bother adding a note pointing to the field if we're inside
1125  // its default member initializer; our primary diagnostic points to
1126  // the same place in that case.
1127  if (Path.empty() ||
1128  Path.back().Kind != IndirectLocalPathEntry::DefaultInit) {
1129  SemaRef.Diag(ExtendingDecl->getLocation(),
1130  diag::note_lifetime_extending_member_declared_here)
1131  << RK << IsSubobjectMember;
1132  }
1133  } else {
1134  // We have a mem-initializer but no particular field within it; this
1135  // is either a base class or a delegating initializer directly
1136  // initializing the base-class from something that doesn't live long
1137  // enough.
1138  //
1139  // FIXME: Warn on this.
1140  return false;
1141  }
1142  } else {
1143  // Paths via a default initializer can only occur during error recovery
1144  // (there's no other way that a default initializer can refer to a
1145  // local). Don't produce a bogus warning on those cases.
1146  if (pathContainsInit(Path))
1147  return false;
1148 
1149  // Suppress false positives for code like the one below:
1150  // Ctor(unique_ptr<T> up) : member(*up), member2(move(up)) {}
1151  if (IsLocalGslOwner && pathOnlyHandlesGslPointer(Path))
1152  return false;
1153 
1154  auto *DRE = dyn_cast<DeclRefExpr>(L);
1155  auto *VD = DRE ? dyn_cast<VarDecl>(DRE->getDecl()) : nullptr;
1156  if (!VD) {
1157  // A member was initialized to a local block.
1158  // FIXME: Warn on this.
1159  return false;
1160  }
1161 
1162  if (auto *Member =
1163  ExtendingEntity ? ExtendingEntity->getDecl() : nullptr) {
1164  bool IsPointer = !Member->getType()->isReferenceType();
1165  SemaRef.Diag(DiagLoc,
1166  IsPointer ? diag::warn_init_ptr_member_to_parameter_addr
1167  : diag::warn_bind_ref_member_to_parameter)
1168  << Member << VD << isa<ParmVarDecl>(VD) << DiagRange;
1169  SemaRef.Diag(Member->getLocation(),
1170  diag::note_ref_or_ptr_member_declared_here)
1171  << (unsigned)IsPointer;
1172  }
1173  }
1174  break;
1175  }
1176 
1177  case LK_New:
1178  if (isa<MaterializeTemporaryExpr>(L)) {
1179  if (IsGslPtrValueFromGslTempOwner)
1180  SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer)
1181  << DiagRange;
1182  else
1183  SemaRef.Diag(DiagLoc, RK == RK_ReferenceBinding
1184  ? diag::warn_new_dangling_reference
1185  : diag::warn_new_dangling_initializer_list)
1186  << !InitEntity->getParent() << DiagRange;
1187  } else {
1188  // We can't determine if the allocation outlives the local declaration.
1189  return false;
1190  }
1191  break;
1192 
1193  case LK_Return:
1194  case LK_StmtExprResult:
1195  if (auto *DRE = dyn_cast<DeclRefExpr>(L)) {
1196  // We can't determine if the local variable outlives the statement
1197  // expression.
1198  if (LK == LK_StmtExprResult)
1199  return false;
1200  SemaRef.Diag(DiagLoc, diag::warn_ret_stack_addr_ref)
1201  << InitEntity->getType()->isReferenceType() << DRE->getDecl()
1202  << isa<ParmVarDecl>(DRE->getDecl()) << DiagRange;
1203  } else if (isa<BlockExpr>(L)) {
1204  SemaRef.Diag(DiagLoc, diag::err_ret_local_block) << DiagRange;
1205  } else if (isa<AddrLabelExpr>(L)) {
1206  // Don't warn when returning a label from a statement expression.
1207  // Leaving the scope doesn't end its lifetime.
1208  if (LK == LK_StmtExprResult)
1209  return false;
1210  SemaRef.Diag(DiagLoc, diag::warn_ret_addr_label) << DiagRange;
1211  } else if (auto *CLE = dyn_cast<CompoundLiteralExpr>(L)) {
1212  SemaRef.Diag(DiagLoc, diag::warn_ret_stack_addr_ref)
1213  << InitEntity->getType()->isReferenceType() << CLE->getInitializer()
1214  << 2 << DiagRange;
1215  } else {
1216  // P2748R5: Disallow Binding a Returned Glvalue to a Temporary.
1217  // [stmt.return]/p6: In a function whose return type is a reference,
1218  // other than an invented function for std::is_convertible ([meta.rel]),
1219  // a return statement that binds the returned reference to a temporary
1220  // expression ([class.temporary]) is ill-formed.
1221  if (SemaRef.getLangOpts().CPlusPlus26 &&
1222  InitEntity->getType()->isReferenceType())
1223  SemaRef.Diag(DiagLoc, diag::err_ret_local_temp_ref)
1224  << InitEntity->getType()->isReferenceType() << DiagRange;
1225  else
1226  SemaRef.Diag(DiagLoc, diag::warn_ret_local_temp_addr_ref)
1227  << InitEntity->getType()->isReferenceType() << DiagRange;
1228  }
1229  break;
1230  }
1231 
1232  for (unsigned I = 0; I != Path.size(); ++I) {
1233  auto Elem = Path[I];
1234 
1235  switch (Elem.Kind) {
1236  case IndirectLocalPathEntry::AddressOf:
1237  case IndirectLocalPathEntry::LValToRVal:
1238  // These exist primarily to mark the path as not permitting or
1239  // supporting lifetime extension.
1240  break;
1241 
1242  case IndirectLocalPathEntry::LifetimeBoundCall:
1243  case IndirectLocalPathEntry::TemporaryCopy:
1244  case IndirectLocalPathEntry::GslPointerInit:
1245  case IndirectLocalPathEntry::GslReferenceInit:
1246  case IndirectLocalPathEntry::GslPointerAssignment:
1247  // FIXME: Consider adding a note for these.
1248  break;
1249 
1250  case IndirectLocalPathEntry::DefaultInit: {
1251  auto *FD = cast<FieldDecl>(Elem.D);
1252  SemaRef.Diag(FD->getLocation(),
1253  diag::note_init_with_default_member_initializer)
1254  << FD << nextPathEntryRange(Path, I + 1, L);
1255  break;
1256  }
1257 
1258  case IndirectLocalPathEntry::VarInit: {
1259  const VarDecl *VD = cast<VarDecl>(Elem.D);
1260  SemaRef.Diag(VD->getLocation(), diag::note_local_var_initializer)
1261  << VD->getType()->isReferenceType() << VD->isImplicit()
1262  << VD->getDeclName() << nextPathEntryRange(Path, I + 1, L);
1263  break;
1264  }
1265 
1266  case IndirectLocalPathEntry::LambdaCaptureInit:
1267  if (!Elem.Capture->capturesVariable())
1268  break;
1269  // FIXME: We can't easily tell apart an init-capture from a nested
1270  // capture of an init-capture.
1271  const ValueDecl *VD = Elem.Capture->getCapturedVar();
1272  SemaRef.Diag(Elem.Capture->getLocation(),
1273  diag::note_lambda_capture_initializer)
1274  << VD << VD->isInitCapture() << Elem.Capture->isExplicit()
1275  << (Elem.Capture->getCaptureKind() == LCK_ByRef) << VD
1276  << nextPathEntryRange(Path, I + 1, L);
1277  break;
1278  }
1279  }
1280 
1281  // We didn't lifetime-extend, so don't go any further; we don't need more
1282  // warnings or errors on inner temporaries within this one's initializer.
1283  return false;
1284  };
1285 
1287  if (EnableLifetimeWarnings && LK == LK_Assignment &&
1288  isRecordWithAttr<PointerAttr>(AEntity->LHS->getType()))
1289  Path.push_back({IndirectLocalPathEntry::GslPointerAssignment, Init});
1290 
1291  if (Init->isGLValue())
1292  visitLocalsRetainedByReferenceBinding(Path, Init, RK_ReferenceBinding,
1293  TemporaryVisitor,
1294  EnableLifetimeWarnings);
1295  else
1297  Path, Init, TemporaryVisitor,
1298  // Don't revisit the sub inits for the intialization case.
1299  /*RevisitSubinits=*/!InitEntity, EnableLifetimeWarnings);
1300 }
1301 
1302 void checkExprLifetime(Sema &SemaRef, const InitializedEntity &Entity,
1303  Expr *Init) {
1304  auto LTResult = getEntityLifetime(&Entity);
1305  LifetimeKind LK = LTResult.getInt();
1306  const InitializedEntity *ExtendingEntity = LTResult.getPointer();
1307  bool EnableLifetimeWarnings = !SemaRef.getDiagnostics().isIgnored(
1308  diag::warn_dangling_lifetime_pointer, SourceLocation());
1309  checkExprLifetimeImpl(SemaRef, &Entity, ExtendingEntity, LK,
1310  /*AEntity*/ nullptr, Init, EnableLifetimeWarnings);
1311 }
1312 
1313 void checkExprLifetime(Sema &SemaRef, const AssignedEntity &Entity,
1314  Expr *Init) {
1315  bool EnableLifetimeWarnings = !SemaRef.getDiagnostics().isIgnored(
1316  diag::warn_dangling_lifetime_pointer, SourceLocation());
1317  bool RunAnalysis = Entity.LHS->getType()->isPointerType() ||
1318  (EnableLifetimeWarnings &&
1319  isRecordWithAttr<PointerAttr>(Entity.LHS->getType()));
1320 
1321  if (!RunAnalysis)
1322  return;
1323 
1324  checkExprLifetimeImpl(SemaRef, /*InitEntity=*/nullptr,
1325  /*ExtendingEntity=*/nullptr, LK_Assignment, &Entity,
1326  Init, EnableLifetimeWarnings);
1327 }
1328 
1329 } // namespace clang::sema
const Decl * D
IndirectLocalPath & Path
enum clang::sema::@1659::IndirectLocalPathEntry::EntryKind Kind
const LambdaCapture * Capture
Expr * E
unsigned OldSize
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:187
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2649
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Type source information for an attributed type.
Definition: TypeLoc.h:875
const T * getAttrAs()
Definition: TypeLoc.h:905
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
Definition: TypeLoc.h:889
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1491
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2064
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3550
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2090
bool isStdNamespace() const
Definition: DeclBase.cpp:1317
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
bool isInStdNamespace() const
Definition: DeclBase.cpp:425
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:523
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:600
SourceLocation getLocation() const
Definition: DeclBase.h:446
bool hasAttr() const
Definition: DeclBase.h:584
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:761
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Definition: Diagnostic.h:922
This represents one expression.
Definition: Expr.h:110
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3110
QualType getType() const
Definition: Expr.h:142
Represents a function declaration or definition.
Definition: Decl.h:1933
QualType getReturnType() const
Definition: Decl.h:2718
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition: Decl.cpp:3682
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2670
One of these records is kept for each identifier that is lexed.
Describes an C or C++ initializer list.
Definition: Expr.h:5070
Describes an entity that is being initialized.
EntityKind getKind() const
Determine the kind of initialization.
unsigned allocateManglingNumber() const
QualType getType() const
Retrieve type being initialized.
ValueDecl * getDecl() const
Retrieve the variable, parameter, or field being initialized.
Definition: SemaInit.cpp:3630
@ EK_Variable
The entity being initialized is a variable.
@ EK_Temporary
The entity being initialized is a temporary object.
@ EK_Binding
The entity being initialized is a structured binding of a decomposition declaration.
@ EK_BlockElement
The entity being initialized is a field of block descriptor for the copied-in c++ object.
@ EK_Parameter_CF_Audited
The entity being initialized is a function parameter; function is member of group of audited CF APIs.
@ EK_LambdaToBlockConversionBlockElement
The entity being initialized is a field of block descriptor for the copied-in lambda object that's us...
@ EK_Member
The entity being initialized is a non-static data member subobject.
@ EK_Base
The entity being initialized is a base member subobject.
@ EK_Result
The entity being initialized is the result of a function call.
@ EK_TemplateParameter
The entity being initialized is a non-type template parameter.
@ EK_StmtExprResult
The entity being initialized is the result of a statement expression.
@ EK_ParenAggInitMember
The entity being initialized is a non-static data member subobject of an object initialized via paren...
@ EK_VectorElement
The entity being initialized is an element of a vector.
@ EK_New
The entity being initialized is an object (or array of objects) allocated via new.
@ EK_CompoundLiteralInit
The entity being initialized is the initializer for a compound literal.
@ EK_Parameter
The entity being initialized is a function parameter.
@ EK_Delegating
The initialization is being done by a delegating constructor.
@ EK_ComplexElement
The entity being initialized is the real or imaginary part of a complex number.
@ EK_ArrayElement
The entity being initialized is an element of an array.
@ EK_LambdaCapture
The entity being initialized is the field that captures a variable in a lambda.
@ EK_Exception
The entity being initialized is an exception object that is being thrown.
@ EK_RelatedResult
The entity being implicitly initialized back to the formal result type.
const InitializedEntity * getParent() const
Retrieve the parent of the entity being initialized, when the initialization itself is occurring with...
bool isDefaultMemberInitializer() const
Is this the default member initializer of a member (specified inside the class definition)?
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
bool capturesVariable() const
Determine whether this capture handles a variable.
Definition: LambdaCapture.h:88
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
A (possibly-)qualified type.
Definition: Type.h:941
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:64
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:493
const LangOptions & getLangOpts() const
Definition: Sema.h:553
static bool CanBeGetReturnObject(const FunctionDecl *FD)
Definition: SemaDecl.cpp:15916
DiagnosticsEngine & getDiagnostics() const
Definition: Sema.h:557
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:59
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition: TypeLoc.h:2684
A container of type source information.
Definition: Type.h:7731
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:256
The base class of the type hierarchy.
Definition: Type.h:1829
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1882
bool isPointerType() const
Definition: Type.h:8013
bool isReferenceType() const
Definition: Type.h:8031
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
Definition: Type.cpp:1867
bool isLValueReferenceType() const
Definition: Type.h:8035
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2240
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:668
QualType getType() const
Definition: Decl.h:679
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
Definition: Decl.cpp:5374
Represents a variable declaration or definition.
Definition: Decl.h:880
static Base getBase(const StringRef IntegerLiteral)
@ RunAnalysis
Run one or more source code analyses.
bool InitField(InterpState &S, CodePtr OpPC, uint32_t I)
1) Pops the value from the stack 2) Peeks a pointer from the stack 3) Pushes the value to field I of ...
Definition: Interp.h:1415
bool LE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:1103
bool Init(InterpState &S, CodePtr OpPC)
Definition: Interp.h:1745
static bool pathContainsInit(IndirectLocalPath &Path)
static void checkExprLifetimeImpl(Sema &SemaRef, const InitializedEntity *InitEntity, const InitializedEntity *ExtendingEntity, LifetimeKind LK, const AssignedEntity *AEntity, Expr *Init, bool EnableLifetimeWarnings)
static bool isVarOnPath(IndirectLocalPath &Path, VarDecl *VD)
static bool isInStlNamespace(const Decl *D)
static void handleGslAnnotatedTypes(IndirectLocalPath &Path, Expr *Call, LocalVisitor Visit)
static bool isRecordWithAttr(QualType Type)
static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, Expr *Init, LocalVisitor Visit, bool RevisitSubinits, bool EnableLifetimeWarnings)
Visit the locals that would be reachable through an object initialized by the prvalue expression Init...
static bool shouldTrackFirstArgument(const FunctionDecl *FD)
static bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD)
void checkExprLifetime(Sema &SemaRef, const AssignedEntity &Entity, Expr *Init)
Check that the lifetime of the given expr (and its subobjects) is sufficient for assigning to the ent...
static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, Expr *Init, ReferenceKind RK, LocalVisitor Visit, bool EnableLifetimeWarnings)
Visit the locals that would be reachable through a reference bound to the glvalue expression Init.
static SourceRange nextPathEntryRange(const IndirectLocalPath &Path, unsigned I, Expr *E)
Find the range for the first interesting entry in the path at or after I.
static LifetimeResult getEntityLifetime(const InitializedEntity *Entity, const InitializedEntity *InitField=nullptr)
Determine the declaration which an initialized entity ultimately refers to, for the purpose of lifeti...
PathLifetimeKind
Whether a path to an object supports lifetime extension.
@ NoExtend
Do not lifetime extend along this path.
@ ShouldExtend
We should lifetime-extend, but we don't because (due to technical limitations) we can't.
@ Extend
Lifetime-extend along this path.
static bool pathOnlyHandlesGslPointer(IndirectLocalPath &Path)
static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee)
static void visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call, LocalVisitor Visit)
static PathLifetimeKind shouldLifetimeExtendThroughPath(const IndirectLocalPath &Path)
Determine whether this is an indirect path to a temporary that we are supposed to lifetime-extend alo...
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
bool isCompoundAssignmentOperator(OverloadedOperatorKind Kind)
Determine if this is a compound assignment operator.
Definition: OperatorKinds.h:53
LLVM_READONLY bool isUppercase(unsigned char c)
Return true if this character is an uppercase ASCII letter: [A-Z].
Definition: CharInfo.h:126
@ LCK_ByRef
Capturing by reference.
Definition: Lambda.h:37
BinaryOperatorKind
const FunctionProtoType * T
#define bool
Definition: stdbool.h:24
Describes an entity that is being assigned.