https://github.com/NeKon69 created https://github.com/llvm/llvm-project/pull/189907
This PR adds origin flow from `[[clang::lifetimebound]]` constructor arguments during `gsl::Pointer` construction. Fixes #175898 >From 4f237572faa6ba6320b95ef5e6095ed4076e22c0 Mon Sep 17 00:00:00 2001 From: NeKon69 <[email protected]> Date: Tue, 31 Mar 2026 11:56:30 +0300 Subject: [PATCH 1/2] [LifetimeSafety] apply basic fix and update the test --- clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp | 5 +++++ clang/test/Sema/warn-lifetime-analysis-nocfg.cpp | 12 +++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp index 861e1f6fa8a33..b55eeb59ac34d 100644 --- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp +++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp @@ -712,6 +712,11 @@ void FactsGenerator::handleFunctionCall(const Expr *Call, CallList->getOuterOriginID(), ArgList->getOuterOriginID(), KillSrc)); KillSrc = false; + } else if (IsArgLifetimeBound(I)) { + CurrentBlockFacts.push_back(FactMgr.createFact<OriginFlowFact>( + CallList->getOuterOriginID(), ArgList->getOuterOriginID(), + KillSrc)); + KillSrc = false; } } else if (shouldTrackPointerImplicitObjectArg(I)) { assert(ArgList->getLength() >= 2 && diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp index d58f23e4b554c..0ed151b9db136 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -931,13 +931,11 @@ struct [[gsl::Pointer]] Pointer { Pointer(const Bar & bar [[clang::lifetimebound]]); }; Pointer test3(Bar bar) { - // FIXME: Detect this using the CFG-based lifetime analysis (constructor of a pointer). - // https://github.com/llvm/llvm-project/issues/175898 - Pointer p = Pointer(Bar()); // expected-warning {{temporary}} - use(p); - p = Pointer(Bar()); // expected-warning {{object backing}} - use(p); - return bar; // expected-warning {{address of stack}} + Pointer p = Pointer(Bar()); // expected-warning {{temporary}} cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + use(p); // cfg-note {{later used here}} + p = Pointer(Bar()); // expected-warning {{object backing}} cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + use(p); // cfg-note {{later used here}} + return bar; // expected-warning {{address of stack}} cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} } template<typename T> >From 610a9a48d4ccc0da8a293d4e60a3391b288caafe Mon Sep 17 00:00:00 2001 From: NeKon69 <[email protected]> Date: Wed, 1 Apr 2026 10:58:02 +0300 Subject: [PATCH 2/2] combine checks into one, update the comment --- .../lib/Analysis/LifetimeSafety/FactsGenerator.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp index b55eeb59ac34d..b314ac45c5760 100644 --- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp +++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp @@ -704,15 +704,10 @@ void FactsGenerator::handleFunctionCall(const Expr *Call, assert(!Args[I]->isGLValue() || ArgList->getLength() >= 2); ArgList = getRValueOrigins(Args[I], ArgList); } - if (isGslOwnerType(Args[I]->getType())) { - // The constructed gsl::Pointer borrows from the Owner's storage, not - // from what the Owner itself borrows, so only the outermost origin is - // needed. - CurrentBlockFacts.push_back(FactMgr.createFact<OriginFlowFact>( - CallList->getOuterOriginID(), ArgList->getOuterOriginID(), - KillSrc)); - KillSrc = false; - } else if (IsArgLifetimeBound(I)) { + if (isGslOwnerType(Args[I]->getType()) || IsArgLifetimeBound(I)) { + // The constructed gsl::Pointer is dependent on the argument itself, not + // on anything the argument is dependent on, so only the outermost + // origin is needed. CurrentBlockFacts.push_back(FactMgr.createFact<OriginFlowFact>( CallList->getOuterOriginID(), ArgList->getOuterOriginID(), KillSrc)); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
