@@ -45,10 +45,14 @@ enum LifetimeKind {
4545 // / a default member initializer), the program is ill-formed.
4646 LK_MemInitializer,
4747
48- // / The lifetime of a temporary bound to this entity probably ends too soon,
48+ // / The lifetime of a temporary bound to this entity may end too soon,
4949 // / because the entity is a pointer and we assign the address of a temporary
5050 // / object to it.
5151 LK_Assignment,
52+
53+ // / The lifetime of a temporary bound to this entity may end too soon,
54+ // / because the entity may capture the reference to a temporary object.
55+ LK_LifetimeCapture,
5256};
5357using LifetimeResult =
5458 llvm::PointerIntPair<const InitializedEntity *, 3 , LifetimeKind>;
@@ -1108,13 +1112,14 @@ static bool shouldRunGSLAssignmentAnalysis(const Sema &SemaRef,
11081112 isAssignmentOperatorLifetimeBound (Entity.AssignmentOperator )));
11091113}
11101114
1111- static void checkExprLifetimeImpl (Sema &SemaRef,
1112- const InitializedEntity *InitEntity,
1113- const InitializedEntity *ExtendingEntity,
1114- LifetimeKind LK,
1115- const AssignedEntity *AEntity, Expr *Init) {
1116- assert ((AEntity && LK == LK_Assignment) ||
1117- (InitEntity && LK != LK_Assignment));
1115+ static void
1116+ checkExprLifetimeImpl (Sema &SemaRef, const InitializedEntity *InitEntity,
1117+ const InitializedEntity *ExtendingEntity, LifetimeKind LK,
1118+ const AssignedEntity *AEntity,
1119+ const CapturingEntity *CapEntity, Expr *Init) {
1120+ assert (!AEntity || LK == LK_Assignment);
1121+ assert (!CapEntity || LK == LK_LifetimeCapture);
1122+ assert (!InitEntity || (LK != LK_Assignment && LK != LK_LifetimeCapture));
11181123 // If this entity doesn't have an interesting lifetime, don't bother looking
11191124 // for temporaries within its initializer.
11201125 if (LK == LK_FullExpression)
@@ -1197,12 +1202,23 @@ static void checkExprLifetimeImpl(Sema &SemaRef,
11971202 break ;
11981203 }
11991204
1205+ case LK_LifetimeCapture: {
1206+ // The captured entity has lifetime beyond the full-expression,
1207+ // and the capturing entity does too, so don't warn.
1208+ if (!MTE)
1209+ return false ;
1210+ if (CapEntity->Entity )
1211+ SemaRef.Diag (DiagLoc, diag::warn_dangling_reference_captured)
1212+ << CapEntity->Entity << DiagRange;
1213+ else
1214+ SemaRef.Diag (DiagLoc, diag::warn_dangling_reference_captured_by_unknown)
1215+ << DiagRange;
1216+ return false ;
1217+ }
1218+
12001219 case LK_Assignment: {
12011220 if (!MTE || pathContainsInit (Path))
12021221 return false ;
1203- assert (shouldLifetimeExtendThroughPath (Path) ==
1204- PathLifetimeKind::NoExtend &&
1205- " No lifetime extension for assignments" );
12061222 if (IsGslPtrValueFromGslTempOwner)
12071223 SemaRef.Diag (DiagLoc, diag::warn_dangling_lifetime_pointer_assignment)
12081224 << AEntity->LHS << DiagRange;
@@ -1411,13 +1427,23 @@ static void checkExprLifetimeImpl(Sema &SemaRef,
14111427 };
14121428
14131429 llvm::SmallVector<IndirectLocalPathEntry, 8 > Path;
1414- if (LK == LK_Assignment &&
1415- shouldRunGSLAssignmentAnalysis (SemaRef, *AEntity)) {
1416- Path.push_back (
1417- {isAssignmentOperatorLifetimeBound (AEntity->AssignmentOperator )
1418- ? IndirectLocalPathEntry::LifetimeBoundCall
1419- : IndirectLocalPathEntry::GslPointerAssignment,
1420- Init});
1430+ switch (LK) {
1431+ case LK_Assignment: {
1432+ if (shouldRunGSLAssignmentAnalysis (SemaRef, *AEntity))
1433+ Path.push_back (
1434+ {isAssignmentOperatorLifetimeBound (AEntity->AssignmentOperator )
1435+ ? IndirectLocalPathEntry::LifetimeBoundCall
1436+ : IndirectLocalPathEntry::GslPointerAssignment,
1437+ Init});
1438+ break ;
1439+ }
1440+ case LK_LifetimeCapture: {
1441+ if (isPointerLikeType (Init->getType ()))
1442+ Path.push_back ({IndirectLocalPathEntry::GslPointerInit, Init});
1443+ break ;
1444+ }
1445+ default :
1446+ break ;
14211447 }
14221448
14231449 if (Init->isGLValue ())
@@ -1430,23 +1456,23 @@ static void checkExprLifetimeImpl(Sema &SemaRef,
14301456 /* RevisitSubinits=*/ !InitEntity);
14311457}
14321458
1433- void checkExprLifetime (Sema &SemaRef, const InitializedEntity &Entity,
1459+ void checkInitLifetime (Sema &SemaRef, const InitializedEntity &Entity,
14341460 Expr *Init) {
14351461 auto LTResult = getEntityLifetime (&Entity);
14361462 LifetimeKind LK = LTResult.getInt ();
14371463 const InitializedEntity *ExtendingEntity = LTResult.getPointer ();
14381464 checkExprLifetimeImpl (SemaRef, &Entity, ExtendingEntity, LK,
1439- /* AEntity*/ nullptr , Init);
1465+ /* AEntity= */ nullptr , /* CapEntity= */ nullptr , Init);
14401466}
14411467
14421468void checkExprLifetimeMustTailArg (Sema &SemaRef,
14431469 const InitializedEntity &Entity, Expr *Init) {
14441470 checkExprLifetimeImpl (SemaRef, &Entity, nullptr , LK_MustTail,
1445- /* AEntity*/ nullptr , Init);
1471+ /* AEntity= */ nullptr , /* CapEntity= */ nullptr , Init);
14461472}
14471473
1448- void checkExprLifetime (Sema &SemaRef, const AssignedEntity &Entity,
1449- Expr *Init) {
1474+ void checkAssignmentLifetime (Sema &SemaRef, const AssignedEntity &Entity,
1475+ Expr *Init) {
14501476 bool EnableDanglingPointerAssignment = !SemaRef.getDiagnostics ().isIgnored (
14511477 diag::warn_dangling_pointer_assignment, SourceLocation ());
14521478 bool RunAnalysis = (EnableDanglingPointerAssignment &&
@@ -1458,7 +1484,20 @@ void checkExprLifetime(Sema &SemaRef, const AssignedEntity &Entity,
14581484
14591485 checkExprLifetimeImpl (SemaRef, /* InitEntity=*/ nullptr ,
14601486 /* ExtendingEntity=*/ nullptr , LK_Assignment, &Entity,
1461- Init);
1487+ /* CapEntity=*/ nullptr , Init);
1488+ }
1489+
1490+ void checkCaptureByLifetime (Sema &SemaRef, const CapturingEntity &Entity,
1491+ Expr *Init) {
1492+ if (SemaRef.getDiagnostics ().isIgnored (diag::warn_dangling_reference_captured,
1493+ SourceLocation ()) &&
1494+ SemaRef.getDiagnostics ().isIgnored (
1495+ diag::warn_dangling_reference_captured_by_unknown, SourceLocation ()))
1496+ return ;
1497+ return checkExprLifetimeImpl (SemaRef, /* InitEntity=*/ nullptr ,
1498+ /* ExtendingEntity=*/ nullptr , LK_LifetimeCapture,
1499+ /* AEntity=*/ nullptr ,
1500+ /* CapEntity=*/ &Entity, Init);
14621501}
14631502
14641503} // namespace clang::sema
0 commit comments