Initial support for pointer arithmetic. Only support concrete indexes and
offsets for now. llvm-svn: 65814
This commit is contained in:
		
							parent
							
								
									b3921bf12e
								
							
						
					
					
						commit
						e7d1493216
					
				| 
						 | 
					@ -113,6 +113,11 @@ public:
 | 
				
			||||||
  virtual CastResult CastRegion(const GRState* state, const MemRegion* R,
 | 
					  virtual CastResult CastRegion(const GRState* state, const MemRegion* R,
 | 
				
			||||||
                                QualType CastToTy) = 0;
 | 
					                                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
 | 
					  /// getSelfRegion - Returns the region for the 'self' (Objective-C) or
 | 
				
			||||||
  ///  'this' object (C++).  When used when analyzing a normal function this
 | 
					  ///  'this' object (C++).  When used when analyzing a normal function this
 | 
				
			||||||
  ///  method returns NULL.
 | 
					  ///  method returns NULL.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -265,7 +265,8 @@ SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
 | 
					SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
 | 
				
			||||||
                             Loc L, NonLoc R) {  
 | 
					                             Loc L, NonLoc R) {  
 | 
				
			||||||
  return UnknownVal();
 | 
					  // Delegate pointer arithmetic to store manager.
 | 
				
			||||||
 | 
					  return Eng.getStoreManager().EvalBinOp(Op, L, R);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Equality operators for Locs.
 | 
					// Equality operators for Locs.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -170,6 +170,8 @@ public:
 | 
				
			||||||
  CastResult CastRegion(const GRState* state, const MemRegion* R,
 | 
					  CastResult CastRegion(const GRState* state, const MemRegion* R,
 | 
				
			||||||
                        QualType CastToTy);
 | 
					                        QualType CastToTy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SVal EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// The high level logic for this method is this:
 | 
					  /// The high level logic for this method is this:
 | 
				
			||||||
  /// Retrieve (L)
 | 
					  /// Retrieve (L)
 | 
				
			||||||
  ///   if L has binding
 | 
					  ///   if L has binding
 | 
				
			||||||
| 
						 | 
					@ -551,6 +553,33 @@ RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R,
 | 
				
			||||||
  return CastResult(AddRegionView(state, ViewR, R), ViewR);
 | 
					  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) {
 | 
					SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) {
 | 
				
			||||||
  assert(!isa<UnknownVal>(L) && "location unknown");
 | 
					  assert(!isa<UnknownVal>(L) && "location unknown");
 | 
				
			||||||
  assert(!isa<UndefinedVal>(L) && "location undefined");
 | 
					  assert(!isa<UndefinedVal>(L) && "location undefined");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue