https://github.com/NeKon69 created 
https://github.com/llvm/llvm-project/pull/189546

This PR adds loan propagation for pointer arithmetic.

It also updates the tests to match the new behavior.

Fixes #180933

>From 364fa6f3020e2d11c2e0d40e995ab7b4c3ce23a3 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Tue, 31 Mar 2026 00:21:57 +0300
Subject: [PATCH 1/3] [LifetimeSafety] propogate loans on pointer arithmetic

---
 .../Analyses/LifetimeSafety/FactsGenerator.h       |  2 ++
 .../lib/Analysis/LifetimeSafety/FactsGenerator.cpp | 14 ++++++++++++--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git 
a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
index dfcbdc7d73007..1bfd3fd5f2c1c 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
@@ -61,6 +61,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 6b61d7fd64fd7..29f4204345586 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -371,9 +371,19 @@ 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()) {
+    flowOrigin(*BO, *RHS);
+    return;
+  }
+  Expr *LHS = BO->getLHS();
+  assert(LHS->getType()->isPointerType() && "Unexpected operand was found");
+  flowOrigin(*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->getType()->isPointerType() && BO->isAdditiveOp())
+    handlePointerArithmetic(BO);
   if (BO->isCompoundAssignmentOp())
     return;
   handleUse(BO->getRHS());

>From 851993ed9f98b26e86ab028d09d7dc20bd9d91d4 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Tue, 31 Mar 2026 09:52:53 +0300
Subject: [PATCH 2/3] [LifetimeSfety] move check after compund assignment check
 and add tests

---
 clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp | 5 +++--
 clang/test/Sema/warn-lifetime-safety-suggestions.cpp | 7 +++++++
 clang/test/Sema/warn-lifetime-safety.cpp             | 7 +++----
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 29f4204345586..7db01392cc11f 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -382,10 +382,11 @@ void FactsGenerator::handlePointerArithmetic(const 
BinaryOperator *BO) {
 }
 
 void FactsGenerator::VisitBinaryOperator(const BinaryOperator *BO) {
-  if (BO->getType()->isPointerType() && BO->isAdditiveOp())
-    handlePointerArithmetic(BO);
   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 22c4222022ebf..3591270306827 100644
--- a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
@@ -438,4 +438,11 @@ struct MemberArrayReturn {
   }
 };
 
+struct MemberPointerArithmeticReturn {
+    int arr[10];
+    int* end() {         // 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 76d43445f8636..4e2c69c7fb2b8 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -2070,14 +2070,13 @@ int* static_array() {
   return &a[1];
 }
 
-// FIXME: Pointer arithmetic is not yet tracked.
 void pointer_arithmetic_use_after_scope() {
   int* p;
   {
     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}}
+  }            // expected-note {{destroyed here}}
+  (void)*p;    // expected-note {{later used here}}
 }
 
 // FIXME: Copying a pointer value out of an array element is not tracked.

>From edece21a757b81e91e706d7224258e33e087a3d0 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Tue, 31 Mar 2026 09:55:30 +0300
Subject: [PATCH 3/3] move test into existing struct

---
 clang/test/Sema/warn-lifetime-safety-suggestions.cpp | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp 
b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
index 3591270306827..d776c1067e4d0 100644
--- a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
@@ -436,13 +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}}
   }
-};
-
-struct MemberPointerArithmeticReturn {
-    int arr[10];
-    int* end() {         // expected-warning {{implicit this in intra-TU 
function should be marked [[clang::lifetimebound]]}}
-        return arr + 10; // 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

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to