OLD | NEW |
1 // SValBuilder.cpp - Basic class for all SValBuilder implementations -*- C++ -*- | 1 // SValBuilder.cpp - Basic class for all SValBuilder implementations -*- C++ -*- |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file defines SValBuilder, the base class for all (complete) SValBuilder | 10 // This file defines SValBuilder, the base class for all (complete) SValBuilder |
11 // implementations. | 11 // implementations. |
12 // | 12 // |
13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
14 | 14 |
15 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" | 15 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" |
16 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" | 16 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" |
17 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" | 17 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" |
18 #include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h" | 18 #include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h" |
19 #include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h" | 19 #include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h" |
20 | 20 |
21 using namespace clang; | 21 using namespace clang; |
22 using namespace ento; | 22 using namespace ento; |
23 | 23 |
24 //===----------------------------------------------------------------------===// | 24 //===----------------------------------------------------------------------===// |
25 // Basic SVal creation. | 25 // Basic SVal creation. |
26 //===----------------------------------------------------------------------===// | 26 //===----------------------------------------------------------------------===// |
27 | 27 |
28 DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType T) { | 28 DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType type) { |
29 if (Loc::isLocType(T)) | 29 if (Loc::isLocType(type)) |
30 return makeNull(); | 30 return makeNull(); |
31 | 31 |
32 if (T->isIntegerType()) | 32 if (type->isIntegerType()) |
33 return makeIntVal(0, T); | 33 return makeIntVal(0, type); |
34 | 34 |
35 // FIXME: Handle floats. | 35 // FIXME: Handle floats. |
36 // FIXME: Handle structs. | 36 // FIXME: Handle structs. |
37 return UnknownVal(); | 37 return UnknownVal(); |
38 } | 38 } |
39 | 39 |
40 | 40 |
41 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, | 41 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, |
42 const llvm::APSInt& v, QualType T) { | 42 const llvm::APSInt& rhs, QualType type) { |
43 // The Environment ensures we always get a persistent APSInt in | 43 // The Environment ensures we always get a persistent APSInt in |
44 // BasicValueFactory, so we don't need to get the APSInt from | 44 // BasicValueFactory, so we don't need to get the APSInt from |
45 // BasicValueFactory again. | 45 // BasicValueFactory again. |
46 assert(!Loc::isLocType(T)); | 46 assert(!Loc::isLocType(type)); |
47 return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, v, T)); | 47 return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, rhs, type)); |
48 } | 48 } |
49 | 49 |
50 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, | 50 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, |
51 const SymExpr *rhs, QualType T) { | 51 const SymExpr *rhs, QualType type) { |
52 assert(SymMgr.getType(lhs) == SymMgr.getType(rhs)); | 52 assert(SymMgr.getType(lhs) == SymMgr.getType(rhs)); |
53 assert(!Loc::isLocType(T)); | 53 assert(!Loc::isLocType(type)); |
54 return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, T)); | 54 return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, type)); |
55 } | 55 } |
56 | 56 |
57 | 57 |
58 SVal SValBuilder::convertToArrayIndex(SVal V) { | 58 SVal SValBuilder::convertToArrayIndex(SVal val) { |
59 if (V.isUnknownOrUndef()) | 59 if (val.isUnknownOrUndef()) |
60 return V; | 60 return val; |
61 | 61 |
62 // Common case: we have an appropriately sized integer. | 62 // Common case: we have an appropriately sized integer. |
63 if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&V)) { | 63 if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&val)) { |
64 const llvm::APSInt& I = CI->getValue(); | 64 const llvm::APSInt& I = CI->getValue(); |
65 if (I.getBitWidth() == ArrayIndexWidth && I.isSigned()) | 65 if (I.getBitWidth() == ArrayIndexWidth && I.isSigned()) |
66 return V; | 66 return val; |
67 } | 67 } |
68 | 68 |
69 return evalCastNL(cast<NonLoc>(V), ArrayIndexTy); | 69 return evalCastFromNonLoc(cast<NonLoc>(val), ArrayIndexTy); |
70 } | 70 } |
71 | 71 |
72 DefinedOrUnknownSVal· | 72 DefinedOrUnknownSVal· |
73 SValBuilder::getRegionValueSymbolVal(const TypedRegion* R) { | 73 SValBuilder::getRegionValueSymbolVal(const TypedRegion* region) { |
74 QualType T = R->getValueType(); | 74 QualType T = region->getValueType(); |
75 | 75 |
76 if (!SymbolManager::canSymbolicate(T)) | 76 if (!SymbolManager::canSymbolicate(T)) |
77 return UnknownVal(); | 77 return UnknownVal(); |
78 | 78 |
79 SymbolRef sym = SymMgr.getRegionValueSymbol(R); | 79 SymbolRef sym = SymMgr.getRegionValueSymbol(region); |
80 | 80 |
81 if (Loc::isLocType(T)) | 81 if (Loc::isLocType(T)) |
82 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); | 82 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); |
83 | 83 |
84 return nonloc::SymbolVal(sym); | 84 return nonloc::SymbolVal(sym); |
85 } | 85 } |
86 | 86 |
87 DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *SymbolTag, | 87 DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *symbolTag, |
88 const Expr *E, | 88 const Expr *expr, |
89 unsigned Count) { | 89 unsigned count) { |
90 QualType T = E->getType(); | 90 QualType T = expr->getType(); |
91 | 91 |
92 if (!SymbolManager::canSymbolicate(T)) | 92 if (!SymbolManager::canSymbolicate(T)) |
93 return UnknownVal(); | 93 return UnknownVal(); |
94 | 94 |
95 SymbolRef sym = SymMgr.getConjuredSymbol(E, Count, SymbolTag); | 95 SymbolRef sym = SymMgr.getConjuredSymbol(expr, count, symbolTag); |
96 | 96 |
97 if (Loc::isLocType(T)) | 97 if (Loc::isLocType(T)) |
98 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); | 98 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); |
99 | 99 |
100 return nonloc::SymbolVal(sym); | 100 return nonloc::SymbolVal(sym); |
101 } | 101 } |
102 | 102 |
103 DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *SymbolTag, | 103 DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *symbolTag, |
104 const Expr *E, | 104 const Expr *expr, |
105 QualType T, | 105 QualType type, |
106 unsigned Count) { | 106 unsigned count) { |
107 ·· | 107 ·· |
108 if (!SymbolManager::canSymbolicate(T)) | 108 if (!SymbolManager::canSymbolicate(type)) |
109 return UnknownVal(); | 109 return UnknownVal(); |
110 | 110 |
111 SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count, SymbolTag); | 111 SymbolRef sym = SymMgr.getConjuredSymbol(expr, type, count, symbolTag); |
112 | 112 |
113 if (Loc::isLocType(T)) | 113 if (Loc::isLocType(type)) |
114 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); | 114 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); |
115 | 115 |
116 return nonloc::SymbolVal(sym); | 116 return nonloc::SymbolVal(sym); |
117 } | 117 } |
118 | 118 |
119 DefinedSVal SValBuilder::getMetadataSymbolVal(const void *SymbolTag, | 119 DefinedSVal SValBuilder::getMetadataSymbolVal(const void *symbolTag, |
120 const MemRegion *MR, | 120 const MemRegion *region, |
121 const Expr *E, QualType T, | 121 const Expr *expr, QualType type, |
122 unsigned Count) { | 122 unsigned count) { |
123 assert(SymbolManager::canSymbolicate(T) && "Invalid metadata symbol type"); | 123 assert(SymbolManager::canSymbolicate(type) && "Invalid metadata symbol type"); |
124 | 124 |
125 SymbolRef sym = SymMgr.getMetadataSymbol(MR, E, T, Count, SymbolTag); | 125 SymbolRef sym = |
| 126 SymMgr.getMetadataSymbol(region, expr, type, count, symbolTag); |
126 | 127 |
127 if (Loc::isLocType(T)) | 128 if (Loc::isLocType(type)) |
128 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); | 129 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); |
129 | 130 |
130 return nonloc::SymbolVal(sym); | 131 return nonloc::SymbolVal(sym); |
131 } | 132 } |
132 | 133 |
133 DefinedOrUnknownSVal | 134 DefinedOrUnknownSVal |
134 SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, | 135 SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, |
135 const TypedRegion *R) { | 136 const TypedRegion *region) { |
136 QualType T = R->getValueType(); | 137 QualType T = region->getValueType(); |
137 | 138 |
138 if (!SymbolManager::canSymbolicate(T)) | 139 if (!SymbolManager::canSymbolicate(T)) |
139 return UnknownVal(); | 140 return UnknownVal(); |
140 | 141 |
141 SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, R); | 142 SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, region); |
142 | 143 |
143 if (Loc::isLocType(T)) | 144 if (Loc::isLocType(T)) |
144 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); | 145 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); |
145 | 146 |
146 return nonloc::SymbolVal(sym); | 147 return nonloc::SymbolVal(sym); |
147 } | 148 } |
148 | 149 |
149 DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl* FD) { | 150 DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl* func) { |
150 return loc::MemRegionVal(MemMgr.getFunctionTextRegion(FD)); | 151 return loc::MemRegionVal(MemMgr.getFunctionTextRegion(func)); |
151 } | 152 } |
152 | 153 |
153 DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *D, | 154 DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block, |
154 CanQualType locTy, | 155 CanQualType locTy, |
155 const LocationContext *LC) { | 156 const LocationContext *locContext) { |
156 const BlockTextRegion *BC = | 157 const BlockTextRegion *BC = |
157 MemMgr.getBlockTextRegion(D, locTy, LC->getAnalysisContext()); | 158 MemMgr.getBlockTextRegion(block, locTy, locContext->getAnalysisContext()); |
158 const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, LC); | 159 const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext); |
159 return loc::MemRegionVal(BD); | 160 return loc::MemRegionVal(BD); |
160 } | 161 } |
161 | 162 |
162 //===----------------------------------------------------------------------===// | 163 //===----------------------------------------------------------------------===// |
163 | 164 |
164 SVal SValBuilder::evalBinOp(const GRState *ST, BinaryOperator::Opcode Op, | 165 SVal SValBuilder::evalBinOp(const GRState *state, BinaryOperator::Opcode op, |
165 SVal L, SVal R, QualType T) { | 166 SVal lhs, SVal rhs, QualType type) { |
166 | 167 |
167 if (L.isUndef() || R.isUndef()) | 168 if (lhs.isUndef() || rhs.isUndef()) |
168 return UndefinedVal(); | 169 return UndefinedVal(); |
169 | 170 |
170 if (L.isUnknown() || R.isUnknown()) | 171 if (lhs.isUnknown() || rhs.isUnknown()) |
171 return UnknownVal(); | 172 return UnknownVal(); |
172 | 173 |
173 if (isa<Loc>(L)) { | 174 if (isa<Loc>(lhs)) { |
174 if (isa<Loc>(R)) | 175 if (isa<Loc>(rhs)) |
175 return evalBinOpLL(ST, Op, cast<Loc>(L), cast<Loc>(R), T); | 176 return evalBinOpLL(state, op, cast<Loc>(lhs), cast<Loc>(rhs), type); |
176 | 177 |
177 return evalBinOpLN(ST, Op, cast<Loc>(L), cast<NonLoc>(R), T); | 178 return evalBinOpLN(state, op, cast<Loc>(lhs), cast<NonLoc>(rhs), type); |
178 } | 179 } |
179 | 180 |
180 if (isa<Loc>(R)) { | 181 if (isa<Loc>(rhs)) { |
181 // Support pointer arithmetic where the addend is on the left | 182 // Support pointer arithmetic where the addend is on the left |
182 // and the pointer on the right. | 183 // and the pointer on the right. |
183 assert(Op == BO_Add); | 184 assert(op == BO_Add); |
184 | 185 |
185 // Commute the operands. | 186 // Commute the operands. |
186 return evalBinOpLN(ST, Op, cast<Loc>(R), cast<NonLoc>(L), T); | 187 return evalBinOpLN(state, op, cast<Loc>(rhs), cast<NonLoc>(lhs), type); |
187 } | 188 } |
188 | 189 |
189 return evalBinOpNN(ST, Op, cast<NonLoc>(L), cast<NonLoc>(R), T); | 190 return evalBinOpNN(state, op, cast<NonLoc>(lhs), cast<NonLoc>(rhs), type); |
190 } | 191 } |
191 | 192 |
192 DefinedOrUnknownSVal SValBuilder::evalEQ(const GRState *ST, | 193 DefinedOrUnknownSVal SValBuilder::evalEQ(const GRState *state, |
193 DefinedOrUnknownSVal L, | 194 DefinedOrUnknownSVal lhs, |
194 DefinedOrUnknownSVal R) { | 195 DefinedOrUnknownSVal rhs) { |
195 return cast<DefinedOrUnknownSVal>(evalBinOp(ST, BO_EQ, L, R, | 196 return cast<DefinedOrUnknownSVal>(evalBinOp(state, BO_EQ, lhs, rhs, |
196 Context.IntTy)); | 197 Context.IntTy)); |
197 } | 198 } |
198 | 199 |
199 // FIXME: should rewrite according to the cast kind. | 200 // FIXME: should rewrite according to the cast kind. |
200 SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) { | 201 SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) { |
201 if (val.isUnknownOrUndef() || castTy == originalTy) | 202 if (val.isUnknownOrUndef() || castTy == originalTy) |
202 return val; | 203 return val; |
203 | 204 |
204 // For const casts, just propagate the value. | 205 // For const casts, just propagate the value. |
205 if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType()) | 206 if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType()) |
206 if (Context.hasSameUnqualifiedType(castTy, originalTy)) | 207 if (Context.hasSameUnqualifiedType(castTy, originalTy)) |
207 return val; | 208 return val; |
208 | 209 |
209 // Check for casts to real or complex numbers. We don't handle these at all | 210 // Check for casts to real or complex numbers. We don't handle these at all |
210 // right now. | 211 // right now. |
211 if (castTy->isFloatingType() || castTy->isAnyComplexType()) | 212 if (castTy->isFloatingType() || castTy->isAnyComplexType()) |
212 return UnknownVal(); | 213 return UnknownVal(); |
213 ·· | 214 ·· |
214 // Check for casts from integers to integers. | 215 // Check for casts from integers to integers. |
215 if (castTy->isIntegerType() && originalTy->isIntegerType()) | 216 if (castTy->isIntegerType() && originalTy->isIntegerType()) |
216 return evalCastNL(cast<NonLoc>(val), castTy); | 217 return evalCastFromNonLoc(cast<NonLoc>(val), castTy); |
217 | 218 |
218 // Check for casts from pointers to integers. | 219 // Check for casts from pointers to integers. |
219 if (castTy->isIntegerType() && Loc::isLocType(originalTy)) | 220 if (castTy->isIntegerType() && Loc::isLocType(originalTy)) |
220 return evalCastL(cast<Loc>(val), castTy); | 221 return evalCastFromLoc(cast<Loc>(val), castTy); |
221 | 222 |
222 // Check for casts from integers to pointers. | 223 // Check for casts from integers to pointers. |
223 if (Loc::isLocType(castTy) && originalTy->isIntegerType()) { | 224 if (Loc::isLocType(castTy) && originalTy->isIntegerType()) { |
224 if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) { | 225 if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) { |
225 if (const MemRegion *R = LV->getLoc().getAsRegion()) { | 226 if (const MemRegion *R = LV->getLoc().getAsRegion()) { |
226 StoreManager &storeMgr = StateMgr.getStoreManager(); | 227 StoreManager &storeMgr = StateMgr.getStoreManager(); |
227 R = storeMgr.castRegion(R, castTy); | 228 R = storeMgr.castRegion(R, castTy); |
228 return R ? SVal(loc::MemRegionVal(R)) : UnknownVal(); | 229 return R ? SVal(loc::MemRegionVal(R)) : UnknownVal(); |
229 } | 230 } |
230 return LV->getLoc(); | 231 return LV->getLoc(); |
(...skipping 18 matching lines...) Expand all Loading... |
249 return val; | 250 return val; |
250 | 251 |
251 // Are we casting from an array to an integer? If so, cast the decayed | 252 // Are we casting from an array to an integer? If so, cast the decayed |
252 // pointer value to an integer. | 253 // pointer value to an integer. |
253 assert(castTy->isIntegerType()); | 254 assert(castTy->isIntegerType()); |
254 | 255 |
255 // FIXME: Keep these here for now in case we decide soon that we | 256 // FIXME: Keep these here for now in case we decide soon that we |
256 // need the original decayed type. | 257 // need the original decayed type. |
257 // QualType elemTy = cast<ArrayType>(originalTy)->getElementType(); | 258 // QualType elemTy = cast<ArrayType>(originalTy)->getElementType(); |
258 // QualType pointerTy = C.getPointerType(elemTy); | 259 // QualType pointerTy = C.getPointerType(elemTy); |
259 return evalCastL(cast<Loc>(val), castTy); | 260 return evalCastFromLoc(cast<Loc>(val), castTy); |
260 } | 261 } |
261 | 262 |
262 // Check for casts from a region to a specific type. | 263 // Check for casts from a region to a specific type. |
263 if (const MemRegion *R = val.getAsRegion()) { | 264 if (const MemRegion *R = val.getAsRegion()) { |
264 // FIXME: We should handle the case where we strip off view layers to get | 265 // FIXME: We should handle the case where we strip off view layers to get |
265 // to a desugared type. | 266 // to a desugared type. |
266 | 267 |
267 if (!Loc::isLocType(castTy)) { | 268 if (!Loc::isLocType(castTy)) { |
268 // FIXME: There can be gross cases where one casts the result of a functio
n | 269 // FIXME: There can be gross cases where one casts the result of a functio
n |
269 // (that returns a pointer) to some other value that happens to fit | 270 // (that returns a pointer) to some other value that happens to fit |
(...skipping 28 matching lines...) Expand all Loading... |
298 | 299 |
299 // Delegate to store manager to get the result of casting a region to a | 300 // Delegate to store manager to get the result of casting a region to a |
300 // different type. If the MemRegion* returned is NULL, this expression | 301 // different type. If the MemRegion* returned is NULL, this expression |
301 // Evaluates to UnknownVal. | 302 // Evaluates to UnknownVal. |
302 R = storeMgr.castRegion(R, castTy); | 303 R = storeMgr.castRegion(R, castTy); |
303 return R ? SVal(loc::MemRegionVal(R)) : UnknownVal(); | 304 return R ? SVal(loc::MemRegionVal(R)) : UnknownVal(); |
304 } | 305 } |
305 | 306 |
306 DispatchCast: | 307 DispatchCast: |
307 // All other cases. | 308 // All other cases. |
308 return isa<Loc>(val) ? evalCastL(cast<Loc>(val), castTy) | 309 return isa<Loc>(val) ? evalCastFromLoc(cast<Loc>(val), castTy) |
309 : evalCastNL(cast<NonLoc>(val), castTy); | 310 : evalCastFromNonLoc(cast<NonLoc>(val), castTy); |
310 } | 311 } |
OLD | NEW |