Author: NeKon69 Date: 2026-04-02T21:59:39+01:00 New Revision: 5669dfc68b5df3f3c6db6428d48c898358707982
URL: https://github.com/llvm/llvm-project/commit/5669dfc68b5df3f3c6db6428d48c898358707982 DIFF: https://github.com/llvm/llvm-project/commit/5669dfc68b5df3f3c6db6428d48c898358707982.diff LOG: [LifetimeSafety] Propagate loans through pointer arithmetic (#189546) This PR adds loan propagation for pointer arithmetic. It also updates the tests to match the new behavior. Fixes #180933 Added: Modified: clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp clang/test/Sema/warn-lifetime-safety-suggestions.cpp clang/test/Sema/warn-lifetime-safety.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h index 775b51afa0237..8fe2436b04086 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h @@ -64,6 +64,8 @@ class FactsGenerator : public ConstStmtVisitor<FactsGenerator> { void handleAssignment(const Expr *LHSExpr, const Expr *RHSExpr); + void handlePointerArithmetic(const BinaryOperator *BO); + void handleCXXCtorInitializer(const CXXCtorInitializer *CII); void handleLifetimeEnds(const CFGLifetimeEnds &LifetimeEnds); diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp index 861e1f6fa8a33..75f2978d848b7 100644 --- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp +++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp @@ -378,11 +378,22 @@ void FactsGenerator::handleAssignment(const Expr *LHSExpr, flow(LHSList->peelOuterOrigin(), RHSList, /*Kill=*/true); } +void FactsGenerator::handlePointerArithmetic(const BinaryOperator *BO) { + if (Expr *RHS = BO->getRHS(); RHS->getType()->isPointerType()) { + killAndFlowOrigin(*BO, *RHS); + return; + } + Expr *LHS = BO->getLHS(); + assert(LHS->getType()->isPointerType() && + "Pointer arithmetic must have a pointer operand"); + killAndFlowOrigin(*BO, *LHS); +} + void FactsGenerator::VisitBinaryOperator(const BinaryOperator *BO) { - // TODO: Handle pointer arithmetic (e.g., `p + 1` or `1 + p`) where the - // result should have the same loans as the pointer operand. if (BO->isCompoundAssignmentOp()) return; + if (BO->getType()->isPointerType() && BO->isAdditiveOp()) + handlePointerArithmetic(BO); handleUse(BO->getRHS()); if (BO->isAssignmentOp()) handleAssignment(BO->getLHS(), BO->getRHS()); diff --git a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp index 22e4f3d1e487b..19c3251b9c296 100644 --- a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp +++ b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp @@ -436,6 +436,9 @@ struct MemberArrayReturn { int* getData() { // expected-warning {{implicit this in intra-TU function should be marked [[clang::lifetimebound]]}} return arr; // expected-note {{param returned here}} } + int* getLast() { // expected-warning {{implicit this in intra-TU function should be marked [[clang::lifetimebound]]}} + return arr + 10; // expected-note {{param returned here}} + } }; } // namespace array diff --git a/clang/test/Sema/warn-lifetime-safety.cpp b/clang/test/Sema/warn-lifetime-safety.cpp index 88a502491e6c0..9b867e0fe1567 100644 --- a/clang/test/Sema/warn-lifetime-safety.cpp +++ b/clang/test/Sema/warn-lifetime-safety.cpp @@ -2069,14 +2069,19 @@ int* static_array() { return &a[1]; } -// FIXME: Pointer arithmetic is not yet tracked. void pointer_arithmetic_use_after_scope() { int* p; + int* p2; + int* p3; { int a[10]{}; - p = a + 5; - } - (void)*p; // Should warn. + p = a + 5; // expected-warning {{object whose reference is captured does not live long enough}} + p2 = a - 5; // expected-warning {{object whose reference is captured does not live long enough}} + p3 = 5 + a; // expected-warning {{object whose reference is captured does not live long enough}} + } // expected-note 3 {{destroyed here}} + (void)*p; // expected-note {{later used here}} + (void)*p2; // expected-note {{later used here}} + (void)*p3; // expected-note {{later used here}} } // FIXME: Copying a pointer value out of an array element is not tracked. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
