@@ -326,24 +326,11 @@ static bool shouldTrackFirstArgument(const FunctionDecl *FD) {
326326 return false ;
327327}
328328
329- static bool implicitObjectParamIsLifetimeBound (const FunctionDecl *FD) {
330- const TypeSourceInfo *TSI = FD->getTypeSourceInfo ();
331- if (!TSI)
332- return false ;
333- // Don't declare this variable in the second operand of the for-statement;
334- // GCC miscompiles that by ending its lifetime before evaluating the
335- // third operand. See gcc.gnu.org/PR86769.
336- AttributedTypeLoc ATL;
337- for (TypeLoc TL = TSI->getTypeLoc ();
338- (ATL = TL.getAsAdjusted <AttributedTypeLoc>());
339- TL = ATL.getModifiedLoc ()) {
340- if (ATL.getAttrAs <LifetimeBoundAttr>())
341- return true ;
342- }
343-
344- // Assume that all assignment operators with a "normal" return type return
345- // *this, that is, an lvalue reference that is the same type as the implicit
346- // object parameter (or the LHS for a non-member operator$=).
329+ // Return true if this is an "normal" assignment operator.
330+ // We assuments that a normal assingment operator always returns *this, that is,
331+ // an lvalue reference that is the same type as the implicit object parameter
332+ // (or the LHS for a non-member operator$=).
333+ static bool isNormalAsisgnmentOperator (const FunctionDecl *FD) {
347334 OverloadedOperatorKind OO = FD->getDeclName ().getCXXOverloadedOperator ();
348335 if (OO == OO_Equal || isCompoundAssignmentOperator (OO)) {
349336 QualType RetT = FD->getReturnType ();
@@ -359,10 +346,27 @@ static bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) {
359346 return true ;
360347 }
361348 }
362-
363349 return false ;
364350}
365351
352+ static bool implicitObjectParamIsLifetimeBound (const FunctionDecl *FD) {
353+ const TypeSourceInfo *TSI = FD->getTypeSourceInfo ();
354+ if (!TSI)
355+ return false ;
356+ // Don't declare this variable in the second operand of the for-statement;
357+ // GCC miscompiles that by ending its lifetime before evaluating the
358+ // third operand. See gcc.gnu.org/PR86769.
359+ AttributedTypeLoc ATL;
360+ for (TypeLoc TL = TSI->getTypeLoc ();
361+ (ATL = TL.getAsAdjusted <AttributedTypeLoc>());
362+ TL = ATL.getModifiedLoc ()) {
363+ if (ATL.getAttrAs <LifetimeBoundAttr>())
364+ return true ;
365+ }
366+
367+ return isNormalAsisgnmentOperator (FD);
368+ }
369+
366370// Visit lifetimebound or gsl-pointer arguments.
367371static void visitFunctionCallArguments (IndirectLocalPath &Path, Expr *Call,
368372 LocalVisitor Visit,
@@ -968,6 +972,22 @@ static bool pathOnlyHandlesGslPointer(IndirectLocalPath &Path) {
968972 return false ;
969973}
970974
975+ static bool isAssginmentOperatorLifetimeBound (CXXMethodDecl *CMD) {
976+ if (!CMD)
977+ return false ;
978+ return isNormalAsisgnmentOperator (CMD) && CMD->param_size () == 1 &&
979+ CMD->getParamDecl (0 )->hasAttr <LifetimeBoundAttr>();
980+ }
981+
982+ static bool shouldRunGSLAssignmentAnalysis (const Sema &SemaRef,
983+ const AssignedEntity &Entity) {
984+ bool EnableGSLAssignmentWarnings = !SemaRef.getDiagnostics ().isIgnored (
985+ diag::warn_dangling_lifetime_pointer_assignment, SourceLocation ());
986+ return (EnableGSLAssignmentWarnings &&
987+ (isRecordWithAttr<PointerAttr>(Entity.LHS ->getType ()) ||
988+ isAssginmentOperatorLifetimeBound (Entity.AssignmentOperator )));
989+ }
990+
971991static void checkExprLifetimeImpl (Sema &SemaRef,
972992 const InitializedEntity *InitEntity,
973993 const InitializedEntity *ExtendingEntity,
@@ -1267,8 +1287,7 @@ static void checkExprLifetimeImpl(Sema &SemaRef,
12671287 };
12681288
12691289 llvm::SmallVector<IndirectLocalPathEntry, 8 > Path;
1270- if (EnableLifetimeWarnings && LK == LK_Assignment &&
1271- isRecordWithAttr<PointerAttr>(AEntity->LHS ->getType ()))
1290+ if (LK == LK_Assignment && shouldRunGSLAssignmentAnalysis (SemaRef, *AEntity))
12721291 Path.push_back ({IndirectLocalPathEntry::GslPointerAssignment, Init});
12731292
12741293 if (Init->isGLValue ())
@@ -1301,8 +1320,7 @@ void checkExprLifetime(Sema &SemaRef, const AssignedEntity &Entity,
13011320 diag::warn_dangling_pointer_assignment, SourceLocation ());
13021321 bool RunAnalysis = (EnableDanglingPointerAssignment &&
13031322 Entity.LHS ->getType ()->isPointerType ()) ||
1304- (EnableLifetimeWarnings &&
1305- isRecordWithAttr<PointerAttr>(Entity.LHS ->getType ()));
1323+ shouldRunGSLAssignmentAnalysis (SemaRef, Entity);
13061324
13071325 if (!RunAnalysis)
13081326 return ;
0 commit comments