]> granicus.if.org Git - clang/commitdiff
After conversations with Zhongxing Xu and Jordy Rose, refine the logic in
authorTed Kremenek <kremenek@apple.com>
Mon, 31 May 2010 01:22:04 +0000 (01:22 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 31 May 2010 01:22:04 +0000 (01:22 +0000)
RegionStoreManager::RetrieveElement() that handles indexing into a larger scalar
object to only consult the direct binding of a super region if it is a scalar.
This isn't perfect yet, and a big FIXME is attached to the code.  This causes
the test case for PR 7218 now to pass.

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

lib/Checker/RegionStore.cpp
test/Analysis/PR7218.c

index 2200ef1002ea5a48d449db8bcdcd69fbe848c504..ddcb7bee494d32cf7fe1def892d6c267ffdf739a 100644 (file)
@@ -1173,27 +1173,33 @@ SVal RegionStoreManager::RetrieveElement(Store store,
     }
   }
 
-  // Check if the immediate super region has a direct binding.
-  if (const Optional<SVal> &V = getDirectBinding(B, superR)) {
-    if (SymbolRef parentSym = V->getAsSymbol()) {
-      return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
-    }
-
-    if (V->isUnknownOrUndef())
-      return *V;
-
-    // Handle LazyCompoundVals for the immediate super region.  Other cases
-    // are handled in 'RetrieveFieldOrElementCommon'.
-    if (const nonloc::LazyCompoundVal *LCV =
-        dyn_cast<nonloc::LazyCompoundVal>(V)) {
-      R = MRMgr.getElementRegionWithSuper(R, LCV->getRegion());
-      return RetrieveElement(LCV->getStore(), R);
+  // Handle the case where we are indexing into a larger scalar object.
+  // For example, this handles:
+  //   int x = ...
+  //   char *y = &x;
+  //   return *y;
+  // FIXME: This is a hack, and doesn't do anything really intelligent yet.
+  const RegionRawOffset &O = R->getAsRawOffset();
+  if (const TypedRegion *baseR = dyn_cast_or_null<TypedRegion>(O.getRegion())) {
+    QualType baseT = baseR->getValueType(Ctx);
+    if (baseT->isScalarType()) {
+      QualType elemT = R->getElementType();
+      if (elemT->isScalarType()) {
+        if (Ctx.getTypeSizeInChars(baseT) >= Ctx.getTypeSizeInChars(elemT)) {
+          if (const Optional<SVal> &V = getDirectBinding(B, superR)) {
+            if (SymbolRef parentSym = V->getAsSymbol())
+              return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
+            if (V->isUnknownOrUndef())
+              return *V;
+            // Other cases: give up.  We are indexing into a larger object
+            // that has some value, but we don't know how to handle that yet.
+            return UnknownVal();
+          }
+        }
+      }
     }
-
-    // Other cases: give up.
-    return UnknownVal();
   }
-
   return RetrieveFieldOrElementCommon(store, R, R->getElementType(), superR);
 }
 
index bda30a7f726c1c70fe9d5734ad466f362f45867d..635e56f053ec7fd98ae4c8b4dff89907023eb5c9 100644 (file)
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store region -verify %s
-// XFAIL: *
 char PR7218(char a) {
     char buf[2];
     buf[0] = a;