diff --git a/clang/lib/Analysis/LifetimeSafety/Checker.cpp b/clang/lib/Analysis/LifetimeSafety/Checker.cpp index ad928c3754fea..5710761937718 100644 --- a/clang/lib/Analysis/LifetimeSafety/Checker.cpp +++ b/clang/lib/Analysis/LifetimeSafety/Checker.cpp @@ -133,7 +133,8 @@ class LifetimeChecker { return; if (PVD->hasAttr()) { // Track that this lifetimebound parameter correctly escapes. - VerifiedLiftimeboundEscapes.insert(PVD); + if (isa(OEF)) + VerifiedLiftimeboundEscapes.insert(PVD); } else { // Otherwise, suggest lifetimebound for parameter escaping through // return or a field in constructor. @@ -147,10 +148,12 @@ class LifetimeChecker { // field! }; auto CheckImplicitThis = [&](const CXXMethodDecl *MD) { - if (implicitObjectParamIsLifetimeBound(MD)) - VerifiedLiftimeboundEscapes.insert(MD); - else if (auto *ReturnEsc = dyn_cast(OEF)) - AnnotationWarningsMap.try_emplace(MD, ReturnEsc->getReturnExpr()); + if (auto *ReturnEsc = dyn_cast(OEF)) { + if (implicitObjectParamIsLifetimeBound(MD)) + VerifiedLiftimeboundEscapes.insert(MD); + else + AnnotationWarningsMap.try_emplace(MD, ReturnEsc->getReturnExpr()); + } }; auto MovedAtEscape = MovedLoans.getMovedLoans(OEF); for (LoanID LID : EscapedLoans) { diff --git a/clang/test/Sema/warn-lifetime-safety-lifetimebound.cpp b/clang/test/Sema/warn-lifetime-safety-lifetimebound.cpp index 5e22677f5269d..b0320bcbf4334 100644 --- a/clang/test/Sema/warn-lifetime-safety-lifetimebound.cpp +++ b/clang/test/Sema/warn-lifetime-safety-lifetimebound.cpp @@ -44,6 +44,24 @@ View return_alias_through_unannotated_passthrough( return not_lb(alias); } +View global_view; + +View assign_param_to_global( + const MyObj &obj [[clang::lifetimebound]]) { // expected-warning {{could not verify that the return value can be lifetime bound to 'obj'}} + global_view = obj; // Wrong kind of escape. + return View(); // Unrelated view. +} + +struct EnclosingState { + View member; + + View assign_param_to_field( + const MyObj &obj [[clang::lifetimebound]]) { // expected-warning {{could not verify that the return value can be lifetime bound to 'obj'}} + member = obj; // Wrong kind of escape. + return View(); // Unrelated view. + } +}; + View not_lb_view(View v); View lb_view(View v [[clang::lifetimebound]]);