Two changes:
(1) Moved the SValuator object from GRExprEngine to ValueManager.  This
   allows ValueManager to use the SValuator when creating SVals.
(2) Added ValueManager::makeArrayIndex() and
    ValueManager::convertToArrayIndex(), two SVal creation methods
    that will help RegionStoreManager always have a consistent set of
    SVals with the same integer size and type when reasoning about
    array indices.
llvm-svn: 75882
			
			
This commit is contained in:
		
							parent
							
								
									86085a57eb
								
							
						
					
					
						commit
						f267a15c8d
					
				| 
						 | 
					@ -20,7 +20,6 @@
 | 
				
			||||||
#include "clang/Analysis/PathSensitive/GRState.h"
 | 
					#include "clang/Analysis/PathSensitive/GRState.h"
 | 
				
			||||||
#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
 | 
					#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
 | 
				
			||||||
#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
 | 
					#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
 | 
				
			||||||
#include "clang/Analysis/PathSensitive/SValuator.h"
 | 
					 | 
				
			||||||
#include "clang/Analysis/PathSensitive/BugReporter.h"
 | 
					#include "clang/Analysis/PathSensitive/BugReporter.h"
 | 
				
			||||||
#include "clang/AST/Type.h"
 | 
					#include "clang/AST/Type.h"
 | 
				
			||||||
#include "clang/AST/ExprObjC.h"
 | 
					#include "clang/AST/ExprObjC.h"
 | 
				
			||||||
| 
						 | 
					@ -69,7 +68,7 @@ protected:
 | 
				
			||||||
  ValueManager &ValMgr;
 | 
					  ValueManager &ValMgr;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  /// SVator - SValuator object that creates SVals from expressions.
 | 
					  /// SVator - SValuator object that creates SVals from expressions.
 | 
				
			||||||
  llvm::OwningPtr<SValuator> SVator;
 | 
					  SValuator &SVator;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  /// EntryNode - The immediate predecessor node.
 | 
					  /// EntryNode - The immediate predecessor node.
 | 
				
			||||||
  NodeTy* EntryNode;
 | 
					  NodeTy* EntryNode;
 | 
				
			||||||
