RegionStore:
-refactor logic for retrieving bindings from VarDecls into RegionStoreManager::RetrieveVar() - improve RegionStoreManager::CastRetrievedVal() and SimpleSValuate::EvalCastNL to better handle casts of values of the same canonical type as well as casts of LocAsInteger values. llvm-svn: 76516
This commit is contained in:
		
							parent
							
								
									05ac8276cf
								
							
						
					
					
						commit
						fe12f88924
					
				| 
						 | 
					@ -287,6 +287,8 @@ public:
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  SVal RetrieveObjCIvar(const GRState *state, const ObjCIvarRegion *R);
 | 
					  SVal RetrieveObjCIvar(const GRState *state, const ObjCIvarRegion *R);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  SVal RetrieveVar(const GRState *state, const VarRegion *R);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  SVal RetrieveLazySymbol(const GRState *state, const TypedRegion *R);
 | 
					  SVal RetrieveLazySymbol(const GRState *state, const TypedRegion *R);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy);
 | 
					  SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy);
 | 
				
			||||||
| 
						 | 
					@ -848,6 +850,9 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
 | 
				
			||||||
  if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R))
 | 
					  if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R))
 | 
				
			||||||
    return CastRetrievedVal(RetrieveObjCIvar(state, IVR), IVR, T);
 | 
					    return CastRetrievedVal(RetrieveObjCIvar(state, IVR), IVR, T);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  if (const VarRegion *VR = dyn_cast<VarRegion>(R))
 | 
				
			||||||
 | 
					    return CastRetrievedVal(RetrieveVar(state, VR), VR, T);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  RegionBindingsTy B = GetRegionBindings(state->getStore());
 | 
					  RegionBindingsTy B = GetRegionBindings(state->getStore());
 | 
				
			||||||
  RegionBindingsTy::data_type* V = B.lookup(R);
 | 
					  RegionBindingsTy::data_type* V = B.lookup(R);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -859,16 +864,6 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
 | 
				
			||||||
  // the value it had upon its creation and/or entry to the analyzed
 | 
					  // the value it had upon its creation and/or entry to the analyzed
 | 
				
			||||||
  // function/method.  These are either symbolic values or 'undefined'.
 | 
					  // function/method.  These are either symbolic values or 'undefined'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // We treat function parameters as symbolic values.
 | 
					 | 
				
			||||||
  if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
 | 
					 | 
				
			||||||
    const VarDecl *VD = VR->getDecl();
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if (VD == SelfDecl)
 | 
					 | 
				
			||||||
      return loc::MemRegionVal(getSelfRegion(0));
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if (VR->hasGlobalsOrParametersStorage())
 | 
					 | 
				
			||||||
      return ValMgr.getRegionValueSymbolValOrUnknown(VR, VD->getType());
 | 
					 | 
				
			||||||
  }  
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (R->hasHeapOrStackStorage()) {
 | 
					  if (R->hasHeapOrStackStorage()) {
 | 
				
			||||||
    // All stack variables are considered to have undefined values
 | 
					    // All stack variables are considered to have undefined values
 | 
				
			||||||
| 
						 | 
					@ -1023,6 +1018,27 @@ SVal RegionStoreManager::RetrieveObjCIvar(const GRState* state,
 | 
				
			||||||
  return RetrieveLazySymbol(state, R);
 | 
					  return RetrieveLazySymbol(state, R);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SVal RegionStoreManager::RetrieveVar(const GRState *state,
 | 
				
			||||||
 | 
					                                     const VarRegion *R) {
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Check if the region has a binding.
 | 
				
			||||||
 | 
					  RegionBindingsTy B = GetRegionBindings(state->getStore());
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if (const SVal* V = B.lookup(R))
 | 
				
			||||||
 | 
					    return *V;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Lazily derive a value for the VarRegion.
 | 
				
			||||||
 | 
					  const VarDecl *VD = R->getDecl();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  if (VD == SelfDecl)
 | 
				
			||||||
 | 
					    return loc::MemRegionVal(getSelfRegion(0));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  if (R->hasGlobalsOrParametersStorage())
 | 
				
			||||||
 | 
					    return ValMgr.getRegionValueSymbolValOrUnknown(R, VD->getType());
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return UndefinedVal();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SVal RegionStoreManager::RetrieveLazySymbol(const GRState *state, 
 | 
					SVal RegionStoreManager::RetrieveLazySymbol(const GRState *state, 
 | 
				
			||||||
                                            const TypedRegion *R) {
 | 
					                                            const TypedRegion *R) {
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
| 
						 | 
					@ -1093,7 +1109,15 @@ SVal RegionStoreManager::RetrieveArray(const GRState *state,
 | 
				
			||||||
SVal RegionStoreManager::CastRetrievedVal(SVal V, const TypedRegion *R,
 | 
					SVal RegionStoreManager::CastRetrievedVal(SVal V, const TypedRegion *R,
 | 
				
			||||||
                                           QualType castTy) {
 | 
					                                           QualType castTy) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (castTy.isNull() || R->getValueType(getContext()) == castTy)
 | 
					  if (castTy.isNull())
 | 
				
			||||||
 | 
					    return V;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  ASTContext &Ctx = getContext();  
 | 
				
			||||||
 | 
					  QualType valTy = R->getValueType(Ctx);
 | 
				
			||||||
 | 
					  castTy = Ctx.getCanonicalType(castTy);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if (valTy == castTy)
 | 
				
			||||||
    return V;
 | 
					    return V;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  return ValMgr.getSValuator().EvalCast(V, castTy);
 | 
					  return ValMgr.getSValuator().EvalCast(V, castTy);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,10 +48,28 @@ SVal SimpleSValuator::EvalCastNL(NonLoc val, QualType castTy) {
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  bool isLocType = Loc::IsLocType(castTy);
 | 
					  bool isLocType = Loc::IsLocType(castTy);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if (isLocType)
 | 
					  if (nonloc::LocAsInteger *LI = dyn_cast<nonloc::LocAsInteger>(&val)) {
 | 
				
			||||||
    if (nonloc::LocAsInteger *LI = dyn_cast<nonloc::LocAsInteger>(&val))
 | 
					    if (isLocType)
 | 
				
			||||||
      return LI->getLoc();
 | 
					      return LI->getLoc();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    ASTContext &Ctx = ValMgr.getContext();    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // FIXME: Support promotions/truncations.
 | 
				
			||||||
 | 
					    if (Ctx.getTypeSize(castTy) == Ctx.getTypeSize(Ctx.VoidPtrTy))
 | 
				
			||||||
 | 
					      return val;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return UnknownVal();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (const SymExpr *se = val.getAsSymbolicExpression()) {
 | 
				
			||||||
 | 
					    ASTContext &Ctx = ValMgr.getContext();
 | 
				
			||||||
 | 
					    QualType T = Ctx.getCanonicalType(se->getType(Ctx));
 | 
				
			||||||
 | 
					    if (T == Ctx.getCanonicalType(castTy))
 | 
				
			||||||
 | 
					      return val;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return UnknownVal();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  if (!isa<nonloc::ConcreteInt>(val))
 | 
					  if (!isa<nonloc::ConcreteInt>(val))
 | 
				
			||||||
    return UnknownVal();
 | 
					    return UnknownVal();
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue