]> granicus.if.org Git - clang/commitdiff
Handle 'long x = 0; char *y = (char *) x;' by layering an
authorTed Kremenek <kremenek@apple.com>
Mon, 4 May 2009 06:35:49 +0000 (06:35 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 4 May 2009 06:35:49 +0000 (06:35 +0000)
'ElementRegion' on top of the VarRegion for 'x'.  This causes the test
case xfail_wine_crash.c to now pass for BasicStoreManager.  It doesn't
crash for RegionStoreManager either, but reports a bogus unintialized
value warning.

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

lib/Analysis/Store.cpp
test/Analysis/basicstore_wine_crash.c [new file with mode: 0644]
test/Analysis/xfail_regionstore_wine_crash.c [moved from test/Analysis/xfail_wine_crash.c with 100% similarity]

index 65e90dec33d591f330beb7dd3957baabe0be22dd..e9b8f6a27fe7ed4ebf16b23fcc78e5c8e125e97a 100644 (file)
@@ -23,7 +23,7 @@ StoreManager::StoreManager(GRStateManager &stateMgr)
 
 StoreManager::CastResult
 StoreManager::CastRegion(const GRState* state, const MemRegion* R,
-                               QualType CastToTy) {
+                         QualType CastToTy) {
   
   ASTContext& Ctx = StateMgr.getContext();
 
@@ -38,10 +38,11 @@ StoreManager::CastRegion(const GRState* state, const MemRegion* R,
       return CastResult(state, R);
   }
   
-  // Check if we are casting to 'void*'.
-  // FIXME: Handle arbitrary upcasts.
-  if (const PointerType* PTy = dyn_cast<PointerType>(ToTy.getTypePtr()))
-    if (PTy->getPointeeType()->isVoidType()) {
+  if (const PointerType* PTy = dyn_cast<PointerType>(ToTy.getTypePtr())) {
+    // Check if we are casting to 'void*'.
+    // FIXME: Handle arbitrary upcasts.
+    QualType Pointee = PTy->getPointeeType();
+    if (Pointee->isVoidType()) {
 
       // Casts to void* only removes TypedViewRegion. If there is no
       // TypedViewRegion, leave the region untouched. This happens when:
@@ -58,6 +59,20 @@ StoreManager::CastRegion(const GRState* state, const MemRegion* R,
       
       return CastResult(state, R);
     }
+    else if (Pointee->isIntegerType()) {
+      // FIXME: At some point, it stands to reason that this 'dyn_cast' should
+      //  become a 'cast' and that 'R' will always be a TypedRegion.
+      if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
+        // Check if we are casting to a region with an integer type.  We now
+        // the types aren't the same, so we construct an ElementRegion.
+        // FIXME: We should have a standard query function to get the size
+        //  of the array index.
+        SVal Idx = ValMgr.makeZeroVal(ValMgr.getContext().VoidPtrTy);
+        ElementRegion* ER = MRMgr.getElementRegion(Pointee, Idx, TR);
+        return CastResult(state, ER);
+      }
+    }
+  }
 
   // FIXME: Need to handle arbitrary downcasts.
   // FIXME: Handle the case where a TypedViewRegion (layering a SymbolicRegion
diff --git a/test/Analysis/basicstore_wine_crash.c b/test/Analysis/basicstore_wine_crash.c
new file mode 100644 (file)
index 0000000..cb5fac8
--- /dev/null
@@ -0,0 +1,11 @@
+// RUN: clang-cc -checker-cfref -analyze -analyzer-store=basic %s
+
+// Once xfail_regionstore_wine_crash.c passes, move this test case
+// into misc-ps.m.
+
+void foo() {
+  long x = 0;
+  char *y = (char *) &x;
+  if (!*y)
+    return;
+}