]> granicus.if.org Git - clang/commitdiff
Improve RegionStoreManager::getSizeInElements()
authorZhongxing Xu <xuzhongxing@gmail.com>
Wed, 6 May 2009 11:51:48 +0000 (11:51 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Wed, 6 May 2009 11:51:48 +0000 (11:51 +0000)
 - add a static function getTypeWidth(), which computes the width of a type
   with the help of TargetInfo.
 - no-outofbounds.c now passes for region store.

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

lib/Analysis/RegionStore.cpp
test/Analysis/xfail-no-outofbounds.c

index 043fc95e084829d4a3aaa22330cea05747b3e2eb..5f987fdf27154fe80d3c940dee5c8efe960864bf 100644 (file)
@@ -18,6 +18,7 @@
 #include "clang/Analysis/PathSensitive/GRState.h"
 #include "clang/Analysis/PathSensitive/GRStateTrait.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Basic/TargetInfo.h"
 
 #include "llvm/ADT/ImmutableMap.h"
 #include "llvm/ADT/ImmutableList.h"
@@ -296,6 +297,7 @@ private:
   // Utility methods.
   BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); }
   ASTContext& getContext() { return StateMgr.getContext(); }
+  TargetInfo& getTargetInfo() { return getContext().getTargetInfo(); }
   SymbolManager& getSymbolManager() { return StateMgr.getSymbolManager(); }
 
   const GRState* AddRegionView(const GRState* St,
@@ -310,6 +312,45 @@ StoreManager* clang::CreateRegionStoreManager(GRStateManager& StMgr) {
   return new RegionStoreManager(StMgr);
 }
 
+// getTypeWidth - compute the width of the type. Should pass in
+// canonical type.
+static unsigned getTypeWidth(ASTContext& Ctx, QualType T) {
+  TargetInfo& Target = Ctx.getTargetInfo();
+  QualType CanT = Ctx.getCanonicalType(T);
+
+  if (CanT->isPointerType())
+    return Target.getPointerWidth(0);
+
+  if (CanT->isCharType())
+    return Target.getCharWidth();
+
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanT)) {
+    switch (BT->getKind()) {
+    case BuiltinType::Char_U:
+    case BuiltinType::UChar:
+    case BuiltinType::Char_S:
+    case BuiltinType::SChar:
+      return Target.getCharWidth();
+
+    case BuiltinType::UShort:
+    case BuiltinType::Short:
+      return Target.getShortWidth();
+
+    case BuiltinType::UInt:
+    case BuiltinType::Int:
+      return Target.getIntWidth();
+
+    case BuiltinType::ULong:
+    case BuiltinType::Long:
+      return Target.getLongWidth();
+    default:
+      assert(0 && "Unprocessed builtin type.");
+    }
+  }
+
+  assert(0 && "Unprocessed type.");
+}
+
 SubRegionMap* RegionStoreManager::getSubRegionMap(const GRState *state) {
   RegionBindingsTy B = GetRegionBindings(state->getStore());
   RegionStoreSubRegionMap *M = new RegionStoreSubRegionMap();
@@ -503,7 +544,17 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St,
 
     // If the VarRegion is cast to other type, compute the size with respect to
     // that type.
-    
+    GRStateRef state(St, StateMgr);
+    const QualType* CastTy = state.get<RegionCasts>(VR);
+
+    if (CastTy) {
+      QualType EleTy =cast<PointerType>(CastTy->getTypePtr())->getPointeeType();
+      QualType VarTy = VR->getRValueType(getContext());
+      unsigned EleWidth = getTypeWidth(getContext(), EleTy);
+      unsigned VarWidth = getTypeWidth(getContext(), VarTy);
+      return NonLoc::MakeIntVal(getBasicVals(), VarWidth / EleWidth, false);
+    }
+
     // Clients can use ordinary variables as if they were arrays.  These
     // essentially are arrays of size 1.
     return NonLoc::MakeIntVal(getBasicVals(), 1, false);
@@ -613,7 +664,7 @@ static bool isSmallerThan(QualType T1, QualType T2) {
 
 RegionStoreManager::CastResult
 RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R,
-                         QualType CastToTy) {
+                               QualType CastToTy) {
   
   ASTContext& Ctx = StateMgr.getContext();
 
index e5c21c5b8175561c146a5c46f68f7e717d8ecb35..f2ee732c2570c7ca3bfc13299fe318f36cee7122 100644 (file)
@@ -1,5 +1,5 @@
 // RUN: clang-cc -checker-cfref -analyze -analyzer-store=region -verify %s 
-// XFAIL
+
 void f() {
   long x = 0;
   char *y = (char*) &x;