]> granicus.if.org Git - clang/commitdiff
Initial support for checking out of bound memory access. Only support
authorZhongxing Xu <xuzhongxing@gmail.com>
Sat, 22 Nov 2008 13:21:46 +0000 (13:21 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Sat, 22 Nov 2008 13:21:46 +0000 (13:21 +0000)
ConcreteInt index for now.

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

include/clang/Analysis/PathSensitive/BasicValueFactory.h
include/clang/Analysis/PathSensitive/ConstraintManager.h
include/clang/Analysis/PathSensitive/GRExprEngine.h
include/clang/Analysis/PathSensitive/GRState.h
include/clang/Analysis/PathSensitive/SVals.h
lib/Analysis/BasicConstraintManager.cpp
lib/Analysis/BasicValueFactory.cpp
lib/Analysis/GRExprEngine.cpp
lib/Analysis/RegionStore.cpp
lib/Analysis/SVals.cpp

index 639ff5d92cc89a6885d7bb1849c32b747b9addb4..70fbe1de83ffe19e59cb1985595bbcd699481f10 100644 (file)
@@ -72,6 +72,7 @@ public:
   ASTContext& getContext() const { return Ctx; }  
 
   const llvm::APSInt& getValue(const llvm::APSInt& X);
+  const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned);
   const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
   const llvm::APSInt& getValue(uint64_t X, QualType T);
 
index 71ae247f577351fd6cafc200b32054fbc582cf95..3f2e60d3ef9bea1728a6f6d59ee8a8ae0f659a8c 100644 (file)
@@ -34,6 +34,10 @@ public:
   virtual const GRState* Assume(const GRState* St, SVal Cond, 
                                 bool Assumption, bool& isFeasible) = 0;
 
+  virtual const GRState* AssumeInBound(const GRState* St, SVal Idx, 
+                                       SVal UpperBound, bool Assumption,
+                                       bool& isFeasible) = 0;
+
   virtual const GRState* AddNE(const GRState* St, SymbolID sym, 
                                const llvm::APSInt& V) = 0;
   virtual const llvm::APSInt* getSymVal(const GRState* St, SymbolID sym) = 0;
index 5ba61d86457efc50a99a40f371ee5b8e5dc6b306..1b7d9bf6a396ba6c40686e202addfed7cc45b95d 100644 (file)
@@ -468,11 +468,7 @@ protected:
 
   const GRState* AssumeInBound(const GRState* St, SVal Idx, SVal UpperBound,
                                bool Assumption, bool& isFeasible) {
-    // FIXME: In this function, we will check if Idx can be in/out 
-    // [0, UpperBound) according to the assumption.  We can extend the 
-    // interface to include a LowerBound parameter.
-    isFeasible = true;
-    return St;
+    return StateMgr.AssumeInBound(St, Idx, UpperBound, Assumption, isFeasible);
   }
 
   NodeTy* MakeNode(NodeSet& Dst, Stmt* S, NodeTy* Pred, const GRState* St,
index 0a40998e3993c35827a82b50716b8fd17f362b8a..68f7921db327390d7bc960fd3501dee3a6baa1c8 100644 (file)
@@ -523,6 +523,12 @@ public:
     return ConstraintMgr->Assume(St, Cond, Assumption, isFeasible);
   }
 
+  const GRState* AssumeInBound(const GRState* St, SVal Idx, SVal UpperBound,
+                               bool Assumption, bool& isFeasible) {
+    return ConstraintMgr->AssumeInBound(St, Idx, UpperBound, Assumption, 
+                                        isFeasible);
+  }
+
   const GRState* AddNE(const GRState* St, SymbolID sym, const llvm::APSInt& V) {
     return ConstraintMgr->AddNE(St, sym, V);
   }
index 417a89adc8a5e0bdae8357647a6bc381f4fd5f93..16322f111f20359dcb10f967d342b86d17e3248f 100644 (file)
@@ -173,6 +173,9 @@ public:
   static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T);
   
   static NonLoc MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I);
+
+  static NonLoc MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I,
+                        bool isUnsigned);
     
   static NonLoc MakeIntTruthVal(BasicValueFactory& BasicVals, bool b);
 
index b09d9de4469adf9a4edd3fe4906cfbd48d4fe81d..a359b23c5492273689cebb598bc04b4b98fe4231 100644 (file)
@@ -69,6 +69,9 @@ public:
   const GRState* AssumeSymLE(const GRState* St, SymbolID sym,
                              const llvm::APSInt& V, bool& isFeasible);
 
+  const GRState* AssumeInBound(const GRState* St, SVal Idx, SVal UpperBound,
+                               bool Assumption, bool& isFeasible);
+
   const GRState* AddEQ(const GRState* St, SymbolID sym, const llvm::APSInt& V);
 
   const GRState* AddNE(const GRState* St, SymbolID sym, const llvm::APSInt& V);
@@ -83,6 +86,9 @@ public:
 
   void print(const GRState* St, std::ostream& Out, 
              const char* nl, const char *sep);
+
+private:
+  BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); }
 };
 
 } // end anonymous namespace
@@ -352,6 +358,27 @@ BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolID sym,
   return St;
 }
 
+const GRState* 
+BasicConstraintManager::AssumeInBound(const GRState* St, SVal Idx, 
+                                      SVal UpperBound, bool Assumption, 
+                                      bool& isFeasible) {
+  // Only support ConcreteInt for now.
+  if (!(isa<nonloc::ConcreteInt>(Idx) && isa<nonloc::ConcreteInt>(UpperBound))){
+    isFeasible = true;
+    return St;
+  }
+
+  const llvm::APSInt& Zero = getBasicVals().getZeroWithPtrWidth(false);
+  const llvm::APSInt& IdxV = cast<nonloc::ConcreteInt>(Idx).getValue();
+  const llvm::APSInt& UBV = cast<nonloc::ConcreteInt>(UpperBound).getValue();
+
+  bool InBound = (Zero <= IdxV) && (IdxV < UBV);
+
+  isFeasible = Assumption ? InBound : !InBound;
+
+  return St;
+}
+
 static int ConstEqTyIndex = 0;
 static int ConstNotEqTyIndex = 0;
 
index 5b7041bc43cdd5046a1c38268086c0e2b80cbde5..7ce305e4cf524e7d6db888bf0c8dc3e973848216 100644 (file)
@@ -76,6 +76,12 @@ const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
   return *P;
 }
 
+const llvm::APSInt& BasicValueFactory::getValue(const llvm::APInt& X,
+                                                bool isUnsigned) {
+  llvm::APSInt V(X, isUnsigned);
+  return getValue(V);
+}
+
 const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
                                            bool isUnsigned) {
   llvm::APSInt V(BitWidth, isUnsigned);
index db325fb9f9af107e22a17c7ce082baa763939a43..6de910fc17187f611aaeef2e486fc53c8fa49f1b 100644 (file)
@@ -1084,9 +1084,14 @@ const GRState* GRExprEngine::EvalLocation(Stmt* Ex, NodeTy* Pred,
       bool isFeasibleOutBound = false;
       const GRState* StOutBound = AssumeInBound(StNotNull, Idx, NumElements, 
                                                 false, isFeasibleOutBound);
-      StInBound = StOutBound = 0; // FIXME: squeltch warning.
 
-      // Report warnings ...
+      if (isFeasibleOutBound) {
+        // Report warning.
+
+        StOutBound = 0;
+      }
+
+      return isFeasibleInBound ? StInBound : NULL;
     }
   }
   
index 6f632f4bc51d6ddfd5edc2bd8a460b51dd3b7c6f..cc7715a98a098f4e9ab7e0da62313682007ecfdf 100644 (file)
@@ -80,6 +80,8 @@ public:
 
   SVal getLValueElement(const GRState* St, SVal Base, SVal Offset);
 
+  SVal getSizeInElements(const GRState* St, const MemRegion* R);
+
   SVal ArrayToPointer(SVal Array);
 
   std::pair<const GRState*, SVal>
@@ -257,6 +259,40 @@ SVal RegionStoreManager::getLValueElement(const GRState* St,
   return UnknownVal();
 }
 
+SVal RegionStoreManager::getSizeInElements(const GRState* St,
+                                           const MemRegion* R) {
+  if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
+    // Get the type of the variable.
+    QualType T = VR->getType(getContext());
+
+    // It must be of array type. 
+    const ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
+
+    // return the size as signed integer.
+    return NonLoc::MakeVal(getBasicVals(), CAT->getSize(), false);
+  }
+
+  if (const StringRegion* SR = dyn_cast<StringRegion>(R)) {
+    // FIXME: Unsupported yet.
+    SR = 0;
+    return UnknownVal();
+  }
+
+  if (const AnonTypedRegion* ATR = dyn_cast<AnonTypedRegion>(R)) {
+    // FIXME: Unsupported yet.
+    ATR = 0;
+    return UnknownVal();
+  }
+
+  if (const FieldRegion* FR = dyn_cast<FieldRegion>(R)) {
+    // FIXME: Unsupported yet.
+    FR = 0;
+    return UnknownVal();
+  }
+  printf("kidn = %d\n", R->getKind());
+  assert(0 && "Other regions are not supported yet.");
+}
+
 // Cast 'pointer to array' to 'pointer to the first element of array'.
 
 SVal RegionStoreManager::ArrayToPointer(SVal Array) {
index 644f60d25af7444113670be55f93d999bf16ec34..764a05fe8f0a9c384ede5d301a8d8762334d3da2 100644 (file)
@@ -253,6 +253,11 @@ NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I) {
                               I->getType()->isUnsignedIntegerType())));
 }
 
+NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I,
+                       bool isUnsigned) {
+  return nonloc::ConcreteInt(BasicVals.getValue(I, isUnsigned));
+}
+
 NonLoc NonLoc::MakeIntTruthVal(BasicValueFactory& BasicVals, bool b) {
   return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
 }