SValBuilder.h revision 9b663716449b618ba0390b1dbebc54fa8e971124
1// SValBuilder.h - Construction of SVals from evaluating expressions -*- C++ -*-
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines SValBuilder, a class that defines the interface for
11//  "symbolical evaluators" which construct an SVal from an expression.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_GR_SVALBUILDER
16#define LLVM_CLANG_GR_SVALBUILDER
17
18#include "clang/AST/Expr.h"
19#include "clang/AST/ExprCXX.h"
20#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
21#include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
22#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
23
24namespace clang {
25
26namespace ento {
27
28class GRState;
29
30class SValBuilder {
31protected:
32  ASTContext &Context;
33
34  /// Manager of APSInt values.
35  BasicValueFactory BasicVals;
36
37  /// Manages the creation of symbols.
38  SymbolManager SymMgr;
39
40  /// Manages the creation of memory regions.
41  MemRegionManager MemMgr;
42
43  GRStateManager &StateMgr;
44
45  /// The scalar type to use for array indices.
46  const QualType ArrayIndexTy;
47
48  /// The width of the scalar type used for array indices.
49  const unsigned ArrayIndexWidth;
50
51public:
52  // FIXME: Make these protected again one RegionStoreManager correctly
53  // handles loads from differening bound value types.
54  virtual SVal evalCastNL(NonLoc val, QualType castTy) = 0;
55  virtual SVal evalCastL(Loc val, QualType castTy) = 0;
56
57public:
58  SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
59              GRStateManager &stateMgr)
60    : Context(context), BasicVals(context, alloc),
61      SymMgr(context, BasicVals, alloc),
62      MemMgr(context, alloc),
63      StateMgr(stateMgr),
64      ArrayIndexTy(context.IntTy),
65      ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {}
66
67  virtual ~SValBuilder() {}
68
69  SVal evalCast(SVal V, QualType castTy, QualType originalType);
70
71  virtual SVal evalMinus(NonLoc val) = 0;
72
73  virtual SVal evalComplement(NonLoc val) = 0;
74
75  virtual SVal evalBinOpNN(const GRState *state, BinaryOperator::Opcode Op,
76                           NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
77
78  virtual SVal evalBinOpLL(const GRState *state, BinaryOperator::Opcode Op,
79                           Loc lhs, Loc rhs, QualType resultTy) = 0;
80
81  virtual SVal evalBinOpLN(const GRState *state, BinaryOperator::Opcode Op,
82                           Loc lhs, NonLoc rhs, QualType resultTy) = 0;
83
84  /// getKnownValue - evaluates a given SVal. If the SVal has only one possible
85  ///  (integer) value, that value is returned. Otherwise, returns NULL.
86  virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal V) = 0;
87
88  SVal evalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
89                 SVal L, SVal R, QualType T);
90
91  DefinedOrUnknownSVal evalEQ(const GRState *ST, DefinedOrUnknownSVal L,
92                              DefinedOrUnknownSVal R);
93
94  ASTContext &getContext() { return Context; }
95  const ASTContext &getContext() const { return Context; }
96
97  GRStateManager &getStateManager() { return StateMgr; }
98
99  QualType getConditionType() const {
100    return  getContext().IntTy;
101  }
102
103  QualType getArrayIndexType() const {
104    return ArrayIndexTy;
105  }
106
107  BasicValueFactory &getBasicValueFactory() { return BasicVals; }
108  const BasicValueFactory &getBasicValueFactory() const { return BasicVals; }
109
110  SymbolManager &getSymbolManager() { return SymMgr; }
111  const SymbolManager &getSymbolManager() const { return SymMgr; }
112
113  MemRegionManager &getRegionManager() { return MemMgr; }
114  const MemRegionManager &getRegionManager() const { return MemMgr; }
115
116  // Forwarding methods to SymbolManager.
117
118  const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T,
119                                          unsigned VisitCount,
120                                          const void* SymbolTag = 0) {
121    return SymMgr.getConjuredSymbol(E, T, VisitCount, SymbolTag);
122  }
123
124  const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount,
125                                          const void* SymbolTag = 0) {
126    return SymMgr.getConjuredSymbol(E, VisitCount, SymbolTag);
127  }
128
129  /// makeZeroVal - Construct an SVal representing '0' for the specified type.
130  DefinedOrUnknownSVal makeZeroVal(QualType T);
131
132  /// getRegionValueSymbolVal - make a unique symbol for value of R.
133  DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedRegion *R);
134
135  DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag,
136                                            const Expr *E, unsigned Count);
137  DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag,
138                                            const Expr *E, QualType T,
139                                            unsigned Count);
140
141  DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
142                                                      const TypedRegion *R);
143
144  DefinedSVal getMetadataSymbolVal(const void *SymbolTag, const MemRegion *MR,
145                                   const Expr *E, QualType T, unsigned Count);
146
147  DefinedSVal getFunctionPointer(const FunctionDecl *FD);
148
149  DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy,
150                              const LocationContext *LC);
151
152  NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) {
153    return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
154  }
155
156  NonLoc makeLazyCompoundVal(const void *store, const TypedRegion *R) {
157    return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(store, R));
158  }
159
160  NonLoc makeZeroArrayIndex() {
161    return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy));
162  }
163
164  NonLoc makeArrayIndex(uint64_t idx) {
165    return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy));
166  }
167
168  SVal convertToArrayIndex(SVal V);
169
170  nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) {
171    return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(),
172                                        I->getType()->isUnsignedIntegerType()));
173  }
174
175  nonloc::ConcreteInt makeIntVal(const CXXBoolLiteralExpr *E) {
176    return E->getValue() ? nonloc::ConcreteInt(BasicVals.getValue(1, 1, true))
177                         : nonloc::ConcreteInt(BasicVals.getValue(0, 1, true));
178  }
179
180  nonloc::ConcreteInt makeIntVal(const llvm::APSInt& V) {
181    return nonloc::ConcreteInt(BasicVals.getValue(V));
182  }
183
184  loc::ConcreteInt makeIntLocVal(const llvm::APSInt &v) {
185    return loc::ConcreteInt(BasicVals.getValue(v));
186  }
187
188  NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) {
189    return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned));
190  }
191
192  DefinedSVal makeIntVal(uint64_t X, QualType T) {
193    if (Loc::IsLocType(T))
194      return loc::ConcreteInt(BasicVals.getValue(X, T));
195
196    return nonloc::ConcreteInt(BasicVals.getValue(X, T));
197  }
198
199  NonLoc makeIntVal(uint64_t X, bool isUnsigned) {
200    return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned));
201  }
202
203  NonLoc makeIntValWithPtrWidth(uint64_t X, bool isUnsigned) {
204    return nonloc::ConcreteInt(BasicVals.getIntWithPtrWidth(X, isUnsigned));
205  }
206
207  NonLoc makeIntVal(uint64_t X, unsigned BitWidth, bool isUnsigned) {
208    return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned));
209  }
210
211  NonLoc makeLocAsInteger(Loc V, unsigned Bits) {
212    return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(V, Bits));
213  }
214
215  NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
216                    const llvm::APSInt& rhs, QualType T);
217
218  NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
219                    const SymExpr *rhs, QualType T);
220
221  NonLoc makeTruthVal(bool b, QualType T) {
222    return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T));
223  }
224
225  NonLoc makeTruthVal(bool b) {
226    return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
227  }
228
229  Loc makeNull() {
230    return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth());
231  }
232
233  Loc makeLoc(SymbolRef Sym) {
234    return loc::MemRegionVal(MemMgr.getSymbolicRegion(Sym));
235  }
236
237  Loc makeLoc(const MemRegion* R) {
238    return loc::MemRegionVal(R);
239  }
240
241  Loc makeLoc(const AddrLabelExpr* E) {
242    return loc::GotoLabel(E->getLabel());
243  }
244
245  Loc makeLoc(const llvm::APSInt& V) {
246    return loc::ConcreteInt(BasicVals.getValue(V));
247  }
248
249};
250
251SValBuilder* createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
252                                     ASTContext &context,
253                                     GRStateManager &stateMgr);
254
255} // end GR namespace
256
257} // end clang namespace
258
259#endif
260