]> granicus.if.org Git - clang/commitdiff
Initial support for pointer arithmetic. Only support concrete indexes and
authorZhongxing Xu <xuzhongxing@gmail.com>
Mon, 2 Mar 2009 07:52:23 +0000 (07:52 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Mon, 2 Mar 2009 07:52:23 +0000 (07:52 +0000)
offsets for now.

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

include/clang/Analysis/PathSensitive/Store.h
lib/Analysis/GRSimpleVals.cpp
lib/Analysis/RegionStore.cpp

index b8d6364388fb5c5cdc0e2a78641f5d5040fac1b5..ed30a8bca535e4df23c2725f99f2c9b73c2eec99 100644 (file)
@@ -112,6 +112,11 @@ public:
   ///  casted and 'CastToTy' the result type of the cast.
   virtual CastResult CastRegion(const GRState* state, const MemRegion* R,
                                 QualType CastToTy) = 0;
+
+  /// EvalBinOp - Perform pointer arithmetic.
+  virtual SVal EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) {
+    return UnknownVal();
+  }
   
   /// getSelfRegion - Returns the region for the 'self' (Objective-C) or
   ///  'this' object (C++).  When used when analyzing a normal function this
index d50876e5b30edebdecbbc38bbe6af383b1a53556..90d9e57bfd4920158aabed3e03e7662a3ee822ca 100644 (file)
@@ -265,7 +265,8 @@ SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
 
 SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                              Loc L, NonLoc R) {  
-  return UnknownVal();
+  // Delegate pointer arithmetic to store manager.
+  return Eng.getStoreManager().EvalBinOp(Op, L, R);
 }
 
 // Equality operators for Locs.
index e6e530bc0f0384e8d0f874b81699f3786e8784b1..7ab54b8b253db0acbe63555ed21f0f3c01cbb0f8 100644 (file)
@@ -170,6 +170,8 @@ public:
   CastResult CastRegion(const GRState* state, const MemRegion* R,
                         QualType CastToTy);
 
+  SVal EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R);
+
   /// The high level logic for this method is this:
   /// Retrieve (L)
   ///   if L has binding
@@ -551,6 +553,33 @@ RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R,
   return CastResult(AddRegionView(state, ViewR, R), ViewR);
 }
 
+SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) {
+  // Assume the base location is MemRegionVal(ElementRegion).
+
+  if (!isa<loc::MemRegionVal>(L)) {
+    return UnknownVal();
+  }
+
+  const MemRegion* MR = cast<loc::MemRegionVal>(L).getRegion();
+
+  const ElementRegion* ER = cast<ElementRegion>(MR);
+  SVal Idx = ER->getIndex();
+
+  nonloc::ConcreteInt* Base = dyn_cast<nonloc::ConcreteInt>(&Idx);
+  nonloc::ConcreteInt* Offset = dyn_cast<nonloc::ConcreteInt>(&R);
+
+  // Only support concrete integer indexes for now.
+  if (Base && Offset) {
+    SVal NewIdx = Base->EvalBinOp(getBasicVals(), Op, *Offset);
+
+    const MemRegion* NewER = MRMgr.getElementRegion(NewIdx, 
+                                                    ER->getArrayRegion());
+    return Loc::MakeVal(NewER);
+
+  } else
+    return UnknownVal();
+}
+
 SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) {
   assert(!isa<UnknownVal>(L) && "location unknown");
   assert(!isa<UndefinedVal>(L) && "location undefined");