https://github.com/aeft updated https://github.com/llvm/llvm-project/pull/184295
>From 746e45f465c57d7503de664f8239cdc2eebf39d9 Mon Sep 17 00:00:00 2001 From: Alex Wang <[email protected]> Date: Mon, 2 Mar 2026 23:34:35 -0800 Subject: [PATCH 1/2] [LifetimeSafety] Detect use of a reference type as a use of underlying origin --- clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp | 3 ++- clang/test/Sema/warn-lifetime-safety-invalidations.cpp | 8 +++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp index 80a73a2bf687e..90d604100438b 100644 --- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp +++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp @@ -366,7 +366,8 @@ void FactsGenerator::handleAssignment(const Expr *LHSExpr, // assigned. RHSList = getRValueOrigins(RHSExpr, RHSList); - if (const auto *DRE_LHS = dyn_cast<DeclRefExpr>(LHSExpr)) + if (const auto *DRE_LHS = dyn_cast<DeclRefExpr>(LHSExpr); + DRE_LHS && !DRE_LHS->getDecl()->getType()->isReferenceType()) markUseAsWrite(DRE_LHS); // Kill the old loans of the destination origin and flow the new loans // from the source origin. diff --git a/clang/test/Sema/warn-lifetime-safety-invalidations.cpp b/clang/test/Sema/warn-lifetime-safety-invalidations.cpp index 486edd7a1a023..6820823bd7f7f 100644 --- a/clang/test/Sema/warn-lifetime-safety-invalidations.cpp +++ b/clang/test/Sema/warn-lifetime-safety-invalidations.cpp @@ -259,11 +259,9 @@ namespace ElementReferences { void ReferenceToVectorElement() { std::vector<int> v = {1, 2, 3}; - int& ref = v[0]; - v.push_back(4); - // FIXME: Detect this as a use of 'ref'. - // https://github.com/llvm/llvm-project/issues/180187 - ref = 10; + int& ref = v[0]; // expected-warning {{object whose reference is captured is later invalidated}} + v.push_back(4); // expected-note {{invalidated here}} + ref = 10; // expected-note {{later used here}} (void)ref; } >From 3cd496a35b4a46f341911250f0346026ab71968d Mon Sep 17 00:00:00 2001 From: Alex Wang <[email protected]> Date: Tue, 3 Mar 2026 12:49:12 -0800 Subject: [PATCH 2/2] fix reference to pointer --- clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp | 8 +++++--- .../test/Sema/warn-lifetime-safety-invalidations.cpp | 12 ++++++++++++ clang/test/Sema/warn-lifetime-safety.cpp | 12 ++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp index 90d604100438b..b6afecfe55281 100644 --- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp +++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp @@ -366,9 +366,11 @@ void FactsGenerator::handleAssignment(const Expr *LHSExpr, // assigned. RHSList = getRValueOrigins(RHSExpr, RHSList); - if (const auto *DRE_LHS = dyn_cast<DeclRefExpr>(LHSExpr); - DRE_LHS && !DRE_LHS->getDecl()->getType()->isReferenceType()) - markUseAsWrite(DRE_LHS); + if (const auto *DRE_LHS = dyn_cast<DeclRefExpr>(LHSExpr)) { + QualType QT = DRE_LHS->getDecl()->getType(); + if (!QT->isReferenceType() || hasOrigins(QT->getPointeeType())) + markUseAsWrite(DRE_LHS); + } // Kill the old loans of the destination origin and flow the new loans // from the source origin. flow(LHSList->peelOuterOrigin(), RHSList, /*Kill=*/true); diff --git a/clang/test/Sema/warn-lifetime-safety-invalidations.cpp b/clang/test/Sema/warn-lifetime-safety-invalidations.cpp index 6820823bd7f7f..bab4b28a9e172 100644 --- a/clang/test/Sema/warn-lifetime-safety-invalidations.cpp +++ b/clang/test/Sema/warn-lifetime-safety-invalidations.cpp @@ -265,6 +265,18 @@ void ReferenceToVectorElement() { (void)ref; } +void PointerRefToVectorElement() { + std::vector<int*> v = {nullptr, nullptr}; + int*& ref = v[0]; + v.push_back(nullptr); + // FIXME: Writing through a reference to an invalidated vector element + // should be detected. Origin_outer (reference binding) is incorrectly + // killed by markUseAsWrite. + int y; + ref = &y; + (void)*ref; +} + void PointerToVectorElement() { std::vector<int> v = {1, 2, 3}; int* ptr = &v[0]; // expected-warning {{object whose reference is captured is later invalidated}} diff --git a/clang/test/Sema/warn-lifetime-safety.cpp b/clang/test/Sema/warn-lifetime-safety.cpp index 76d43445f8636..866542303414a 100644 --- a/clang/test/Sema/warn-lifetime-safety.cpp +++ b/clang/test/Sema/warn-lifetime-safety.cpp @@ -752,6 +752,18 @@ void no_error_if_dangle_then_rescue_gsl() { v.use(); // This is safe. } +void no_error_if_dangle_then_rescue_via_ref() { + MyObj safe; + MyObj* p; + MyObj*& ref = p; + { + MyObj temp; + ref = &temp; // p temporarily points to temp via ref. + } + ref = &safe; // p is "rescued" via ref before use. + (void)*ref; // This is safe. +} + void no_error_loan_from_current_iteration(bool cond) { // See https://github.com/llvm/llvm-project/issues/156959. MyObj b; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
