[analyzer] Set concrete offset bindings to UnknownVal when processing symbolic offset...
authorAnna Zaks <ganna@apple.com>
Mon, 25 Mar 2013 20:43:24 +0000 (20:43 +0000)
committerAnna Zaks <ganna@apple.com>
Mon, 25 Mar 2013 20:43:24 +0000 (20:43 +0000)
This addresses an undefined value false positive from concreteOffsetBindingIsInvalidatedBySymbolicOffsetAssignment.

Fixes PR14877; radar://12991168.

llvm-svn: 177905

clang/lib/StaticAnalyzer/Core/RegionStore.cpp
clang/test/Analysis/region-store.c

index 58d9430..ae2752d 100644 (file)
@@ -833,14 +833,22 @@ RegionStoreManager::removeSubRegionBindings(RegionBindingsConstRef B,
                                             const SubRegion *Top) {
   BindingKey TopKey = BindingKey::Make(Top, BindingKey::Default);
   const MemRegion *ClusterHead = TopKey.getBaseRegion();
+  const ClusterBindings *Cluster = B.lookup(ClusterHead);
+
   if (Top == ClusterHead) {
     // We can remove an entire cluster's bindings all in one go.
     return B.remove(Top);
   }
 
-  const ClusterBindings *Cluster = B.lookup(ClusterHead);
-  if (!Cluster)
+  if (!Cluster) {
+    // If we're invalidating a region with a symbolic offset, we need to make
+    // sure we don't treat the base region as uninitialized anymore.
+    if (TopKey.hasSymbolicOffset()) {
+      const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
+      return B.addBinding(Concrete, BindingKey::Default, UnknownVal());
+    }
     return B;
+  }
 
   SmallVector<BindingPair, 32> Bindings;
   collectSubRegionBindings(Bindings, svalBuilder, *Cluster, Top, TopKey,
index d620150..70bda11 100644 (file)
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix,debug.ExprInspection -verify %s
 
 int printf(const char *restrict,...);
 
@@ -22,3 +21,36 @@ int compoundLiteralTest2() {
     }
     return 0;
 }
+
+int concreteOffsetBindingIsInvalidatedBySymbolicOffsetAssignment(int length,
+                                                                 int i) {
+  int values[length];
+  values[i] = 4;
+  return values[0]; // no-warning
+}
+
+struct X{
+  int mem;
+};
+int initStruct(struct X *st);
+int structOffsetBindingIsInvalidated(int length, int i){
+  struct X l;
+  initStruct(&l);
+  return l.mem; // no-warning
+}
+
+void clang_analyzer_eval(int);
+void testConstraintOnRegionOffset(int *values, int length, int i){
+  if (values[1] == 4) {
+    values[i] = 5;
+    clang_analyzer_eval(values[1] == 4);// expected-warning {{UNKNOWN}}
+  }
+}
+
+int initArray(int *values);
+void testConstraintOnRegionOffsetStack(int *values, int length, int i) {
+  if (values[0] == 4) {
+    initArray(values);
+    clang_analyzer_eval(values[0] == 4);// expected-warning {{UNKNOWN}}
+  }
+}