 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
55.7% |
44 / 79 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
82.3% |
65 / 79 |
| |
|
Line Coverage: |
75.2% |
88 / 117 |
| |
 |
|
 |
1 : //=== BasicValueFactory.cpp - Basic values for Path Sens analysis --*- 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 BasicValueFactory, a class that manages the lifetime
11 : // of APSInt objects and symbolic constraints used by GRExprEngine
12 : // and related classes.
13 : //
14 : //===----------------------------------------------------------------------===//
15 :
16 : #include "clang/Checker/PathSensitive/BasicValueFactory.h"
17 :
18 : using namespace clang;
19 :
20 : void CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
21 110: llvm::ImmutableList<SVal> L) {
22 110: T.Profile(ID);
23 110: ID.AddPointer(L.getInternalPointer());
24 110: }
25 :
26 : void LazyCompoundValData::Profile(llvm::FoldingSetNodeID& ID,
27 52: const void *store,const TypedRegion *region) {
28 52: ID.AddPointer(store);
29 52: ID.AddPointer(region);
30 52: }
31 :
32 : typedef std::pair<SVal, uintptr_t> SValData;
33 : typedef std::pair<SVal, SVal> SValPair;
34 :
35 : namespace llvm {
36 : template<> struct FoldingSetTrait<SValData> {
37 10: static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
38 10: X.first.Profile(ID);
39 10: ID.AddPointer( (void*) X.second);
40 10: }
41 : };
42 :
43 : template<> struct FoldingSetTrait<SValPair> {
44 0: static inline void Profile(const SValPair& X, llvm::FoldingSetNodeID& ID) {
45 0: X.first.Profile(ID);
46 0: X.second.Profile(ID);
47 0: }
48 : };
49 : }
50 :
51 : typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValData> >
52 : PersistentSValsTy;
53 :
54 : typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValPair> >
55 : PersistentSValPairsTy;
56 :
57 2138: BasicValueFactory::~BasicValueFactory() {
58 : // Note that the dstor for the contents of APSIntSet will never be called,
59 : // so we iterate over the set and invoke the dstor for each APSInt. This
60 : // frees an aux. memory allocated to represent very large constants.
7171: branch 4 taken
2138: branch 5 taken
0: branch 10 not taken
0: branch 11 not taken
61 9309: for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
62 7171: I->getValue().~APSInt();
63 :
72: branch 0 taken
2066: branch 1 taken
72: branch 3 taken
72: branch 4 taken
64 2138: delete (PersistentSValsTy*) PersistentSVals;
0: branch 0 not taken
2138: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
65 2138: delete (PersistentSValPairsTy*) PersistentSValPairs;
66 2138: }
67 :
68 25739: const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
69 25739: llvm::FoldingSetNodeID ID;
70 : void* InsertPos;
71 : typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy;
72 :
73 25739: X.Profile(ID);
74 25739: FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
75 :
7171: branch 0 taken
18568: branch 1 taken
76 25739: if (!P) {
77 7171: P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
7171: branch 1 taken
0: branch 2 not taken
78 7171: new (P) FoldNodeTy(X);
7171: branch 0 taken
0: branch 1 not taken
79 7171: APSIntSet.InsertNode(P, InsertPos);
80 : }
81 :
82 25739: return *P;
83 : }
84 :
85 : const llvm::APSInt& BasicValueFactory::getValue(const llvm::APInt& X,
86 5175: bool isUnsigned) {
87 5175: llvm::APSInt V(X, isUnsigned);
88 5175: return getValue(V);
89 : }
90 :
91 : const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
92 5867: bool isUnsigned) {
93 5867: llvm::APSInt V(BitWidth, isUnsigned);
94 5867: V = X;
95 5867: return getValue(V);
96 : }
97 :
98 3064: const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
99 :
100 3064: unsigned bits = Ctx.getTypeSize(T);
2456: branch 2 taken
608: branch 3 taken
176: branch 5 taken
2280: branch 6 taken
101 3064: llvm::APSInt V(bits, T->isUnsignedIntegerType() || Loc::IsLocType(T));
102 3064: V = X;
103 3064: return getValue(V);
104 : }
105 :
106 : const CompoundValData*
107 : BasicValueFactory::getCompoundValData(QualType T,
108 109: llvm::ImmutableList<SVal> Vals) {
109 :
110 109: llvm::FoldingSetNodeID ID;
111 109: CompoundValData::Profile(ID, T, Vals);
112 : void* InsertPos;
113 :
114 109: CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
115 :
109: branch 0 taken
0: branch 1 not taken
116 109: if (!D) {
117 109: D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
109: branch 1 taken
0: branch 2 not taken
118 109: new (D) CompoundValData(T, Vals);
119 109: CompoundValDataSet.InsertNode(D, InsertPos);
120 : }
121 :
122 109: return D;
123 : }
124 :
125 : const LazyCompoundValData*
126 : BasicValueFactory::getLazyCompoundValData(const void *store,
127 52: const TypedRegion *region) {
128 52: llvm::FoldingSetNodeID ID;
129 52: LazyCompoundValData::Profile(ID, store, region);
130 : void* InsertPos;
131 :
132 : LazyCompoundValData *D =
133 52: LazyCompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
134 :
52: branch 0 taken
0: branch 1 not taken
135 52: if (!D) {
136 52: D = (LazyCompoundValData*) BPAlloc.Allocate<LazyCompoundValData>();
52: branch 1 taken
0: branch 2 not taken
137 52: new (D) LazyCompoundValData(store, region);
138 52: LazyCompoundValDataSet.InsertNode(D, InsertPos);
139 : }
140 :
141 52: return D;
142 : }
143 :
144 : const llvm::APSInt*
145 : BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op,
146 1359: const llvm::APSInt& V1, const llvm::APSInt& V2) {
147 :
0: branch 0 not taken
12: branch 1 taken
27: branch 2 taken
0: branch 3 not taken
837: branch 4 taken
32: branch 5 taken
104: branch 6 taken
4: branch 7 taken
141: branch 8 taken
28: branch 9 taken
0: branch 10 not taken
0: branch 11 not taken
149: branch 12 taken
3: branch 13 taken
0: branch 14 not taken
22: branch 15 taken
0: branch 16 not taken
148 1359: switch (Op) {
149 : default:
150 0: assert (false && "Invalid Opcode.");
151 :
152 : case BinaryOperator::Mul:
153 12: return &getValue( V1 * V2 );
154 :
155 : case BinaryOperator::Div:
156 27: return &getValue( V1 / V2 );
157 :
158 : case BinaryOperator::Rem:
159 0: return &getValue( V1 % V2 );
160 :
161 : case BinaryOperator::Add:
162 837: return &getValue( V1 + V2 );
163 :
164 : case BinaryOperator::Sub:
165 32: return &getValue( V1 - V2 );
166 :
167 : case BinaryOperator::Shl: {
168 :
169 : // FIXME: This logic should probably go higher up, where we can
170 : // test these conditions symbolically.
171 :
172 : // FIXME: Expand these checks to include all undefined behavior.
173 :
104: branch 1 taken
0: branch 2 not taken
0: branch 4 not taken
104: branch 5 taken
0: branch 6 not taken
104: branch 7 taken
174 104: if (V2.isSigned() && V2.isNegative())
175 0: return NULL;
176 :
177 104: uint64_t Amt = V2.getZExtValue();
178 :
0: branch 1 not taken
104: branch 2 taken
179 104: if (Amt > V1.getBitWidth())
180 0: return NULL;
181 :
182 104: return &getValue( V1.operator<<( (unsigned) Amt ));
183 : }
184 :
185 : case BinaryOperator::Shr: {
186 :
187 : // FIXME: This logic should probably go higher up, where we can
188 : // test these conditions symbolically.
189 :
190 : // FIXME: Expand these checks to include all undefined behavior.
191 :
4: branch 1 taken
0: branch 2 not taken
0: branch 4 not taken
4: branch 5 taken
0: branch 6 not taken
4: branch 7 taken
192 4: if (V2.isSigned() && V2.isNegative())
193 0: return NULL;
194 :
195 4: uint64_t Amt = V2.getZExtValue();
196 :
0: branch 1 not taken
4: branch 2 taken
197 4: if (Amt > V1.getBitWidth())
198 0: return NULL;
199 :
200 4: return &getValue( V1.operator>>( (unsigned) Amt ));
201 : }
202 :
203 : case BinaryOperator::LT:
204 141: return &getTruthValue( V1 < V2 );
205 :
206 : case BinaryOperator::GT:
207 28: return &getTruthValue( V1 > V2 );
208 :
209 : case BinaryOperator::LE:
210 0: return &getTruthValue( V1 <= V2 );
211 :
212 : case BinaryOperator::GE:
213 0: return &getTruthValue( V1 >= V2 );
214 :
215 : case BinaryOperator::EQ:
216 149: return &getTruthValue( V1 == V2 );
217 :
218 : case BinaryOperator::NE:
219 3: return &getTruthValue( V1 != V2 );
220 :
221 : // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
222 :
223 : case BinaryOperator::And:
224 0: return &getValue( V1 & V2 );
225 :
226 : case BinaryOperator::Or:
227 22: return &getValue( V1 | V2 );
228 :
229 : case BinaryOperator::Xor:
230 0: return &getValue( V1 ^ V2 );
231 : }
232 : }
233 :
234 :
235 : const std::pair<SVal, uintptr_t>&
236 93: BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
237 :
238 : // Lazily create the folding set.
72: branch 0 taken
21: branch 1 taken
239 93: if (!PersistentSVals) PersistentSVals = new PersistentSValsTy();
240 :
241 93: llvm::FoldingSetNodeID ID;
242 : void* InsertPos;
243 93: V.Profile(ID);
244 93: ID.AddPointer((void*) Data);
245 :
246 93: PersistentSValsTy& Map = *((PersistentSValsTy*) PersistentSVals);
247 :
248 : typedef llvm::FoldingSetNodeWrapper<SValData> FoldNodeTy;
249 93: FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
250 :
83: branch 0 taken
10: branch 1 taken
251 93: if (!P) {
252 83: P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
83: branch 2 taken
0: branch 3 not taken
253 83: new (P) FoldNodeTy(std::make_pair(V, Data));
83: branch 0 taken
0: branch 1 not taken
254 83: Map.InsertNode(P, InsertPos);
255 : }
256 :
257 93: return P->getValue();
258 : }
259 :
260 : const std::pair<SVal, SVal>&
261 0: BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) {
262 :
263 : // Lazily create the folding set.
0: branch 0 not taken
0: branch 1 not taken
264 0: if (!PersistentSValPairs) PersistentSValPairs = new PersistentSValPairsTy();
265 :
266 0: llvm::FoldingSetNodeID ID;
267 : void* InsertPos;
268 0: V1.Profile(ID);
269 0: V2.Profile(ID);
270 :
271 0: PersistentSValPairsTy& Map = *((PersistentSValPairsTy*) PersistentSValPairs);
272 :
273 : typedef llvm::FoldingSetNodeWrapper<SValPair> FoldNodeTy;
274 0: FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
275 :
0: branch 0 not taken
0: branch 1 not taken
276 0: if (!P) {
277 0: P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
0: branch 2 not taken
0: branch 3 not taken
278 0: new (P) FoldNodeTy(std::make_pair(V1, V2));
0: branch 0 not taken
0: branch 1 not taken
279 0: Map.InsertNode(P, InsertPos);
280 : }
281 :
282 0: return P->getValue();
283 : }
284 :
285 0: const SVal* BasicValueFactory::getPersistentSVal(SVal X) {
286 0: return &getPersistentSValWithData(X, 0).first;
287 0: }
288 :
289 :
Generated: 2010-02-10 01:31 by zcov