| 
						 | 
					@ -603,31 +602,25 @@ protected:
 | 
				
			||||||
  void EvalEagerlyAssume(NodeSet& Dst, NodeSet& Src, Expr *Ex);
 | 
					  void EvalEagerlyAssume(NodeSet& Dst, NodeSet& Src, Expr *Ex);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  SVal EvalCast(SVal X, QualType CastT) {
 | 
					  SVal EvalCast(SVal X, QualType CastT) {
 | 
				
			||||||
    if (X.isUnknownOrUndef())
 | 
					    return SVator.EvalCast(X, CastT);
 | 
				
			||||||
      return X;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if (isa<Loc>(X))
 | 
					 | 
				
			||||||
      return SVator->EvalCast(cast<Loc>(X), CastT);
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      return SVator->EvalCast(cast<NonLoc>(X), CastT);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  SVal EvalMinus(SVal X) {
 | 
					  SVal EvalMinus(SVal X) {
 | 
				
			||||||
    return X.isValid() ? SVator->EvalMinus(cast<NonLoc>(X)) : X;
 | 
					    return X.isValid() ? SVator.EvalMinus(cast<NonLoc>(X)) : X;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  SVal EvalComplement(SVal X) {
 | 
					  SVal EvalComplement(SVal X) {
 | 
				
			||||||
    return X.isValid() ? SVator->EvalComplement(cast<NonLoc>(X)) : X;
 | 
					    return X.isValid() ? SVator.EvalComplement(cast<NonLoc>(X)) : X;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, NonLoc R, QualType T) {
 | 
					  SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, NonLoc R, QualType T) {
 | 
				
			||||||
    return SVator->EvalBinOpNN(op, L, R, T);
 | 
					    return SVator.EvalBinOpNN(op, L, R, T);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, SVal R, QualType T) {
 | 
					  SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, SVal R, QualType T) {
 | 
				
			||||||
    return R.isValid() ? SVator->EvalBinOpNN(op, L, cast<NonLoc>(R), T) : R;
 | 
					    return R.isValid() ? SVator.EvalBinOpNN(op, L, cast<NonLoc>(R), T) : R;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
 | 
					  SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,10 +16,12 @@
 | 
				
			||||||
#ifndef LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
 | 
					#ifndef LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
 | 
				
			||||||
#define LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
 | 
					#define LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "llvm/ADT/OwningPtr.h"
 | 
				
			||||||
#include "clang/Analysis/PathSensitive/MemRegion.h"
 | 
					#include "clang/Analysis/PathSensitive/MemRegion.h"
 | 
				
			||||||
#include "clang/Analysis/PathSensitive/SVals.h"
 | 
					#include "clang/Analysis/PathSensitive/SVals.h"
 | 
				
			||||||
#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
 | 
					#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
 | 
				
			||||||
#include "clang/Analysis/PathSensitive/SymbolManager.h"
 | 
					#include "clang/Analysis/PathSensitive/SymbolManager.h"
 | 
				
			||||||
 | 
					#include "clang/Analysis/PathSensitive/SValuator.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace llvm { class BumpPtrAllocator; }
 | 
					namespace llvm { class BumpPtrAllocator; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,14 +34,25 @@ class ValueManager {
 | 
				
			||||||
  /// SymMgr - Object that manages the symbol information.
 | 
					  /// SymMgr - Object that manages the symbol information.
 | 
				
			||||||
  SymbolManager SymMgr;
 | 
					  SymbolManager SymMgr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// SVator - SValuator object that creates SVals from expressions.
 | 
				
			||||||
 | 
					  llvm::OwningPtr<SValuator> SVator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  MemRegionManager MemMgr;
 | 
					  MemRegionManager MemMgr;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  const QualType ArrayIndexTy;
 | 
				
			||||||
 | 
					  const unsigned ArrayIndexWidth;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context)
 | 
					  ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context)
 | 
				
			||||||
               : Context(context), BasicVals(Context, alloc),
 | 
					               : Context(context), BasicVals(Context, alloc),
 | 
				
			||||||
                 SymMgr(Context, BasicVals, alloc),
 | 
					                 SymMgr(Context, BasicVals, alloc),
 | 
				
			||||||
                 MemMgr(Context, alloc) {}
 | 
					                 MemMgr(Context, alloc),
 | 
				
			||||||
 | 
					                 ArrayIndexTy(Context.IntTy),
 | 
				
			||||||
 | 
					                 ArrayIndexWidth(Context.getTypeSize(ArrayIndexTy))  
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    // FIXME: Generalize later.
 | 
				
			||||||
 | 
					    SVator.reset(clang::CreateSimpleSValuator(*this));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Accessors to submanagers.
 | 
					  // Accessors to submanagers.
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
| 
						 | 
					@ -51,6 +64,8 @@ public:
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  SymbolManager &getSymbolManager() { return SymMgr; }
 | 
					  SymbolManager &getSymbolManager() { return SymMgr; }
 | 
				
			||||||
  const SymbolManager &getSymbolManager() const { return SymMgr; }
 | 
					  const SymbolManager &getSymbolManager() const { return SymMgr; }
 | 
				
			||||||
 | 
					                 
 | 
				
			||||||
 | 
					  SValuator &getSValuator() { return *SVator.get(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  MemRegionManager &getRegionManager() { return MemMgr; }
 | 
					  MemRegionManager &getRegionManager() { return MemMgr; }
 | 
				
			||||||
  const MemRegionManager &getRegionManager() const { return MemMgr; }
 | 
					  const MemRegionManager &getRegionManager() const { return MemMgr; }
 | 
				
			||||||
| 
						 | 
					@ -92,8 +107,14 @@ public:
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  NonLoc makeZeroArrayIndex() {
 | 
					  NonLoc makeZeroArrayIndex() {
 | 
				
			||||||
    return nonloc::ConcreteInt(BasicVals.getZeroWithPtrWidth(false));
 | 
					    return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  NonLoc makeArrayIndex(uint64_t idx) {
 | 
				
			||||||
 | 
					    return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  SVal convertToArrayIndex(SVal V);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) {
 | 
					  nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) {
 | 
				
			||||||
    return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(),
 | 
					    return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,7 +124,7 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
 | 
				
			||||||
    StateMgr(G.getContext(), SMC, CMC, G.getAllocator(), cfg, CD, L),
 | 
					    StateMgr(G.getContext(), SMC, CMC, G.getAllocator(), cfg, CD, L),
 | 
				
			||||||
    SymMgr(StateMgr.getSymbolManager()),
 | 
					    SymMgr(StateMgr.getSymbolManager()),
 | 
				
			||||||
    ValMgr(StateMgr.getValueManager()),
 | 
					    ValMgr(StateMgr.getValueManager()),
 | 
				
			||||||
    SVator(clang::CreateSimpleSValuator(ValMgr)), // FIXME: Generalize later.
 | 
					    SVator(ValMgr.getSValuator()),
 | 
				
			||||||
    CurrentStmt(NULL),
 | 
					    CurrentStmt(NULL),
 | 
				
			||||||
    NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
 | 
					    NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
 | 
				
			||||||
    RaiseSel(GetNullarySelector("raise", G.getContext())), 
 | 
					    RaiseSel(GetNullarySelector("raise", G.getContext())), 
 | 
				
			||||||
| 
						 | 
					@ -3090,9 +3090,9 @@ SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op,
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if (isa<Loc>(L)) {
 | 
					  if (isa<Loc>(L)) {
 | 
				
			||||||
    if (isa<Loc>(R))
 | 
					    if (isa<Loc>(R))
 | 
				
			||||||
      return SVator->EvalBinOpLL(Op, cast<Loc>(L), cast<Loc>(R), T);
 | 
					      return SVator.EvalBinOpLL(Op, cast<Loc>(L), cast<Loc>(R), T);
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      return SVator->EvalBinOpLN(state, Op, cast<Loc>(L), cast<NonLoc>(R), T);
 | 
					      return SVator.EvalBinOpLN(state, Op, cast<Loc>(L), cast<NonLoc>(R), T);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if (isa<Loc>(R)) {
 | 
					  if (isa<Loc>(R)) {
 | 
				
			||||||
| 
						 | 
					@ -3102,10 +3102,10 @@ SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op,
 | 
				
			||||||
    assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub);
 | 
					    assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Commute the operands.
 | 
					    // Commute the operands.
 | 
				
			||||||
    return SVator->EvalBinOpLN(state, Op, cast<Loc>(R), cast<NonLoc>(L), T);
 | 
					    return SVator.EvalBinOpLN(state, Op, cast<Loc>(R), cast<NonLoc>(L), T);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    return SVator->EvalBinOpNN(Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
 | 
					    return SVator.EvalBinOpNN(Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//===----------------------------------------------------------------------===//
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,6 +55,17 @@ NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SVal ValueManager::convertToArrayIndex(SVal V) {
 | 
				
			||||||
 | 
					  // Common case: we have an appropriately sized integer.
 | 
				
			||||||
 | 
					  if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&V)) {
 | 
				
			||||||
 | 
					    const llvm::APSInt& I = CI->getValue();
 | 
				
			||||||
 | 
					    if (I.getBitWidth() == ArrayIndexWidth && I.isSigned())
 | 
				
			||||||
 | 
					      return V;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return SVator->EvalCast(V, ArrayIndexTy);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R, QualType T) {
 | 
					SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R, QualType T) {
 | 
				
			||||||
  SymbolRef sym = SymMgr.getRegionValueSymbol(R, T);
 | 
					  SymbolRef sym = SymMgr.getRegionValueSymbol(R, T);
 | 
				
			||||||
                                
 | 
					                                
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue