]> granicus.if.org Git - clang/commitdiff
Add a boilerplate for out-of-bound array checking. This has no real function currently.
authorZhongxing Xu <xuzhongxing@gmail.com>
Sat, 8 Nov 2008 03:45:42 +0000 (03:45 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Sat, 8 Nov 2008 03:45:42 +0000 (03:45 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58886 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/GRExprEngine.h
include/clang/Analysis/PathSensitive/Store.h
lib/Analysis/GRExprEngine.cpp

index 86853627ee7970970863dd3f3f30dc55f005609b..5339f6f3a26f7af989a79a0ed254383af0d697c9 100644 (file)
@@ -455,6 +455,15 @@ protected:
     return StateMgr.Assume(St, Cond, Assumption, isFeasible);
   }
 
+  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;
+  }
+
   NodeTy* MakeNode(NodeSet& Dst, Stmt* S, NodeTy* Pred, const GRState* St,
                    ProgramPoint::Kind K = ProgramPoint::PostStmtKind) {
     assert (Builder && "GRStmtNodeBuilder not present.");
index c4e21f2b196d2aeaad81e6701ba6fd45f3f666fc..7b6bf1e1d2da70f717eb2d58c1a3bbbd0827749f 100644 (file)
@@ -72,7 +72,11 @@ public:
                               const FieldDecl* D) = 0;
   
   virtual SVal getLValueElement(const GRState* St, SVal Base, SVal Offset) = 0;
-  
+
+  virtual SVal getSizeInElements(const GRState* St, const MemRegion* R) {
+    return UnknownVal();
+  }
+
   /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit
   ///  conversions between arrays and pointers.
   virtual SVal ArrayToPointer(SVal Array) = 0;
index e2c23b4942b71e46e8b411ac60ba432398c8fb59..8f8a143863d38feaa50bbcf880ae81f39f912565 100644 (file)
@@ -1067,6 +1067,28 @@ const GRState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred,
       else ExplicitNullDeref.insert(NullNode);
     }
   }
+
+  // Check for out-of-bound array access.
+  if (isFeasibleNotNull && isa<loc::MemRegionVal>(LV)) {
+    const MemRegion* R = cast<loc::MemRegionVal>(LV).getRegion();
+    if (const ElementRegion* ER = dyn_cast<ElementRegion>(R)) {
+      // Get the index of the accessed element.
+      SVal Idx = ER->getIndex();
+      // Get the extent of the array.
+      SVal NumElements = StateMgr.getStoreManager().getSizeInElements(StNotNull,
+                                                       ER->getSuperRegion());
+
+      bool isFeasibleInBound = false;
+      const GRState* StInBound = AssumeInBound(StNotNull, Idx, NumElements, 
+                                               true, isFeasibleInBound);
+
+      bool isFeasibleOutBound = false;
+      const GRState* StOutBound = AssumeInBound(StNotNull, Idx, NumElements, 
+                                                false, isFeasibleOutBound);
+
+      // Report warnings ...
+    }
+  }
   
   return isFeasibleNotNull ? StNotNull : NULL;
 }