]> granicus.if.org Git - clang/commitdiff
Fix lazy symbolication bug in RegionStore involving fields of global variables. ...
authorTed Kremenek <kremenek@apple.com>
Tue, 26 Oct 2010 00:06:17 +0000 (00:06 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 26 Oct 2010 00:06:17 +0000 (00:06 +0000)
globals memory space gets assigned a symbolic value, but that value was not being used for lazy symbolication
of fields of globals.  This could result in cases where bogus null dereferences were being reported.

Fixes PR 8440.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117336 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Checker/RegionStore.cpp
test/Analysis/misc-ps.m

index 95d082ee447910df3f2db65971214d86bae3c49b..231be0af18d77986f4e7e271328b7af3546560a1 100644 (file)
@@ -686,6 +686,16 @@ void InvalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) {
     B = RM.Add(B, baseR, BindingKey::Default, V);
     return;
   }
+  
+  if (includeGlobals && 
+      isa<NonStaticGlobalSpaceRegion>(baseR->getMemorySpace())) {
+    // If the region is a global and we are invalidating all globals,
+    // just erase the entry.  This causes all globals to be lazily
+    // symbolicated from the same base symbol.
+    B = RM.Remove(B, baseR);
+    return;
+  }
+  
 
   DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, T, Count);
   assert(SymbolManager::canSymbolicate(T) || V.isUnknown());
@@ -1182,16 +1192,16 @@ SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store,
   RegionBindings B = GetRegionBindings(store);
 
   while (superR) {
-    if (const Optional<SVal> &D = RetrieveDerivedDefaultValue(B, superR, R, Ty))
+    if (const Optional<SVal> &D =
+        RetrieveDerivedDefaultValue(B, superR, R, Ty))
       return *D;
 
     // If our super region is a field or element itself, walk up the region
     // hierarchy to see if there is a default value installed in an ancestor.
-    if (isa<FieldRegion>(superR) || isa<ElementRegion>(superR)) {
-      superR = cast<SubRegion>(superR)->getSuperRegion();
+    if (const SubRegion *SR = dyn_cast<SubRegion>(superR)) {
+      superR = SR->getSuperRegion();
       continue;
     }
-
     break;
   }
 
index 52dd7e1defb9e9d098e8bbf2c2a6e84c4e2f1f3e..12e51023a9ecf0ce882421ceb76e26cbd37c6130 100644 (file)
@@ -1159,3 +1159,23 @@ void __PR8458(PR8458 *x) {
   @synchronized(x.lock) {} // no-warning
 }
 
+// PR 8440 - False null dereference during store to array-in-field-in-global.
+// This test case previously resulted in a bogus null deref warning from
+// incorrect lazy symbolication logic in RegionStore.
+static struct {
+  int num;
+  char **data;
+} saved_pr8440;
+
+char *foo_pr8440();
+char **bar_pr8440();
+void baz_pr8440(int n)
+{
+   saved_pr8440.num = n;
+   if (saved_pr8440.data) 
+     return;
+   saved_pr8440.data = bar_pr8440();
+   for (int i = 0 ; i < n ; i ++)
+     saved_pr8440.data[i] = foo_pr8440(); // no-warning
+}
+