]> granicus.if.org Git - clang/commitdiff
Restructure RegionStoreManager::getSizeInElements() to use a switch statement
authorTed Kremenek <kremenek@apple.com>
Fri, 10 Jul 2009 22:30:06 +0000 (22:30 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 10 Jul 2009 22:30:06 +0000 (22:30 +0000)
over the types of MemRegions. This allows the compiler to warn us which regions
are not handled, and also is a little faster.

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

lib/Analysis/RegionStore.cpp

index 1e95f174b5ac76d658543cef49dd7e4d7d29bc5c..45a61986472a530ed36bf30c6fac7b810ccadfd7 100644 (file)
@@ -538,64 +538,79 @@ SVal RegionStoreManager::getLValueElement(const GRState *St,
 //===----------------------------------------------------------------------===//
 
 SVal RegionStoreManager::getSizeInElements(const GRState *state,
-                                           const MemRegion* R) {
-  if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
-    // Get the type of the variable.
-    QualType T = VR->getDesugaredValueType(getContext());
+                                           const MemRegion *R) {
+  
+  switch (R->getKind()) {
+    case MemRegion::MemSpaceRegionKind:
+      assert(0 && "Cannot index into a MemSpace");
+      return UnknownVal();      
+      
+    case MemRegion::CodeTextRegionKind:
+      // Technically this can happen if people do funny things with casts.
+      return UnknownVal();
 
-    // FIXME: Handle variable-length arrays.
-    if (isa<VariableArrayType>(T))
+      // Not yet handled.
+    case MemRegion::AllocaRegionKind:
+    case MemRegion::CompoundLiteralRegionKind:
+    case MemRegion::ElementRegionKind:
+    case MemRegion::FieldRegionKind:
+    case MemRegion::ObjCIvarRegionKind:
+    case MemRegion::ObjCObjectRegionKind:
+    case MemRegion::SymbolicRegionKind:
       return UnknownVal();
-    
-    if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(T)) {
-      // return the size as signed integer.
-      return ValMgr.makeIntVal(CAT->getSize(), false);
+      
+    case MemRegion::StringRegionKind: {
+      const StringLiteral* Str = cast<StringRegion>(R)->getStringLiteral();
+      // We intentionally made the size value signed because it participates in 
+      // operations with signed indices.
+      return ValMgr.makeIntVal(Str->getByteLength()+1, false);
     }
+      
+      // TypedViewRegion will soon be removed.
+    case MemRegion::TypedViewRegionKind:
+      return UnknownVal();
 
-    const QualType* CastTy = state->get<RegionCasts>(VR);
-
-    // If the VarRegion is cast to other type, compute the size with respect to
-    // that type.
-    if (CastTy) {
-      QualType EleTy =cast<PointerType>(CastTy->getTypePtr())->getPointeeType();
-      QualType VarTy = VR->getValueType(getContext());
-      uint64_t EleSize = getContext().getTypeSize(EleTy);
-      uint64_t VarSize = getContext().getTypeSize(VarTy);
-      assert(VarSize != 0);
-      return ValMgr.makeIntVal(VarSize/EleSize, false);
+    case MemRegion::VarRegionKind: {
+      const VarRegion* VR = cast<VarRegion>(R);
+      // Get the type of the variable.
+      QualType T = VR->getDesugaredValueType(getContext());
+      
+      // FIXME: Handle variable-length arrays.
+      if (isa<VariableArrayType>(T))
+        return UnknownVal();
+      
+      if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(T)) {
+        // return the size as signed integer.
+        return ValMgr.makeIntVal(CAT->getSize(), false);
+      }
+      
+      const QualType* CastTy = state->get<RegionCasts>(VR);
+      
+      // If the VarRegion is cast to other type, compute the size with respect to
+      // that type.
+      if (CastTy) {
+        QualType EleTy =cast<PointerType>(CastTy->getTypePtr())->getPointeeType();
+        QualType VarTy = VR->getValueType(getContext());
+        uint64_t EleSize = getContext().getTypeSize(EleTy);
+        uint64_t VarSize = getContext().getTypeSize(VarTy);
+        assert(VarSize != 0);
+        return ValMgr.makeIntVal(VarSize/EleSize, false);
+      }
+      
+      // Clients can use ordinary variables as if they were arrays.  These
+      // essentially are arrays of size 1.
+      return ValMgr.makeIntVal(1, false);
     }
-
-    // Clients can use ordinary variables as if they were arrays.  These
-    // essentially are arrays of size 1.
-    return ValMgr.makeIntVal(1, false);
-  }
-
-  if (const StringRegion* SR = dyn_cast<StringRegion>(R)) {
-    const StringLiteral* Str = SR->getStringLiteral();
-    // We intentionally made the size value signed because it participates in 
-    // operations with signed indices.
-    return ValMgr.makeIntVal(Str->getByteLength()+1, false);
-  }
-
-  if (const FieldRegion* FR = dyn_cast<FieldRegion>(R)) {
-    // FIXME: Unsupported yet.
-    FR = 0;
-    return UnknownVal();
-  }
-
-  if (isa<SymbolicRegion>(R)) {
-    return UnknownVal();
-  }
-
-  if (isa<AllocaRegion>(R)) {
-    return UnknownVal();
-  }
-
-  if (isa<ElementRegion>(R)) {
-    return UnknownVal();
+          
+    case MemRegion::BEG_DECL_REGIONS:
+    case MemRegion::END_DECL_REGIONS:
+    case MemRegion::BEG_TYPED_REGIONS:
+    case MemRegion::END_TYPED_REGIONS:
+      assert(0 && "Infeasible region");
+      return UnknownVal();
   }
-
-  assert(0 && "Other regions are not supported yet.");
+      
+  assert(0 && "Unreachable");
   return UnknownVal();
 }