[PATCH] D132236: [analyzer] Fix liveness of LazyCompoundVals

Balázs Benics via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 19 08:20:09 PDT 2022


steakhal created this revision.
steakhal added reviewers: NoQ, xazax.hun, martong, ASDenysPetrov, Szelethus, isuckatcs, vabridgers.
Herald added subscribers: manas, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware.
Herald added a project: All.
steakhal requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The `SymbolReaper` should consider a region //live// if that appears in
the store bindings anywhere - even if the region is wrapped by
`RegionSymbolVals`, `SymbolicRegions` or `LazyCompoundVals`.

This mistake by the `SymbolReaper` materialized in false-positives like
in the following example:

  void ptr1(List* n) {
    List* n2 = new List(*n); // cctor
    if (!n->next) {
      if (n2->next) {
        clang_analyzer_warnIfReached(); // FP! This should be unreachable.
      }
    }
    delete n2;
  }

The store entry of the pointee of `n2` looks something like this:

  HeapSymRegion{conj_$1{List *, LC1, S2540, #1}}  0(Default)  lazyCompoundVal{0x5641f1ed8830,Element{SymRegion{reg_$2<List * n>},0 S64b,struct List}}

So, any constraints referring to the `VarRegion` `n` supposed to be kept alive by that store binding.
Hence, the analyzer should be able to see that `reg_$3<List * Element{SymRegion{reg_$2<List * n>},0 S64b,struct List}.next> { [0, 0] }` when it reaches the `n2->next`.

This patch fixes the issue by reusing the `SymbolReaper::markLive(MemRegion)` for doing the appropriate traversal.

I'm yet to do the performance testing, given that this is actually in
the hot path.

Co-authored-by: Tomasz Kamiński <tomasz.kaminski at sonarsource.com>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D132236

Files:
  clang/lib/StaticAnalyzer/Core/RegionStore.cpp
  clang/test/Analysis/trivial-copy-struct.cpp


Index: clang/test/Analysis/trivial-copy-struct.cpp
===================================================================
--- clang/test/Analysis/trivial-copy-struct.cpp
+++ clang/test/Analysis/trivial-copy-struct.cpp
@@ -34,3 +34,28 @@
   (void)(n1->ptr);
   (void)(n2->ptr);
 }
+
+struct List {
+  List* next;
+};
+
+void ptr1(List* n) {
+  List* n2 = new List(*n); // cctor
+  if (!n->next) {
+    if (n2->next) {
+      clang_analyzer_warnIfReached(); // unreachable
+    }
+  }
+  delete n2;
+}
+
+void ptr2(List* n) {
+  List* n2 = new List(); // ctor
+  *n2 = *n; // assignment
+  if (!n->next) {
+    if (n2->next) {
+      clang_analyzer_warnIfReached(); // unreachable
+    }
+  }
+  delete n2;
+}
Index: clang/lib/StaticAnalyzer/Core/RegionStore.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -2829,22 +2829,14 @@
 }
 
 void RemoveDeadBindingsWorker::VisitBinding(SVal V) {
-  // Is it a LazyCompoundVal?  All referenced regions are live as well.
-  if (Optional<nonloc::LazyCompoundVal> LCS =
-          V.getAs<nonloc::LazyCompoundVal>()) {
-
-    const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
-
-    for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
-                                                        E = Vals.end();
-         I != E; ++I)
-      VisitBinding(*I);
+  const MemRegion *R = V.getAsRegion();
 
-    return;
-  }
+  // Is it a LazyCompoundVal?  All referenced regions are live as well.
+  if (auto LCS = V.getAs<nonloc::LazyCompoundVal>())
+    R = LCS->getRegion();
 
   // If V is a region, then add it to the worklist.
-  if (const MemRegion *R = V.getAsRegion()) {
+  if (R) {
     AddToWorkList(R);
     SymReaper.markLive(R);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D132236.454011.patch
Type: text/x-patch
Size: 1842 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220819/37b9f600/attachment.bin>


More information about the cfe-commits mailing list