/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //=-- ExprEngineC.cpp - ExprEngine support for C expressions ----*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file defines ExprEngine's support for C expressions. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "clang/AST/ExprCXX.h" |
14 | | #include "clang/AST/DeclCXX.h" |
15 | | #include "clang/StaticAnalyzer/Core/CheckerManager.h" |
16 | | #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" |
17 | | |
18 | | using namespace clang; |
19 | | using namespace ento; |
20 | | using llvm::APSInt; |
21 | | |
22 | | /// Optionally conjure and return a symbol for offset when processing |
23 | | /// an expression \p Expression. |
24 | | /// If \p Other is a location, conjure a symbol for \p Symbol |
25 | | /// (offset) if it is unknown so that memory arithmetic always |
26 | | /// results in an ElementRegion. |
27 | | /// \p Count The number of times the current basic block was visited. |
28 | | static SVal conjureOffsetSymbolOnLocation( |
29 | | SVal Symbol, SVal Other, Expr* Expression, SValBuilder &svalBuilder, |
30 | 25.5k | unsigned Count, const LocationContext *LCtx) { |
31 | 25.5k | QualType Ty = Expression->getType(); |
32 | 25.5k | if (Other.getAs<Loc>() && |
33 | 25.5k | Ty->isIntegralOrEnumerationType()10.1k && |
34 | 25.5k | Symbol.isUnknown()10.0k ) { |
35 | 0 | return svalBuilder.conjureSymbolVal(Expression, LCtx, Ty, Count); |
36 | 0 | } |
37 | 25.5k | return Symbol; |
38 | 25.5k | } |
39 | | |
40 | | void ExprEngine::VisitBinaryOperator(const BinaryOperator* B, |
41 | | ExplodedNode *Pred, |
42 | 73.1k | ExplodedNodeSet &Dst) { |
43 | | |
44 | 73.1k | Expr *LHS = B->getLHS()->IgnoreParens(); |
45 | 73.1k | Expr *RHS = B->getRHS()->IgnoreParens(); |
46 | | |
47 | | // FIXME: Prechecks eventually go in ::Visit(). |
48 | 73.1k | ExplodedNodeSet CheckedSet; |
49 | 73.1k | ExplodedNodeSet Tmp2; |
50 | 73.1k | getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this); |
51 | | |
52 | | // With both the LHS and RHS evaluated, process the operation itself. |
53 | 73.1k | for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end(); |
54 | 146k | it != ei; ++it72.9k ) { |
55 | | |
56 | 72.9k | ProgramStateRef state = (*it)->getState(); |
57 | 72.9k | const LocationContext *LCtx = (*it)->getLocationContext(); |
58 | 72.9k | SVal LeftV = state->getSVal(LHS, LCtx); |
59 | 72.9k | SVal RightV = state->getSVal(RHS, LCtx); |
60 | | |
61 | 72.9k | BinaryOperator::Opcode Op = B->getOpcode(); |
62 | | |
63 | 72.9k | if (Op == BO_Assign) { |
64 | | // EXPERIMENTAL: "Conjured" symbols. |
65 | | // FIXME: Handle structs. |
66 | 20.8k | if (RightV.isUnknown()) { |
67 | 2.96k | unsigned Count = currBldrCtx->blockCount(); |
68 | 2.96k | RightV = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, |
69 | 2.96k | Count); |
70 | 2.96k | } |
71 | | // Simulate the effects of a "store": bind the value of the RHS |
72 | | // to the L-Value represented by the LHS. |
73 | 20.8k | SVal ExprVal = B->isGLValue() ? LeftV14.8k : RightV6.02k ; |
74 | 20.8k | evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, LCtx, ExprVal), |
75 | 20.8k | LeftV, RightV); |
76 | 20.8k | continue; |
77 | 20.8k | } |
78 | | |
79 | 52.0k | if (!B->isAssignmentOp()) { |
80 | 50.9k | StmtNodeBuilder Bldr(*it, Tmp2, *currBldrCtx); |
81 | | |
82 | 50.9k | if (B->isAdditiveOp()) { |
83 | | // TODO: This can be removed after we enable history tracking with |
84 | | // SymSymExpr. |
85 | 12.7k | unsigned Count = currBldrCtx->blockCount(); |
86 | 12.7k | RightV = conjureOffsetSymbolOnLocation( |
87 | 12.7k | RightV, LeftV, RHS, svalBuilder, Count, LCtx); |
88 | 12.7k | LeftV = conjureOffsetSymbolOnLocation( |
89 | 12.7k | LeftV, RightV, LHS, svalBuilder, Count, LCtx); |
90 | 12.7k | } |
91 | | |
92 | | // Although we don't yet model pointers-to-members, we do need to make |
93 | | // sure that the members of temporaries have a valid 'this' pointer for |
94 | | // other checks. |
95 | 50.9k | if (B->getOpcode() == BO_PtrMemD) |
96 | 23 | state = createTemporaryRegionIfNeeded(state, LCtx, LHS); |
97 | | |
98 | | // Process non-assignments except commas or short-circuited |
99 | | // logical expressions (LAnd and LOr). |
100 | 50.9k | SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType()); |
101 | 50.9k | if (!Result.isUnknown()) { |
102 | 50.1k | state = state->BindExpr(B, LCtx, Result); |
103 | 50.1k | } else { |
104 | | // If we cannot evaluate the operation escape the operands. |
105 | 830 | state = escapeValues(state, LeftV, PSK_EscapeOther); |
106 | 830 | state = escapeValues(state, RightV, PSK_EscapeOther); |
107 | 830 | } |
108 | | |
109 | 50.9k | Bldr.generateNode(B, *it, state); |
110 | 50.9k | continue; |
111 | 50.9k | } |
112 | | |
113 | 1.02k | assert (B->isCompoundAssignmentOp()); |
114 | | |
115 | 0 | switch (Op) { |
116 | 0 | default: |
117 | 0 | llvm_unreachable("Invalid opcode for compound assignment."); |
118 | 34 | case BO_MulAssign: Op = BO_Mul; break; |
119 | 29 | case BO_DivAssign: Op = BO_Div; break; |
120 | 12 | case BO_RemAssign: Op = BO_Rem; break; |
121 | 471 | case BO_AddAssign: Op = BO_Add; break; |
122 | 196 | case BO_SubAssign: Op = BO_Sub; break; |
123 | 20 | case BO_ShlAssign: Op = BO_Shl; break; |
124 | 8 | case BO_ShrAssign: Op = BO_Shr; break; |
125 | 171 | case BO_AndAssign: Op = BO_And; break; |
126 | 66 | case BO_XorAssign: Op = BO_Xor; break; |
127 | 20 | case BO_OrAssign: Op = BO_Or; break; |
128 | 1.02k | } |
129 | | |
130 | | // Perform a load (the LHS). This performs the checks for |
131 | | // null dereferences, and so on. |
132 | 1.02k | ExplodedNodeSet Tmp; |
133 | 1.02k | SVal location = LeftV; |
134 | 1.02k | evalLoad(Tmp, B, LHS, *it, state, location); |
135 | | |
136 | 2.05k | for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; |
137 | 1.02k | ++I1.02k ) { |
138 | | |
139 | 1.02k | state = (*I)->getState(); |
140 | 1.02k | const LocationContext *LCtx = (*I)->getLocationContext(); |
141 | 1.02k | SVal V = state->getSVal(LHS, LCtx); |
142 | | |
143 | | // Get the computation type. |
144 | 1.02k | QualType CTy = |
145 | 1.02k | cast<CompoundAssignOperator>(B)->getComputationResultType(); |
146 | 1.02k | CTy = getContext().getCanonicalType(CTy); |
147 | | |
148 | 1.02k | QualType CLHSTy = |
149 | 1.02k | cast<CompoundAssignOperator>(B)->getComputationLHSType(); |
150 | 1.02k | CLHSTy = getContext().getCanonicalType(CLHSTy); |
151 | | |
152 | 1.02k | QualType LTy = getContext().getCanonicalType(LHS->getType()); |
153 | | |
154 | | // Promote LHS. |
155 | 1.02k | V = svalBuilder.evalCast(V, CLHSTy, LTy); |
156 | | |
157 | | // Compute the result of the operation. |
158 | 1.02k | SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy), |
159 | 1.02k | B->getType(), CTy); |
160 | | |
161 | | // EXPERIMENTAL: "Conjured" symbols. |
162 | | // FIXME: Handle structs. |
163 | | |
164 | 1.02k | SVal LHSVal; |
165 | | |
166 | 1.02k | if (Result.isUnknown()) { |
167 | | // The symbolic value is actually for the type of the left-hand side |
168 | | // expression, not the computation type, as this is the value the |
169 | | // LValue on the LHS will bind to. |
170 | 179 | LHSVal = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, LTy, |
171 | 179 | currBldrCtx->blockCount()); |
172 | | // However, we need to convert the symbol to the computation type. |
173 | 179 | Result = svalBuilder.evalCast(LHSVal, CTy, LTy); |
174 | 179 | } |
175 | 846 | else { |
176 | | // The left-hand side may bind to a different value then the |
177 | | // computation type. |
178 | 846 | LHSVal = svalBuilder.evalCast(Result, LTy, CTy); |
179 | 846 | } |
180 | | |
181 | | // In C++, assignment and compound assignment operators return an |
182 | | // lvalue. |
183 | 1.02k | if (B->isGLValue()) |
184 | 262 | state = state->BindExpr(B, LCtx, location); |
185 | 763 | else |
186 | 763 | state = state->BindExpr(B, LCtx, Result); |
187 | | |
188 | 1.02k | evalStore(Tmp2, B, LHS, *I, state, location, LHSVal); |
189 | 1.02k | } |
190 | 1.02k | } |
191 | | |
192 | | // FIXME: postvisits eventually go in ::Visit() |
193 | 73.1k | getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this); |
194 | 73.1k | } |
195 | | |
196 | | void ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, |
197 | 384 | ExplodedNodeSet &Dst) { |
198 | | |
199 | 384 | CanQualType T = getContext().getCanonicalType(BE->getType()); |
200 | | |
201 | 384 | const BlockDecl *BD = BE->getBlockDecl(); |
202 | | // Get the value of the block itself. |
203 | 384 | SVal V = svalBuilder.getBlockPointer(BD, T, |
204 | 384 | Pred->getLocationContext(), |
205 | 384 | currBldrCtx->blockCount()); |
206 | | |
207 | 384 | ProgramStateRef State = Pred->getState(); |
208 | | |
209 | | // If we created a new MemRegion for the block, we should explicitly bind |
210 | | // the captured variables. |
211 | 384 | if (const BlockDataRegion *BDR = |
212 | 384 | dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) { |
213 | | |
214 | 384 | BlockDataRegion::referenced_vars_iterator I = BDR->referenced_vars_begin(), |
215 | 384 | E = BDR->referenced_vars_end(); |
216 | | |
217 | 384 | auto CI = BD->capture_begin(); |
218 | 384 | auto CE = BD->capture_end(); |
219 | 701 | for (; I != E; ++I317 ) { |
220 | 317 | const VarRegion *capturedR = I.getCapturedRegion(); |
221 | 317 | const TypedValueRegion *originalR = I.getOriginalRegion(); |
222 | | |
223 | | // If the capture had a copy expression, use the result of evaluating |
224 | | // that expression, otherwise use the original value. |
225 | | // We rely on the invariant that the block declaration's capture variables |
226 | | // are a prefix of the BlockDataRegion's referenced vars (which may include |
227 | | // referenced globals, etc.) to enable fast lookup of the capture for a |
228 | | // given referenced var. |
229 | 317 | const Expr *copyExpr = nullptr; |
230 | 317 | if (CI != CE) { |
231 | 277 | assert(CI->getVariable() == capturedR->getDecl()); |
232 | 0 | copyExpr = CI->getCopyExpr(); |
233 | 277 | CI++; |
234 | 277 | } |
235 | | |
236 | 317 | if (capturedR != originalR) { |
237 | 205 | SVal originalV; |
238 | 205 | const LocationContext *LCtx = Pred->getLocationContext(); |
239 | 205 | if (copyExpr) { |
240 | 10 | originalV = State->getSVal(copyExpr, LCtx); |
241 | 195 | } else { |
242 | 195 | originalV = State->getSVal(loc::MemRegionVal(originalR)); |
243 | 195 | } |
244 | 205 | State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, LCtx); |
245 | 205 | } |
246 | 317 | } |
247 | 384 | } |
248 | | |
249 | 384 | ExplodedNodeSet Tmp; |
250 | 384 | StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx); |
251 | 384 | Bldr.generateNode(BE, Pred, |
252 | 384 | State->BindExpr(BE, Pred->getLocationContext(), V), |
253 | 384 | nullptr, ProgramPoint::PostLValueKind); |
254 | | |
255 | | // FIXME: Move all post/pre visits to ::Visit(). |
256 | 384 | getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this); |
257 | 384 | } |
258 | | |
259 | | ProgramStateRef ExprEngine::handleLValueBitCast( |
260 | | ProgramStateRef state, const Expr* Ex, const LocationContext* LCtx, |
261 | | QualType T, QualType ExTy, const CastExpr* CastE, StmtNodeBuilder& Bldr, |
262 | 46.8k | ExplodedNode* Pred) { |
263 | 46.8k | if (T->isLValueReferenceType()) { |
264 | 6 | assert(!CastE->getType()->isLValueReferenceType()); |
265 | 0 | ExTy = getContext().getLValueReferenceType(ExTy); |
266 | 46.7k | } else if (T->isRValueReferenceType()) { |
267 | 1 | assert(!CastE->getType()->isRValueReferenceType()); |
268 | 0 | ExTy = getContext().getRValueReferenceType(ExTy); |
269 | 1 | } |
270 | | // Delegate to SValBuilder to process. |
271 | 0 | SVal OrigV = state->getSVal(Ex, LCtx); |
272 | 46.8k | SVal V = svalBuilder.evalCast(OrigV, T, ExTy); |
273 | | // Negate the result if we're treating the boolean as a signed i1 |
274 | 46.8k | if (CastE->getCastKind() == CK_BooleanToSignedIntegral) |
275 | 0 | V = evalMinus(V); |
276 | 46.8k | state = state->BindExpr(CastE, LCtx, V); |
277 | 46.8k | if (V.isUnknown() && !OrigV.isUnknown()883 ) { |
278 | 242 | state = escapeValues(state, OrigV, PSK_EscapeOther); |
279 | 242 | } |
280 | 46.8k | Bldr.generateNode(CastE, Pred, state); |
281 | | |
282 | 46.8k | return state; |
283 | 46.8k | } |
284 | | |
285 | | ProgramStateRef ExprEngine::handleLVectorSplat( |
286 | | ProgramStateRef state, const LocationContext* LCtx, const CastExpr* CastE, |
287 | 0 | StmtNodeBuilder &Bldr, ExplodedNode* Pred) { |
288 | | // Recover some path sensitivity by conjuring a new value. |
289 | 0 | QualType resultType = CastE->getType(); |
290 | 0 | if (CastE->isGLValue()) |
291 | 0 | resultType = getContext().getPointerType(resultType); |
292 | 0 | SVal result = svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, |
293 | 0 | resultType, |
294 | 0 | currBldrCtx->blockCount()); |
295 | 0 | state = state->BindExpr(CastE, LCtx, result); |
296 | 0 | Bldr.generateNode(CastE, Pred, state); |
297 | |
|
298 | 0 | return state; |
299 | 0 | } |
300 | | |
301 | | void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, |
302 | 322k | ExplodedNode *Pred, ExplodedNodeSet &Dst) { |
303 | | |
304 | 322k | ExplodedNodeSet dstPreStmt; |
305 | 322k | getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this); |
306 | | |
307 | 322k | if (CastE->getCastKind() == CK_LValueToRValue) { |
308 | 139k | for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end(); |
309 | 279k | I!=E; ++I139k ) { |
310 | 139k | ExplodedNode *subExprNode = *I; |
311 | 139k | ProgramStateRef state = subExprNode->getState(); |
312 | 139k | const LocationContext *LCtx = subExprNode->getLocationContext(); |
313 | 139k | evalLoad(Dst, CastE, CastE, subExprNode, state, state->getSVal(Ex, LCtx)); |
314 | 139k | } |
315 | 139k | return; |
316 | 139k | } |
317 | | |
318 | | // All other casts. |
319 | 182k | QualType T = CastE->getType(); |
320 | 182k | QualType ExTy = Ex->getType(); |
321 | | |
322 | 182k | if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE)) |
323 | 18.1k | T = ExCast->getTypeAsWritten(); |
324 | | |
325 | 182k | StmtNodeBuilder Bldr(dstPreStmt, Dst, *currBldrCtx); |
326 | 182k | for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end(); |
327 | 365k | I != E; ++I182k ) { |
328 | | |
329 | 182k | Pred = *I; |
330 | 182k | ProgramStateRef state = Pred->getState(); |
331 | 182k | const LocationContext *LCtx = Pred->getLocationContext(); |
332 | | |
333 | 182k | switch (CastE->getCastKind()) { |
334 | 0 | case CK_LValueToRValue: |
335 | 0 | llvm_unreachable("LValueToRValue casts handled earlier."); |
336 | 852 | case CK_ToVoid: |
337 | 852 | continue; |
338 | | // The analyzer doesn't do anything special with these casts, |
339 | | // since it understands retain/release semantics already. |
340 | 99 | case CK_ARCProduceObject: |
341 | 191 | case CK_ARCConsumeObject: |
342 | 364 | case CK_ARCReclaimReturnedObject: |
343 | 364 | case CK_ARCExtendBlockObject: // Fall-through. |
344 | 368 | case CK_CopyAndAutoreleaseBlockObject: |
345 | | // The analyser can ignore atomic casts for now, although some future |
346 | | // checkers may want to make certain that you're not modifying the same |
347 | | // value through atomic and nonatomic pointers. |
348 | 369 | case CK_AtomicToNonAtomic: |
349 | 370 | case CK_NonAtomicToAtomic: |
350 | | // True no-ops. |
351 | 34.7k | case CK_NoOp: |
352 | 36.7k | case CK_ConstructorConversion: |
353 | 36.9k | case CK_UserDefinedConversion: |
354 | 96.6k | case CK_FunctionToPointerDecay: |
355 | 97.7k | case CK_BuiltinFnToFnPtr: { |
356 | | // Copy the SVal of Ex to CastE. |
357 | 97.7k | ProgramStateRef state = Pred->getState(); |
358 | 97.7k | const LocationContext *LCtx = Pred->getLocationContext(); |
359 | 97.7k | SVal V = state->getSVal(Ex, LCtx); |
360 | 97.7k | state = state->BindExpr(CastE, LCtx, V); |
361 | 97.7k | Bldr.generateNode(CastE, Pred, state); |
362 | 97.7k | continue; |
363 | 96.6k | } |
364 | 20 | case CK_MemberPointerToBoolean: |
365 | 900 | case CK_PointerToBoolean: { |
366 | 900 | SVal V = state->getSVal(Ex, LCtx); |
367 | 900 | auto PTMSV = V.getAs<nonloc::PointerToMember>(); |
368 | 900 | if (PTMSV) |
369 | 20 | V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy); |
370 | 900 | if (V.isUndef() || PTMSV) { |
371 | 20 | state = state->BindExpr(CastE, LCtx, V); |
372 | 20 | Bldr.generateNode(CastE, Pred, state); |
373 | 20 | continue; |
374 | 20 | } |
375 | | // Explicitly proceed with default handler for this case cascade. |
376 | 880 | state = |
377 | 880 | handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); |
378 | 880 | continue; |
379 | 900 | } |
380 | 0 | case CK_Dependent: |
381 | 9.36k | case CK_ArrayToPointerDecay: |
382 | 20.3k | case CK_BitCast: |
383 | 20.3k | case CK_LValueToRValueBitCast: |
384 | 20.3k | case CK_AddressSpaceConversion: |
385 | 20.3k | case CK_BooleanToSignedIntegral: |
386 | 20.4k | case CK_IntegralToPointer: |
387 | 20.5k | case CK_PointerToIntegral: { |
388 | 20.5k | SVal V = state->getSVal(Ex, LCtx); |
389 | 20.5k | if (V.getAs<nonloc::PointerToMember>()) { |
390 | 0 | state = state->BindExpr(CastE, LCtx, UnknownVal()); |
391 | 0 | Bldr.generateNode(CastE, Pred, state); |
392 | 0 | continue; |
393 | 0 | } |
394 | | // Explicitly proceed with default handler for this case cascade. |
395 | 20.5k | state = |
396 | 20.5k | handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); |
397 | 20.5k | continue; |
398 | 20.5k | } |
399 | 24.7k | case CK_IntegralToBoolean: |
400 | 25.0k | case CK_IntegralToFloating: |
401 | 25.0k | case CK_FloatingToIntegral: |
402 | 25.1k | case CK_FloatingToBoolean: |
403 | 25.1k | case CK_FloatingCast: |
404 | 25.1k | case CK_FloatingRealToComplex: |
405 | 25.1k | case CK_FloatingComplexToReal: |
406 | 25.1k | case CK_FloatingComplexToBoolean: |
407 | 25.1k | case CK_FloatingComplexCast: |
408 | 25.1k | case CK_FloatingComplexToIntegralComplex: |
409 | 25.1k | case CK_IntegralRealToComplex: |
410 | 25.1k | case CK_IntegralComplexToReal: |
411 | 25.1k | case CK_IntegralComplexToBoolean: |
412 | 25.1k | case CK_IntegralComplexCast: |
413 | 25.1k | case CK_IntegralComplexToFloatingComplex: |
414 | 25.3k | case CK_CPointerToObjCPointerCast: |
415 | 25.3k | case CK_BlockPointerToObjCPointerCast: |
416 | 25.3k | case CK_AnyPointerToBlockPointerCast: |
417 | 25.3k | case CK_ObjCObjectLValueCast: |
418 | 25.3k | case CK_ZeroToOCLOpaqueType: |
419 | 25.3k | case CK_IntToOCLSampler: |
420 | 25.3k | case CK_LValueBitCast: |
421 | 25.3k | case CK_FloatingToFixedPoint: |
422 | 25.3k | case CK_FixedPointToFloating: |
423 | 25.3k | case CK_FixedPointCast: |
424 | 25.3k | case CK_FixedPointToBoolean: |
425 | 25.3k | case CK_FixedPointToIntegral: |
426 | 25.3k | case CK_IntegralToFixedPoint: { |
427 | 25.3k | state = |
428 | 25.3k | handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); |
429 | 25.3k | continue; |
430 | 25.3k | } |
431 | 32.9k | case CK_IntegralCast: { |
432 | | // Delegate to SValBuilder to process. |
433 | 32.9k | SVal V = state->getSVal(Ex, LCtx); |
434 | 32.9k | V = svalBuilder.evalIntegralCast(state, V, T, ExTy); |
435 | 32.9k | state = state->BindExpr(CastE, LCtx, V); |
436 | 32.9k | Bldr.generateNode(CastE, Pred, state); |
437 | 32.9k | continue; |
438 | 25.3k | } |
439 | 224 | case CK_DerivedToBase: |
440 | 834 | case CK_UncheckedDerivedToBase: { |
441 | | // For DerivedToBase cast, delegate to the store manager. |
442 | 834 | SVal val = state->getSVal(Ex, LCtx); |
443 | 834 | val = getStoreManager().evalDerivedToBase(val, CastE); |
444 | 834 | state = state->BindExpr(CastE, LCtx, val); |
445 | 834 | Bldr.generateNode(CastE, Pred, state); |
446 | 834 | continue; |
447 | 224 | } |
448 | | // Handle C++ dyn_cast. |
449 | 38 | case CK_Dynamic: { |
450 | 38 | SVal val = state->getSVal(Ex, LCtx); |
451 | | |
452 | | // Compute the type of the result. |
453 | 38 | QualType resultType = CastE->getType(); |
454 | 38 | if (CastE->isGLValue()) |
455 | 3 | resultType = getContext().getPointerType(resultType); |
456 | | |
457 | 38 | bool Failed = false; |
458 | | |
459 | | // Check if the value being cast evaluates to 0. |
460 | 38 | if (val.isZeroConstant()) |
461 | 2 | Failed = true; |
462 | | // Else, evaluate the cast. |
463 | 36 | else |
464 | 36 | val = getStoreManager().attemptDownCast(val, T, Failed); |
465 | | |
466 | 38 | if (Failed) { |
467 | 8 | if (T->isReferenceType()) { |
468 | | // A bad_cast exception is thrown if input value is a reference. |
469 | | // Currently, we model this, by generating a sink. |
470 | 1 | Bldr.generateSink(CastE, Pred, state); |
471 | 1 | continue; |
472 | 7 | } else { |
473 | | // If the cast fails on a pointer, bind to 0. |
474 | 7 | state = state->BindExpr(CastE, LCtx, svalBuilder.makeNull()); |
475 | 7 | } |
476 | 30 | } else { |
477 | | // If we don't know if the cast succeeded, conjure a new symbol. |
478 | 30 | if (val.isUnknown()) { |
479 | 0 | DefinedOrUnknownSVal NewSym = |
480 | 0 | svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType, |
481 | 0 | currBldrCtx->blockCount()); |
482 | 0 | state = state->BindExpr(CastE, LCtx, NewSym); |
483 | 0 | } else |
484 | | // Else, bind to the derived region value. |
485 | 30 | state = state->BindExpr(CastE, LCtx, val); |
486 | 30 | } |
487 | 37 | Bldr.generateNode(CastE, Pred, state); |
488 | 37 | continue; |
489 | 38 | } |
490 | 80 | case CK_BaseToDerived: { |
491 | 80 | SVal val = state->getSVal(Ex, LCtx); |
492 | 80 | QualType resultType = CastE->getType(); |
493 | 80 | if (CastE->isGLValue()) |
494 | 0 | resultType = getContext().getPointerType(resultType); |
495 | | |
496 | 80 | bool Failed = false; |
497 | | |
498 | 80 | if (!val.isConstant()) { |
499 | 72 | val = getStoreManager().attemptDownCast(val, T, Failed); |
500 | 72 | } |
501 | | |
502 | | // Failed to cast or the result is unknown, fall back to conservative. |
503 | 80 | if (Failed || val.isUnknown()76 ) { |
504 | 4 | val = |
505 | 4 | svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType, |
506 | 4 | currBldrCtx->blockCount()); |
507 | 4 | } |
508 | 80 | state = state->BindExpr(CastE, LCtx, val); |
509 | 80 | Bldr.generateNode(CastE, Pred, state); |
510 | 80 | continue; |
511 | 38 | } |
512 | 3.41k | case CK_NullToPointer: { |
513 | 3.41k | SVal V = svalBuilder.makeNull(); |
514 | 3.41k | state = state->BindExpr(CastE, LCtx, V); |
515 | 3.41k | Bldr.generateNode(CastE, Pred, state); |
516 | 3.41k | continue; |
517 | 38 | } |
518 | 5 | case CK_NullToMemberPointer: { |
519 | 5 | SVal V = svalBuilder.getMemberPointer(nullptr); |
520 | 5 | state = state->BindExpr(CastE, LCtx, V); |
521 | 5 | Bldr.generateNode(CastE, Pred, state); |
522 | 5 | continue; |
523 | 38 | } |
524 | 5 | case CK_DerivedToBaseMemberPointer: |
525 | 31 | case CK_BaseToDerivedMemberPointer: |
526 | 31 | case CK_ReinterpretMemberPointer: { |
527 | 31 | SVal V = state->getSVal(Ex, LCtx); |
528 | 31 | if (auto PTMSV = V.getAs<nonloc::PointerToMember>()) { |
529 | 31 | SVal CastedPTMSV = |
530 | 31 | svalBuilder.makePointerToMember(getBasicVals().accumCXXBase( |
531 | 31 | CastE->path(), *PTMSV, CastE->getCastKind())); |
532 | 31 | state = state->BindExpr(CastE, LCtx, CastedPTMSV); |
533 | 31 | Bldr.generateNode(CastE, Pred, state); |
534 | 31 | continue; |
535 | 31 | } |
536 | | // Explicitly proceed with default handler for this case cascade. |
537 | 0 | state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred); |
538 | 0 | continue; |
539 | 31 | } |
540 | | // Various C++ casts that are not handled yet. |
541 | 0 | case CK_ToUnion: |
542 | 0 | case CK_VectorSplat: { |
543 | 0 | state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred); |
544 | 0 | continue; |
545 | 0 | } |
546 | 0 | case CK_MatrixCast: { |
547 | | // TODO: Handle MatrixCast here. |
548 | 0 | continue; |
549 | 0 | } |
550 | 182k | } |
551 | 182k | } |
552 | 182k | } |
553 | | |
554 | | void ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, |
555 | | ExplodedNode *Pred, |
556 | 65 | ExplodedNodeSet &Dst) { |
557 | 65 | StmtNodeBuilder B(Pred, Dst, *currBldrCtx); |
558 | | |
559 | 65 | ProgramStateRef State = Pred->getState(); |
560 | 65 | const LocationContext *LCtx = Pred->getLocationContext(); |
561 | | |
562 | 65 | const Expr *Init = CL->getInitializer(); |
563 | 65 | SVal V = State->getSVal(CL->getInitializer(), LCtx); |
564 | | |
565 | 65 | if (isa<CXXConstructExpr>(Init) || isa<CXXStdInitializerListExpr>(Init)59 ) { |
566 | | // No work needed. Just pass the value up to this expression. |
567 | 55 | } else { |
568 | 55 | assert(isa<InitListExpr>(Init)); |
569 | 0 | Loc CLLoc = State->getLValue(CL, LCtx); |
570 | 55 | State = State->bindLoc(CLLoc, V, LCtx); |
571 | | |
572 | 55 | if (CL->isGLValue()) |
573 | 36 | V = CLLoc; |
574 | 55 | } |
575 | | |
576 | 0 | B.generateNode(CL, Pred, State->BindExpr(CL, LCtx, V)); |
577 | 65 | } |
578 | | |
579 | | void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, |
580 | 31.4k | ExplodedNodeSet &Dst) { |
581 | 31.4k | if (isa<TypedefNameDecl>(*DS->decl_begin())) { |
582 | | // C99 6.7.7 "Any array size expressions associated with variable length |
583 | | // array declarators are evaluated each time the declaration of the typedef |
584 | | // name is reached in the order of execution." |
585 | | // The checkers should know about typedef to be able to handle VLA size |
586 | | // expressions. |
587 | 5 | ExplodedNodeSet DstPre; |
588 | 5 | getCheckerManager().runCheckersForPreStmt(DstPre, Pred, DS, *this); |
589 | 5 | getCheckerManager().runCheckersForPostStmt(Dst, DstPre, DS, *this); |
590 | 5 | return; |
591 | 5 | } |
592 | | |
593 | | // Assumption: The CFG has one DeclStmt per Decl. |
594 | 31.4k | const VarDecl *VD = dyn_cast_or_null<VarDecl>(*DS->decl_begin()); |
595 | | |
596 | 31.4k | if (!VD) { |
597 | | //TODO:AZ: remove explicit insertion after refactoring is done. |
598 | 0 | Dst.insert(Pred); |
599 | 0 | return; |
600 | 0 | } |
601 | | |
602 | | // FIXME: all pre/post visits should eventually be handled by ::Visit(). |
603 | 31.4k | ExplodedNodeSet dstPreVisit; |
604 | 31.4k | getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this); |
605 | | |
606 | 31.4k | ExplodedNodeSet dstEvaluated; |
607 | 31.4k | StmtNodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx); |
608 | 31.4k | for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end(); |
609 | 62.8k | I!=E; ++I31.4k ) { |
610 | 31.4k | ExplodedNode *N = *I; |
611 | 31.4k | ProgramStateRef state = N->getState(); |
612 | 31.4k | const LocationContext *LC = N->getLocationContext(); |
613 | | |
614 | | // Decls without InitExpr are not initialized explicitly. |
615 | 31.4k | if (const Expr *InitEx = VD->getInit()) { |
616 | | |
617 | | // Note in the state that the initialization has occurred. |
618 | 28.5k | ExplodedNode *UpdatedN = N; |
619 | 28.5k | SVal InitVal = state->getSVal(InitEx, LC); |
620 | | |
621 | 28.5k | assert(DS->isSingleDecl()); |
622 | 28.5k | if (getObjectUnderConstruction(state, DS, LC)) { |
623 | 7.36k | state = finishObjectConstruction(state, DS, LC); |
624 | | // We constructed the object directly in the variable. |
625 | | // No need to bind anything. |
626 | 7.36k | B.generateNode(DS, UpdatedN, state); |
627 | 21.1k | } else { |
628 | | // Recover some path-sensitivity if a scalar value evaluated to |
629 | | // UnknownVal. |
630 | 21.1k | if (InitVal.isUnknown()) { |
631 | 5.17k | QualType Ty = InitEx->getType(); |
632 | 5.17k | if (InitEx->isGLValue()) { |
633 | 0 | Ty = getContext().getPointerType(Ty); |
634 | 0 | } |
635 | | |
636 | 5.17k | InitVal = svalBuilder.conjureSymbolVal(nullptr, InitEx, LC, Ty, |
637 | 5.17k | currBldrCtx->blockCount()); |
638 | 5.17k | } |
639 | | |
640 | | |
641 | 21.1k | B.takeNodes(UpdatedN); |
642 | 21.1k | ExplodedNodeSet Dst2; |
643 | 21.1k | evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, LC), InitVal, true); |
644 | 21.1k | B.addNodes(Dst2); |
645 | 21.1k | } |
646 | 28.5k | } |
647 | 2.92k | else { |
648 | 2.92k | B.generateNode(DS, N, state); |
649 | 2.92k | } |
650 | 31.4k | } |
651 | | |
652 | 31.4k | getCheckerManager().runCheckersForPostStmt(Dst, B.getResults(), DS, *this); |
653 | 31.4k | } |
654 | | |
655 | | void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, |
656 | 1.35k | ExplodedNodeSet &Dst) { |
657 | | // This method acts upon CFG elements for logical operators && and || |
658 | | // and attaches the value (true or false) to them as expressions. |
659 | | // It doesn't produce any state splits. |
660 | | // If we made it that far, we're past the point when we modeled the short |
661 | | // circuit. It means that we should have precise knowledge about whether |
662 | | // we've short-circuited. If we did, we already know the value we need to |
663 | | // bind. If we didn't, the value of the RHS (casted to the boolean type) |
664 | | // is the answer. |
665 | | // Currently this method tries to figure out whether we've short-circuited |
666 | | // by looking at the ExplodedGraph. This method is imperfect because there |
667 | | // could inevitably have been merges that would have resulted in multiple |
668 | | // potential path traversal histories. We bail out when we fail. |
669 | | // Due to this ambiguity, a more reliable solution would have been to |
670 | | // track the short circuit operation history path-sensitively until |
671 | | // we evaluate the respective logical operator. |
672 | 1.35k | assert(B->getOpcode() == BO_LAnd || |
673 | 1.35k | B->getOpcode() == BO_LOr); |
674 | | |
675 | 0 | StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); |
676 | 1.35k | ProgramStateRef state = Pred->getState(); |
677 | | |
678 | 1.35k | if (B->getType()->isVectorType()) { |
679 | | // FIXME: We do not model vector arithmetic yet. When adding support for |
680 | | // that, note that the CFG-based reasoning below does not apply, because |
681 | | // logical operators on vectors are not short-circuit. Currently they are |
682 | | // modeled as short-circuit in Clang CFG but this is incorrect. |
683 | | // Do not set the value for the expression. It'd be UnknownVal by default. |
684 | 2 | Bldr.generateNode(B, Pred, state); |
685 | 2 | return; |
686 | 2 | } |
687 | | |
688 | 1.35k | ExplodedNode *N = Pred; |
689 | 2.72k | while (!N->getLocation().getAs<BlockEntrance>()) { |
690 | 1.37k | ProgramPoint P = N->getLocation(); |
691 | 1.37k | assert(P.getAs<PreStmt>()|| P.getAs<PreStmtPurgeDeadSymbols>()); |
692 | 0 | (void) P; |
693 | 1.37k | if (N->pred_size() != 1) { |
694 | | // We failed to track back where we came from. |
695 | 0 | Bldr.generateNode(B, Pred, state); |
696 | 0 | return; |
697 | 0 | } |
698 | 1.37k | N = *N->pred_begin(); |
699 | 1.37k | } |
700 | | |
701 | 1.35k | if (N->pred_size() != 1) { |
702 | | // We failed to track back where we came from. |
703 | 6 | Bldr.generateNode(B, Pred, state); |
704 | 6 | return; |
705 | 6 | } |
706 | | |
707 | 1.34k | N = *N->pred_begin(); |
708 | 1.34k | BlockEdge BE = N->getLocation().castAs<BlockEdge>(); |
709 | 1.34k | SVal X; |
710 | | |
711 | | // Determine the value of the expression by introspecting how we |
712 | | // got this location in the CFG. This requires looking at the previous |
713 | | // block we were in and what kind of control-flow transfer was involved. |
714 | 1.34k | const CFGBlock *SrcBlock = BE.getSrc(); |
715 | | // The only terminator (if there is one) that makes sense is a logical op. |
716 | 1.34k | CFGTerminator T = SrcBlock->getTerminator(); |
717 | 1.34k | if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) { |
718 | 498 | (void) Term; |
719 | 498 | assert(Term->isLogicalOp()); |
720 | 0 | assert(SrcBlock->succ_size() == 2); |
721 | | // Did we take the true or false branch? |
722 | 498 | unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 193 : 0405 ; |
723 | 498 | X = svalBuilder.makeIntVal(constant, B->getType()); |
724 | 498 | } |
725 | 846 | else { |
726 | | // If there is no terminator, by construction the last statement |
727 | | // in SrcBlock is the value of the enclosing expression. |
728 | | // However, we still need to constrain that value to be 0 or 1. |
729 | 846 | assert(!SrcBlock->empty()); |
730 | 0 | CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>(); |
731 | 846 | const Expr *RHS = cast<Expr>(Elem.getStmt()); |
732 | 846 | SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext()); |
733 | | |
734 | 846 | if (RHSVal.isUndef()) { |
735 | 1 | X = RHSVal; |
736 | 845 | } else { |
737 | | // We evaluate "RHSVal != 0" expression which result in 0 if the value is |
738 | | // known to be false, 1 if the value is known to be true and a new symbol |
739 | | // when the assumption is unknown. |
740 | 845 | nonloc::ConcreteInt Zero(getBasicVals().getValue(0, B->getType())); |
741 | 845 | X = evalBinOp(N->getState(), BO_NE, |
742 | 845 | svalBuilder.evalCast(RHSVal, B->getType(), RHS->getType()), |
743 | 845 | Zero, B->getType()); |
744 | 845 | } |
745 | 846 | } |
746 | 0 | Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X)); |
747 | 1.34k | } |
748 | | |
749 | | void ExprEngine::VisitInitListExpr(const InitListExpr *IE, |
750 | | ExplodedNode *Pred, |
751 | 1.20k | ExplodedNodeSet &Dst) { |
752 | 1.20k | StmtNodeBuilder B(Pred, Dst, *currBldrCtx); |
753 | | |
754 | 1.20k | ProgramStateRef state = Pred->getState(); |
755 | 1.20k | const LocationContext *LCtx = Pred->getLocationContext(); |
756 | 1.20k | QualType T = getContext().getCanonicalType(IE->getType()); |
757 | 1.20k | unsigned NumInitElements = IE->getNumInits(); |
758 | | |
759 | 1.20k | if (!IE->isGLValue() && !IE->isTransparent()1.19k && |
760 | 1.20k | (1.17k T->isArrayType()1.17k || T->isRecordType()642 || T->isVectorType()68 || |
761 | 1.17k | T->isAnyComplexType()62 )) { |
762 | 1.12k | llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList(); |
763 | | |
764 | | // Handle base case where the initializer has no elements. |
765 | | // e.g: static int* myArray[] = {}; |
766 | 1.12k | if (NumInitElements == 0) { |
767 | 168 | SVal V = svalBuilder.makeCompoundVal(T, vals); |
768 | 168 | B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V)); |
769 | 168 | return; |
770 | 168 | } |
771 | | |
772 | 953 | for (InitListExpr::const_reverse_iterator it = IE->rbegin(), |
773 | 3.11k | ei = IE->rend(); it != ei; ++it2.16k ) { |
774 | 2.16k | SVal V = state->getSVal(cast<Expr>(*it), LCtx); |
775 | 2.16k | vals = getBasicVals().prependSVal(V, vals); |
776 | 2.16k | } |
777 | | |
778 | 953 | B.generateNode(IE, Pred, |
779 | 953 | state->BindExpr(IE, LCtx, |
780 | 953 | svalBuilder.makeCompoundVal(T, vals))); |
781 | 953 | return; |
782 | 1.12k | } |
783 | | |
784 | | // Handle scalars: int{5} and int{} and GLvalues. |
785 | | // Note, if the InitListExpr is a GLvalue, it means that there is an address |
786 | | // representing it, so it must have a single init element. |
787 | 86 | assert(NumInitElements <= 1); |
788 | | |
789 | 0 | SVal V; |
790 | 86 | if (NumInitElements == 0) |
791 | 57 | V = getSValBuilder().makeZeroVal(T); |
792 | 29 | else |
793 | 29 | V = state->getSVal(IE->getInit(0), LCtx); |
794 | | |
795 | 86 | B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V)); |
796 | 86 | } |
797 | | |
798 | | void ExprEngine::VisitGuardedExpr(const Expr *Ex, |
799 | | const Expr *L, |
800 | | const Expr *R, |
801 | | ExplodedNode *Pred, |
802 | 906 | ExplodedNodeSet &Dst) { |
803 | 906 | assert(L && R); |
804 | | |
805 | 0 | StmtNodeBuilder B(Pred, Dst, *currBldrCtx); |
806 | 906 | ProgramStateRef state = Pred->getState(); |
807 | 906 | const LocationContext *LCtx = Pred->getLocationContext(); |
808 | 906 | const CFGBlock *SrcBlock = nullptr; |
809 | | |
810 | | // Find the predecessor block. |
811 | 906 | ProgramStateRef SrcState = state; |
812 | 2.72k | for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()1.81k ) { |
813 | 2.72k | ProgramPoint PP = N->getLocation(); |
814 | 2.72k | if (PP.getAs<PreStmtPurgeDeadSymbols>() || PP.getAs<BlockEntrance>()1.81k ) { |
815 | | // If the state N has multiple predecessors P, it means that successors |
816 | | // of P are all equivalent. |
817 | | // In turn, that means that all nodes at P are equivalent in terms |
818 | | // of observable behavior at N, and we can follow any of them. |
819 | | // FIXME: a more robust solution which does not walk up the tree. |
820 | 1.81k | continue; |
821 | 1.81k | } |
822 | 906 | SrcBlock = PP.castAs<BlockEdge>().getSrc(); |
823 | 906 | SrcState = N->getState(); |
824 | 906 | break; |
825 | 2.72k | } |
826 | | |
827 | 906 | assert(SrcBlock && "missing function entry"); |
828 | | |
829 | | // Find the last expression in the predecessor block. That is the |
830 | | // expression that is used for the value of the ternary expression. |
831 | 0 | bool hasValue = false; |
832 | 906 | SVal V; |
833 | | |
834 | 906 | for (CFGElement CE : llvm::reverse(*SrcBlock)) { |
835 | 906 | if (Optional<CFGStmt> CS = CE.getAs<CFGStmt>()) { |
836 | 906 | const Expr *ValEx = cast<Expr>(CS->getStmt()); |
837 | 906 | ValEx = ValEx->IgnoreParens(); |
838 | | |
839 | | // For GNU extension '?:' operator, the left hand side will be an |
840 | | // OpaqueValueExpr, so get the underlying expression. |
841 | 906 | if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L)) |
842 | 21 | L = OpaqueEx->getSourceExpr(); |
843 | | |
844 | | // If the last expression in the predecessor block matches true or false |
845 | | // subexpression, get its the value. |
846 | 906 | if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()274 ) { |
847 | 904 | hasValue = true; |
848 | 904 | V = SrcState->getSVal(ValEx, LCtx); |
849 | 904 | } |
850 | 906 | break; |
851 | 906 | } |
852 | 906 | } |
853 | | |
854 | 906 | if (!hasValue) |
855 | 2 | V = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx, |
856 | 2 | currBldrCtx->blockCount()); |
857 | | |
858 | | // Generate a new node with the binding from the appropriate path. |
859 | 906 | B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true)); |
860 | 906 | } |
861 | | |
862 | | void ExprEngine:: |
863 | | VisitOffsetOfExpr(const OffsetOfExpr *OOE, |
864 | 21 | ExplodedNode *Pred, ExplodedNodeSet &Dst) { |
865 | 21 | StmtNodeBuilder B(Pred, Dst, *currBldrCtx); |
866 | 21 | Expr::EvalResult Result; |
867 | 21 | if (OOE->EvaluateAsInt(Result, getContext())) { |
868 | 21 | APSInt IV = Result.Val.getInt(); |
869 | 21 | assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType())); |
870 | 0 | assert(OOE->getType()->castAs<BuiltinType>()->isInteger()); |
871 | 0 | assert(IV.isSigned() == OOE->getType()->isSignedIntegerType()); |
872 | 0 | SVal X = svalBuilder.makeIntVal(IV); |
873 | 21 | B.generateNode(OOE, Pred, |
874 | 21 | Pred->getState()->BindExpr(OOE, Pred->getLocationContext(), |
875 | 21 | X)); |
876 | 21 | } |
877 | | // FIXME: Handle the case where __builtin_offsetof is not a constant. |
878 | 21 | } |
879 | | |
880 | | |
881 | | void ExprEngine:: |
882 | | VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, |
883 | | ExplodedNode *Pred, |
884 | 963 | ExplodedNodeSet &Dst) { |
885 | | // FIXME: Prechecks eventually go in ::Visit(). |
886 | 963 | ExplodedNodeSet CheckedSet; |
887 | 963 | getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this); |
888 | | |
889 | 963 | ExplodedNodeSet EvalSet; |
890 | 963 | StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx); |
891 | | |
892 | 963 | QualType T = Ex->getTypeOfArgument(); |
893 | | |
894 | 963 | for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); |
895 | 1.92k | I != E; ++I961 ) { |
896 | 961 | if (Ex->getKind() == UETT_SizeOf) { |
897 | 958 | if (!T->isIncompleteType() && !T->isConstantSizeType()954 ) { |
898 | 11 | assert(T->isVariableArrayType() && "Unknown non-constant-sized type."); |
899 | | |
900 | | // FIXME: Add support for VLA type arguments and VLA expressions. |
901 | | // When that happens, we should probably refactor VLASizeChecker's code. |
902 | 0 | continue; |
903 | 947 | } else if (T->getAs<ObjCObjectType>()) { |
904 | | // Some code tries to take the sizeof an ObjCObjectType, relying that |
905 | | // the compiler has laid out its representation. Just report Unknown |
906 | | // for these. |
907 | 0 | continue; |
908 | 0 | } |
909 | 958 | } |
910 | | |
911 | 950 | APSInt Value = Ex->EvaluateKnownConstInt(getContext()); |
912 | 950 | CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue()); |
913 | | |
914 | 950 | ProgramStateRef state = (*I)->getState(); |
915 | 950 | state = state->BindExpr(Ex, (*I)->getLocationContext(), |
916 | 950 | svalBuilder.makeIntVal(amt.getQuantity(), |
917 | 950 | Ex->getType())); |
918 | 950 | Bldr.generateNode(Ex, *I, state); |
919 | 950 | } |
920 | | |
921 | 963 | getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this); |
922 | 963 | } |
923 | | |
924 | | void ExprEngine::handleUOExtension(ExplodedNodeSet::iterator I, |
925 | | const UnaryOperator *U, |
926 | 17.0k | StmtNodeBuilder &Bldr) { |
927 | | // FIXME: We can probably just have some magic in Environment::getSVal() |
928 | | // that propagates values, instead of creating a new node here. |
929 | | // |
930 | | // Unary "+" is a no-op, similar to a parentheses. We still have places |
931 | | // where it may be a block-level expression, so we need to |
932 | | // generate an extra node that just propagates the value of the |
933 | | // subexpression. |
934 | 17.0k | const Expr *Ex = U->getSubExpr()->IgnoreParens(); |
935 | 17.0k | ProgramStateRef state = (*I)->getState(); |
936 | 17.0k | const LocationContext *LCtx = (*I)->getLocationContext(); |
937 | 17.0k | Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, |
938 | 17.0k | state->getSVal(Ex, LCtx))); |
939 | 17.0k | } |
940 | | |
941 | | void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred, |
942 | 28.4k | ExplodedNodeSet &Dst) { |
943 | | // FIXME: Prechecks eventually go in ::Visit(). |
944 | 28.4k | ExplodedNodeSet CheckedSet; |
945 | 28.4k | getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this); |
946 | | |
947 | 28.4k | ExplodedNodeSet EvalSet; |
948 | 28.4k | StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx); |
949 | | |
950 | 28.4k | for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); |
951 | 56.8k | I != E; ++I28.4k ) { |
952 | 28.4k | switch (U->getOpcode()) { |
953 | 7.82k | default: { |
954 | 7.82k | Bldr.takeNodes(*I); |
955 | 7.82k | ExplodedNodeSet Tmp; |
956 | 7.82k | VisitIncrementDecrementOperator(U, *I, Tmp); |
957 | 7.82k | Bldr.addNodes(Tmp); |
958 | 7.82k | break; |
959 | 0 | } |
960 | 14 | case UO_Real: { |
961 | 14 | const Expr *Ex = U->getSubExpr()->IgnoreParens(); |
962 | | |
963 | | // FIXME: We don't have complex SValues yet. |
964 | 14 | if (Ex->getType()->isAnyComplexType()) { |
965 | | // Just report "Unknown." |
966 | 10 | break; |
967 | 10 | } |
968 | | |
969 | | // For all other types, UO_Real is an identity operation. |
970 | 4 | assert (U->getType() == Ex->getType()); |
971 | 0 | ProgramStateRef state = (*I)->getState(); |
972 | 4 | const LocationContext *LCtx = (*I)->getLocationContext(); |
973 | 4 | Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, |
974 | 4 | state->getSVal(Ex, LCtx))); |
975 | 4 | break; |
976 | 14 | } |
977 | | |
978 | 11 | case UO_Imag: { |
979 | 11 | const Expr *Ex = U->getSubExpr()->IgnoreParens(); |
980 | | // FIXME: We don't have complex SValues yet. |
981 | 11 | if (Ex->getType()->isAnyComplexType()) { |
982 | | // Just report "Unknown." |
983 | 8 | break; |
984 | 8 | } |
985 | | // For all other types, UO_Imag returns 0. |
986 | 3 | ProgramStateRef state = (*I)->getState(); |
987 | 3 | const LocationContext *LCtx = (*I)->getLocationContext(); |
988 | 3 | SVal X = svalBuilder.makeZeroVal(Ex->getType()); |
989 | 3 | Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X)); |
990 | 3 | break; |
991 | 11 | } |
992 | | |
993 | 3.67k | case UO_AddrOf: { |
994 | | // Process pointer-to-member address operation. |
995 | 3.67k | const Expr *Ex = U->getSubExpr()->IgnoreParens(); |
996 | 3.67k | if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) { |
997 | 2.91k | const ValueDecl *VD = DRE->getDecl(); |
998 | | |
999 | 2.91k | if (isa<CXXMethodDecl>(VD) || isa<FieldDecl>(VD)2.89k || |
1000 | 2.91k | isa<IndirectFieldDecl>(VD)2.87k ) { |
1001 | 59 | ProgramStateRef State = (*I)->getState(); |
1002 | 59 | const LocationContext *LCtx = (*I)->getLocationContext(); |
1003 | 59 | SVal SV = svalBuilder.getMemberPointer(cast<NamedDecl>(VD)); |
1004 | 59 | Bldr.generateNode(U, *I, State->BindExpr(U, LCtx, SV)); |
1005 | 59 | break; |
1006 | 59 | } |
1007 | 2.91k | } |
1008 | | // Explicitly proceed with default handler for this case cascade. |
1009 | 3.61k | handleUOExtension(I, U, Bldr); |
1010 | 3.61k | break; |
1011 | 3.67k | } |
1012 | 4 | case UO_Plus: |
1013 | 4 | assert(!U->isGLValue()); |
1014 | 4 | LLVM_FALLTHROUGH; |
1015 | 13.4k | case UO_Deref: |
1016 | 13.4k | case UO_Extension: { |
1017 | 13.4k | handleUOExtension(I, U, Bldr); |
1018 | 13.4k | break; |
1019 | 13.4k | } |
1020 | | |
1021 | 1.11k | case UO_LNot: |
1022 | 2.43k | case UO_Minus: |
1023 | 3.43k | case UO_Not: { |
1024 | 3.43k | assert (!U->isGLValue()); |
1025 | 0 | const Expr *Ex = U->getSubExpr()->IgnoreParens(); |
1026 | 3.43k | ProgramStateRef state = (*I)->getState(); |
1027 | 3.43k | const LocationContext *LCtx = (*I)->getLocationContext(); |
1028 | | |
1029 | | // Get the value of the subexpression. |
1030 | 3.43k | SVal V = state->getSVal(Ex, LCtx); |
1031 | | |
1032 | 3.43k | if (V.isUnknownOrUndef()) { |
1033 | 10 | Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V)); |
1034 | 10 | break; |
1035 | 10 | } |
1036 | | |
1037 | 3.42k | switch (U->getOpcode()) { |
1038 | 0 | default: |
1039 | 0 | llvm_unreachable("Invalid Opcode."); |
1040 | 1.00k | case UO_Not: |
1041 | | // FIXME: Do we need to handle promotions? |
1042 | 1.00k | state = state->BindExpr(U, LCtx, evalComplement(V.castAs<NonLoc>())); |
1043 | 1.00k | break; |
1044 | 1.31k | case UO_Minus: |
1045 | | // FIXME: Do we need to handle promotions? |
1046 | 1.31k | state = state->BindExpr(U, LCtx, evalMinus(V.castAs<NonLoc>())); |
1047 | 1.31k | break; |
1048 | 1.11k | case UO_LNot: |
1049 | | // C99 6.5.3.3: "The expression !E is equivalent to (0==E)." |
1050 | | // |
1051 | | // Note: technically we do "E == 0", but this is the same in the |
1052 | | // transfer functions as "0 == E". |
1053 | 1.11k | SVal Result; |
1054 | 1.11k | if (Optional<Loc> LV = V.getAs<Loc>()) { |
1055 | 281 | Loc X = svalBuilder.makeNullWithType(Ex->getType()); |
1056 | 281 | Result = evalBinOp(state, BO_EQ, *LV, X, U->getType()); |
1057 | 831 | } else if (Ex->getType()->isFloatingType()) { |
1058 | | // FIXME: handle floating point types. |
1059 | 1 | Result = UnknownVal(); |
1060 | 830 | } else { |
1061 | 830 | nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType())); |
1062 | 830 | Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X, |
1063 | 830 | U->getType()); |
1064 | 830 | } |
1065 | | |
1066 | 1.11k | state = state->BindExpr(U, LCtx, Result); |
1067 | 1.11k | break; |
1068 | 3.42k | } |
1069 | 3.42k | Bldr.generateNode(U, *I, state); |
1070 | 3.42k | break; |
1071 | 3.42k | } |
1072 | 28.4k | } |
1073 | 28.4k | } |
1074 | | |
1075 | 28.4k | getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this); |
1076 | 28.4k | } |
1077 | | |
1078 | | void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U, |
1079 | | ExplodedNode *Pred, |
1080 | 7.82k | ExplodedNodeSet &Dst) { |
1081 | | // Handle ++ and -- (both pre- and post-increment). |
1082 | 7.82k | assert (U->isIncrementDecrementOp()); |
1083 | 0 | const Expr *Ex = U->getSubExpr()->IgnoreParens(); |
1084 | | |
1085 | 7.82k | const LocationContext *LCtx = Pred->getLocationContext(); |
1086 | 7.82k | ProgramStateRef state = Pred->getState(); |
1087 | 7.82k | SVal loc = state->getSVal(Ex, LCtx); |
1088 | | |
1089 | | // Perform a load. |
1090 | 7.82k | ExplodedNodeSet Tmp; |
1091 | 7.82k | evalLoad(Tmp, U, Ex, Pred, state, loc); |
1092 | | |
1093 | 7.82k | ExplodedNodeSet Dst2; |
1094 | 7.82k | StmtNodeBuilder Bldr(Tmp, Dst2, *currBldrCtx); |
1095 | 15.6k | for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end();I!=E;++I7.81k ) { |
1096 | | |
1097 | 7.81k | state = (*I)->getState(); |
1098 | 7.81k | assert(LCtx == (*I)->getLocationContext()); |
1099 | 0 | SVal V2_untested = state->getSVal(Ex, LCtx); |
1100 | | |
1101 | | // Propagate unknown and undefined values. |
1102 | 7.81k | if (V2_untested.isUnknownOrUndef()) { |
1103 | 292 | state = state->BindExpr(U, LCtx, V2_untested); |
1104 | | |
1105 | | // Perform the store, so that the uninitialized value detection happens. |
1106 | 292 | Bldr.takeNodes(*I); |
1107 | 292 | ExplodedNodeSet Dst3; |
1108 | 292 | evalStore(Dst3, U, Ex, *I, state, loc, V2_untested); |
1109 | 292 | Bldr.addNodes(Dst3); |
1110 | | |
1111 | 292 | continue; |
1112 | 292 | } |
1113 | 7.52k | DefinedSVal V2 = V2_untested.castAs<DefinedSVal>(); |
1114 | | |
1115 | | // Handle all other values. |
1116 | 7.52k | BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add7.12k : BO_Sub398 ; |
1117 | | |
1118 | | // If the UnaryOperator has non-location type, use its type to create the |
1119 | | // constant value. If the UnaryOperator has location type, create the |
1120 | | // constant with int type and pointer width. |
1121 | 7.52k | SVal RHS; |
1122 | 7.52k | SVal Result; |
1123 | | |
1124 | 7.52k | if (U->getType()->isAnyPointerType()) |
1125 | 833 | RHS = svalBuilder.makeArrayIndex(1); |
1126 | 6.69k | else if (U->getType()->isIntegralOrEnumerationType()) |
1127 | 6.69k | RHS = svalBuilder.makeIntVal(1, U->getType()); |
1128 | 1 | else |
1129 | 1 | RHS = UnknownVal(); |
1130 | | |
1131 | | // The use of an operand of type bool with the ++ operators is deprecated |
1132 | | // but valid until C++17. And if the operand of the ++ operator is of type |
1133 | | // bool, it is set to true until C++17. Note that for '_Bool', it is also |
1134 | | // set to true when it encounters ++ operator. |
1135 | 7.52k | if (U->getType()->isBooleanType() && U->isIncrementOp()70 ) |
1136 | 52 | Result = svalBuilder.makeTruthVal(true, U->getType()); |
1137 | 7.47k | else |
1138 | 7.47k | Result = evalBinOp(state, Op, V2, RHS, U->getType()); |
1139 | | |
1140 | | // Conjure a new symbol if necessary to recover precision. |
1141 | 7.52k | if (Result.isUnknown()){ |
1142 | 3 | DefinedOrUnknownSVal SymVal = |
1143 | 3 | svalBuilder.conjureSymbolVal(nullptr, U, LCtx, |
1144 | 3 | currBldrCtx->blockCount()); |
1145 | 3 | Result = SymVal; |
1146 | | |
1147 | | // If the value is a location, ++/-- should always preserve |
1148 | | // non-nullness. Check if the original value was non-null, and if so |
1149 | | // propagate that constraint. |
1150 | 3 | if (Loc::isLocType(U->getType())) { |
1151 | 0 | DefinedOrUnknownSVal Constraint = |
1152 | 0 | svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType())); |
1153 | |
|
1154 | 0 | if (!state->assume(Constraint, true)) { |
1155 | | // It isn't feasible for the original value to be null. |
1156 | | // Propagate this constraint. |
1157 | 0 | Constraint = svalBuilder.evalEQ(state, SymVal, |
1158 | 0 | svalBuilder.makeZeroVal(U->getType())); |
1159 | |
|
1160 | 0 | state = state->assume(Constraint, false); |
1161 | 0 | assert(state); |
1162 | 0 | } |
1163 | 0 | } |
1164 | 3 | } |
1165 | | |
1166 | | // Since the lvalue-to-rvalue conversion is explicit in the AST, |
1167 | | // we bind an l-value if the operator is prefix and an lvalue (in C++). |
1168 | 7.52k | if (U->isGLValue()) |
1169 | 1.32k | state = state->BindExpr(U, LCtx, loc); |
1170 | 6.20k | else |
1171 | 6.20k | state = state->BindExpr(U, LCtx, U->isPostfix() ? V25.67k : Result530 ); |
1172 | | |
1173 | | // Perform the store. |
1174 | 7.52k | Bldr.takeNodes(*I); |
1175 | 7.52k | ExplodedNodeSet Dst3; |
1176 | 7.52k | evalStore(Dst3, U, Ex, *I, state, loc, Result); |
1177 | 7.52k | Bldr.addNodes(Dst3); |
1178 | 7.52k | } |
1179 | 7.82k | Dst.insert(Dst2); |
1180 | 7.82k | } |