llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Aaditya Agarwal (aaditya8979)

<details>
<summary>Changes</summary>

### Description
This PR resolves a false positive in `alpha.cplusplus.SmartPtr` where repeated 
calls to `std::unique_ptr::get()` on the same object returned identity-distinct 
symbols. This instability caused deterministic equivalence checks (e.g., `X == 
Y`) to incorrectly bifurcate into both `TRUE` and `FALSE` execution paths.

### Root Cause
`SmartPtrModeling` intercepts calls to smart pointer methods (`get()`, 
`release()`, `reset()`, `swap()`) via `evalCall`, establishing precise memory 
state transitions in the `TrackedRegionMap`. 

However, `ExprEngine::evalCall` runs an unconditional post-call 
`PSK_EscapeOutParameters` escape scan for every C++ method call on an object 
with a non-trivial destructor. Because `std::unique_ptr&lt;T&gt;` has a 
non-trivial destructor, its inner pointer is unconditionally marked as escaped 
after every modeled method call. 

This triggers a destructive chain:
`runCheckersForPointerEscape` → `checkRegionChanges` → 
`removeTrackedSubregions` → **`TrackedRegionMap` entry wiped.**

Consequently, the map entry established by the handler is destroyed before the 
next statement evaluates. A subsequent call to `P.get()` finds an empty cache 
and conjures a fresh, identity-distinct symbol (`conj_$1`), breaking symbol 
equivalence.

### The Fix
This patch introduces a surgical bypass in 
`SmartPtrModeling::checkRegionChanges`. 

`SmartPtrMethodHandlers` encodes exactly which `CallEvent`s the checker 
explicitly models. If `checkRegionChanges` is invoked for a call that matches 
one of our handlers, the handler has already produced the authoritative, 
deterministic memory state. The conservative region wipe is preempted, 
preserving the cached `TrackedRegionMap` state.

```cpp
if (Call &amp;&amp; SmartPtrMethodHandlers.lookup(*Call))
  return State;

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


1 Files Affected:

- (modified) clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp (+10) 


``````````diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp 
b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
index ad81e5076f931..de549377d6f77 100644
--- a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
@@ -573,6 +573,16 @@ ProgramStateRef SmartPtrModeling::checkRegionChanges(
     ArrayRef<const MemRegion *> ExplicitRegions,
     ArrayRef<const MemRegion *> Regions, const StackFrame *SF,
     const CallEvent *Call) const {
+  // Preempt conservative invalidation. If the invalidation is triggered by a
+  // modeled smart pointer method (e.g., get(), release(), swap()), the handler
+  // has already executed the precise, deterministic memory transitions via
+  // TrackedRegionMap. The ExprEngine's post-call PSK_EscapeOutParameters scan
+  // fires unconditionally for any object with a non-trivial destructor, which
+  // causes removeTrackedSubregions to blindly wipe our established state. If
+  // we own the CallEvent, we trust the state our handler produced.
+  if (Call && SmartPtrMethodHandlers.lookup(*Call))
+    return State;
+
   TrackedRegionMapTy RegionMap = State->get<TrackedRegionMap>();
   TrackedRegionMapTy::Factory &RegionMapFactory =
       State->get_context<TrackedRegionMap>();

``````````

</details>


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

Reply via email to