llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-temporal-safety

@llvm/pr-subscribers-clang

Author: Utkarsh Saxena (usx95)

<details>
<summary>Changes</summary>

Fixes an off-by-one crash in the lifetime_capture_by attribute handling. The 
CapturingArgIdx is already an index into the full Args array, but the code was 
incorrectly creating a CallArgs array (dropping the first argument for instance 
methods) and then indexing into it with CapturingArgIdx, causing incorrect 
argument access and potential out-of-bounds crashes.



---
Full diff: https://github.com/llvm/llvm-project/pull/227231.diff


2 Files Affected:

- (modified) clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp (+6-5) 
- (modified) clang/test/Sema/LifetimeSafety/safety.cpp (+23) 


``````````diff
diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 292e3279233bb..a6726c46f5347 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -1044,11 +1044,12 @@ void FactsGenerator::handleLifetimeCaptureBy(const 
FunctionDecl *FD,
           CapturingArgIdx == LifetimeCaptureByAttr::Unknown ||
           CapturingArgIdx == LifetimeCaptureByAttr::Invalid)
         continue;
-      ArrayRef<const Expr *> CallArgs = IsInstance ? Args.drop_front() : Args;
-      const Expr *CapturedByArg =
-          (CapturingArgIdx == LifetimeCaptureByAttr::This)
-              ? Args[0]
-              : CallArgs[CapturingArgIdx];
+        // FIXME: Diagnose bad CapturingArgIdx.
+      if (CapturingArgIdx != LifetimeCaptureByAttr::This &&
+          (CapturingArgIdx < 0 ||
+           static_cast<size_t>(CapturingArgIdx) >= Args.size()))
+        continue;
+      const Expr *CapturedByArg = Args[CapturingArgIdx];
       assert(CapturedByArg && "Capturer expression must be valid");
 
       OriginList *Dest = readValue(CapturedByArg);
diff --git a/clang/test/Sema/LifetimeSafety/safety.cpp 
b/clang/test/Sema/LifetimeSafety/safety.cpp
index bf49e86577678..fb91fb30713db 100644
--- a/clang/test/Sema/LifetimeSafety/safety.cpp
+++ b/clang/test/Sema/LifetimeSafety/safety.cpp
@@ -4076,6 +4076,29 @@ void capturing_multiple_locals() {
     use(v);                         // expected-note 2 {{later used here}}
 }
 
+namespace off_by_one_crash {
+struct Item {
+  const int* ptr;
+};
+
+struct Container {
+  const Item* saved;
+};
+
+struct Helper {
+  void AddItem(const Item& item [[clang::lifetime_capture_by(c)]],
+               Container& c) const;
+  void Populate() const {
+    Container c{};
+    {
+      Item item;
+      AddItem(item, c); // expected-warning {{local variable 'item' does not 
live long enough}}
+    }                   // expected-note {{local variable 'item' is destroyed 
here}}
+    use(c);             // expected-note {{later used here}}
+  }
+};
+} // namespace off_by_one_crash
+
 struct [[gsl::Pointer()]] PtrWithInt { int x; };
 PtrWithInt f() {
   return PtrWithInt{10};

``````````

</details>


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

Reply via email to