1 //=-- ExprEngineC.cpp - ExprEngine support for C 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 ExprEngine's support for C expressions.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
15 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
16
17 using namespace clang;
18 using namespace ento;
19 using llvm::APSInt;
20
VisitBinaryOperator(const BinaryOperator * B,ExplodedNode * Pred,ExplodedNodeSet & Dst)21 void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
22 ExplodedNode *Pred,
23 ExplodedNodeSet &Dst) {
24
25 Expr *LHS = B->getLHS()->IgnoreParens();
26 Expr *RHS = B->getRHS()->IgnoreParens();
27
28 // FIXME: Prechecks eventually go in ::Visit().
29 ExplodedNodeSet CheckedSet;
30 ExplodedNodeSet Tmp2;
31 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this);
32
33 // With both the LHS and RHS evaluated, process the operation itself.
34 for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end();
35 it != ei; ++it) {
36
37 ProgramStateRef state = (*it)->getState();
38 const LocationContext *LCtx = (*it)->getLocationContext();
39 SVal LeftV = state->getSVal(LHS, LCtx);
40 SVal RightV = state->getSVal(RHS, LCtx);
41
42 BinaryOperator::Opcode Op = B->getOpcode();
43
44 if (Op == BO_Assign) {
45 // EXPERIMENTAL: "Conjured" symbols.
46 // FIXME: Handle structs.
47 if (RightV.isUnknown()) {
48 unsigned Count = currentBuilderContext->getCurrentBlockCount();
49 RightV = svalBuilder.getConjuredSymbolVal(NULL, B->getRHS(), LCtx, Count);
50 }
51 // Simulate the effects of a "store": bind the value of the RHS
52 // to the L-Value represented by the LHS.
53 SVal ExprVal = B->isLValue() ? LeftV : RightV;
54 evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, LCtx, ExprVal),
55 LeftV, RightV);
56 continue;
57 }
58
59 if (!B->isAssignmentOp()) {
60 StmtNodeBuilder Bldr(*it, Tmp2, *currentBuilderContext);
61 // Process non-assignments except commas or short-circuited
62 // logical expressions (LAnd and LOr).
63 SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
64 if (Result.isUnknown()) {
65 Bldr.generateNode(B, *it, state);
66 continue;
67 }
68
69 state = state->BindExpr(B, LCtx, Result);
70 Bldr.generateNode(B, *it, state);
71 continue;
72 }
73
74 assert (B->isCompoundAssignmentOp());
75
76 switch (Op) {
77 default:
78 llvm_unreachable("Invalid opcode for compound assignment.");
79 case BO_MulAssign: Op = BO_Mul; break;
80 case BO_DivAssign: Op = BO_Div; break;
81 case BO_RemAssign: Op = BO_Rem; break;
82 case BO_AddAssign: Op = BO_Add; break;
83 case BO_SubAssign: Op = BO_Sub; break;
84 case BO_ShlAssign: Op = BO_Shl; break;
85 case BO_ShrAssign: Op = BO_Shr; break;
86 case BO_AndAssign: Op = BO_And; break;
87 case BO_XorAssign: Op = BO_Xor; break;
88 case BO_OrAssign: Op = BO_Or; break;
89 }
90
91 // Perform a load (the LHS). This performs the checks for
92 // null dereferences, and so on.
93 ExplodedNodeSet Tmp;
94 SVal location = LeftV;
95 evalLoad(Tmp, B, LHS, *it, state, location);
96
97 for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E;
98 ++I) {
99
100 state = (*I)->getState();
101 const LocationContext *LCtx = (*I)->getLocationContext();
102 SVal V = state->getSVal(LHS, LCtx);
103
104 // Get the computation type.
105 QualType CTy =
106 cast<CompoundAssignOperator>(B)->getComputationResultType();
107 CTy = getContext().getCanonicalType(CTy);
108
109 QualType CLHSTy =
110 cast<CompoundAssignOperator>(B)->getComputationLHSType();
111 CLHSTy = getContext().getCanonicalType(CLHSTy);
112
113 QualType LTy = getContext().getCanonicalType(LHS->getType());
114
115 // Promote LHS.
116 V = svalBuilder.evalCast(V, CLHSTy, LTy);
117
118 // Compute the result of the operation.
119 SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
120 B->getType(), CTy);
121
122 // EXPERIMENTAL: "Conjured" symbols.
123 // FIXME: Handle structs.
124
125 SVal LHSVal;
126
127 if (Result.isUnknown()) {
128
129 unsigned Count = currentBuilderContext->getCurrentBlockCount();
130
131 // The symbolic value is actually for the type of the left-hand side
132 // expression, not the computation type, as this is the value the
133 // LValue on the LHS will bind to.
134 LHSVal = svalBuilder.getConjuredSymbolVal(NULL, B->getRHS(), LCtx,
135 LTy, Count);
136
137 // However, we need to convert the symbol to the computation type.
138 Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
139 }
140 else {
141 // The left-hand side may bind to a different value then the
142 // computation type.
143 LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
144 }
145
146 // In C++, assignment and compound assignment operators return an
147 // lvalue.
148 if (B->isLValue())
149 state = state->BindExpr(B, LCtx, location);
150 else
151 state = state->BindExpr(B, LCtx, Result);
152
153 evalStore(Tmp2, B, LHS, *I, state, location, LHSVal);
154 }
155 }
156
157 // FIXME: postvisits eventually go in ::Visit()
158 getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this);
159 }
160
VisitBlockExpr(const BlockExpr * BE,ExplodedNode * Pred,ExplodedNodeSet & Dst)161 void ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
162 ExplodedNodeSet &Dst) {
163
164 CanQualType T = getContext().getCanonicalType(BE->getType());
165 SVal V = svalBuilder.getBlockPointer(BE->getBlockDecl(), T,
166 Pred->getLocationContext());
167
168 ExplodedNodeSet Tmp;
169 StmtNodeBuilder Bldr(Pred, Tmp, *currentBuilderContext);
170 Bldr.generateNode(BE, Pred,
171 Pred->getState()->BindExpr(BE, Pred->getLocationContext(),
172 V),
173 false, 0,
174 ProgramPoint::PostLValueKind);
175
176 // FIXME: Move all post/pre visits to ::Visit().
177 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
178 }
179
VisitCast(const CastExpr * CastE,const Expr * Ex,ExplodedNode * Pred,ExplodedNodeSet & Dst)180 void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
181 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
182
183 ExplodedNodeSet dstPreStmt;
184 getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this);
185
186 if (CastE->getCastKind() == CK_LValueToRValue) {
187 for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
188 I!=E; ++I) {
189 ExplodedNode *subExprNode = *I;
190 ProgramStateRef state = subExprNode->getState();
191 const LocationContext *LCtx = subExprNode->getLocationContext();
192 evalLoad(Dst, CastE, CastE, subExprNode, state, state->getSVal(Ex, LCtx));
193 }
194 return;
195 }
196
197 // All other casts.
198 QualType T = CastE->getType();
199 QualType ExTy = Ex->getType();
200
201 if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
202 T = ExCast->getTypeAsWritten();
203
204 StmtNodeBuilder Bldr(dstPreStmt, Dst, *currentBuilderContext);
205 for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
206 I != E; ++I) {
207
208 Pred = *I;
209
210 switch (CastE->getCastKind()) {
211 case CK_LValueToRValue:
212 llvm_unreachable("LValueToRValue casts handled earlier.");
213 case CK_ToVoid:
214 continue;
215 // The analyzer doesn't do anything special with these casts,
216 // since it understands retain/release semantics already.
217 case CK_ARCProduceObject:
218 case CK_ARCConsumeObject:
219 case CK_ARCReclaimReturnedObject:
220 case CK_ARCExtendBlockObject: // Fall-through.
221 case CK_CopyAndAutoreleaseBlockObject:
222 // The analyser can ignore atomic casts for now, although some future
223 // checkers may want to make certain that you're not modifying the same
224 // value through atomic and nonatomic pointers.
225 case CK_AtomicToNonAtomic:
226 case CK_NonAtomicToAtomic:
227 // True no-ops.
228 case CK_NoOp:
229 case CK_FunctionToPointerDecay: {
230 // Copy the SVal of Ex to CastE.
231 ProgramStateRef state = Pred->getState();
232 const LocationContext *LCtx = Pred->getLocationContext();
233 SVal V = state->getSVal(Ex, LCtx);
234 state = state->BindExpr(CastE, LCtx, V);
235 Bldr.generateNode(CastE, Pred, state);
236 continue;
237 }
238 case CK_Dependent:
239 case CK_ArrayToPointerDecay:
240 case CK_BitCast:
241 case CK_LValueBitCast:
242 case CK_IntegralCast:
243 case CK_NullToPointer:
244 case CK_IntegralToPointer:
245 case CK_PointerToIntegral:
246 case CK_PointerToBoolean:
247 case CK_IntegralToBoolean:
248 case CK_IntegralToFloating:
249 case CK_FloatingToIntegral:
250 case CK_FloatingToBoolean:
251 case CK_FloatingCast:
252 case CK_FloatingRealToComplex:
253 case CK_FloatingComplexToReal:
254 case CK_FloatingComplexToBoolean:
255 case CK_FloatingComplexCast:
256 case CK_FloatingComplexToIntegralComplex:
257 case CK_IntegralRealToComplex:
258 case CK_IntegralComplexToReal:
259 case CK_IntegralComplexToBoolean:
260 case CK_IntegralComplexCast:
261 case CK_IntegralComplexToFloatingComplex:
262 case CK_CPointerToObjCPointerCast:
263 case CK_BlockPointerToObjCPointerCast:
264 case CK_AnyPointerToBlockPointerCast:
265 case CK_ObjCObjectLValueCast: {
266 // Delegate to SValBuilder to process.
267 ProgramStateRef state = Pred->getState();
268 const LocationContext *LCtx = Pred->getLocationContext();
269 SVal V = state->getSVal(Ex, LCtx);
270 V = svalBuilder.evalCast(V, T, ExTy);
271 state = state->BindExpr(CastE, LCtx, V);
272 Bldr.generateNode(CastE, Pred, state);
273 continue;
274 }
275 case CK_DerivedToBase:
276 case CK_UncheckedDerivedToBase: {
277 // For DerivedToBase cast, delegate to the store manager.
278 ProgramStateRef state = Pred->getState();
279 const LocationContext *LCtx = Pred->getLocationContext();
280 SVal val = state->getSVal(Ex, LCtx);
281 val = getStoreManager().evalDerivedToBase(val, T);
282 state = state->BindExpr(CastE, LCtx, val);
283 Bldr.generateNode(CastE, Pred, state);
284 continue;
285 }
286 // Handle C++ dyn_cast.
287 case CK_Dynamic: {
288 ProgramStateRef state = Pred->getState();
289 const LocationContext *LCtx = Pred->getLocationContext();
290 SVal val = state->getSVal(Ex, LCtx);
291
292 // Compute the type of the result.
293 QualType resultType = CastE->getType();
294 if (CastE->isLValue())
295 resultType = getContext().getPointerType(resultType);
296
297 bool Failed = false;
298
299 // Check if the value being cast evaluates to 0.
300 if (val.isZeroConstant())
301 Failed = true;
302 // Else, evaluate the cast.
303 else
304 val = getStoreManager().evalDynamicCast(val, T, Failed);
305
306 if (Failed) {
307 if (T->isReferenceType()) {
308 // A bad_cast exception is thrown if input value is a reference.
309 // Currently, we model this, by generating a sink.
310 Bldr.generateNode(CastE, Pred, state, true);
311 continue;
312 } else {
313 // If the cast fails on a pointer, bind to 0.
314 state = state->BindExpr(CastE, LCtx, svalBuilder.makeNull());
315 }
316 } else {
317 // If we don't know if the cast succeeded, conjure a new symbol.
318 if (val.isUnknown()) {
319 DefinedOrUnknownSVal NewSym = svalBuilder.getConjuredSymbolVal(NULL,
320 CastE, LCtx, resultType,
321 currentBuilderContext->getCurrentBlockCount());
322 state = state->BindExpr(CastE, LCtx, NewSym);
323 } else
324 // Else, bind to the derived region value.
325 state = state->BindExpr(CastE, LCtx, val);
326 }
327 Bldr.generateNode(CastE, Pred, state);
328 continue;
329 }
330 // Various C++ casts that are not handled yet.
331 case CK_ToUnion:
332 case CK_BaseToDerived:
333 case CK_NullToMemberPointer:
334 case CK_BaseToDerivedMemberPointer:
335 case CK_DerivedToBaseMemberPointer:
336 case CK_ReinterpretMemberPointer:
337 case CK_UserDefinedConversion:
338 case CK_ConstructorConversion:
339 case CK_VectorSplat:
340 case CK_MemberPointerToBoolean: {
341 // Recover some path-sensitivty by conjuring a new value.
342 QualType resultType = CastE->getType();
343 if (CastE->isLValue())
344 resultType = getContext().getPointerType(resultType);
345 const LocationContext *LCtx = Pred->getLocationContext();
346 SVal result = svalBuilder.getConjuredSymbolVal(NULL, CastE, LCtx,
347 resultType, currentBuilderContext->getCurrentBlockCount());
348 ProgramStateRef state = Pred->getState()->BindExpr(CastE, LCtx,
349 result);
350 Bldr.generateNode(CastE, Pred, state);
351 continue;
352 }
353 }
354 }
355 }
356
VisitCompoundLiteralExpr(const CompoundLiteralExpr * CL,ExplodedNode * Pred,ExplodedNodeSet & Dst)357 void ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
358 ExplodedNode *Pred,
359 ExplodedNodeSet &Dst) {
360 StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
361
362 const InitListExpr *ILE
363 = cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
364
365 ProgramStateRef state = Pred->getState();
366 SVal ILV = state->getSVal(ILE, Pred->getLocationContext());
367 const LocationContext *LC = Pred->getLocationContext();
368 state = state->bindCompoundLiteral(CL, LC, ILV);
369
370 if (CL->isLValue())
371 B.generateNode(CL, Pred, state->BindExpr(CL, LC, state->getLValue(CL, LC)));
372 else
373 B.generateNode(CL, Pred, state->BindExpr(CL, LC, ILV));
374 }
375
VisitDeclStmt(const DeclStmt * DS,ExplodedNode * Pred,ExplodedNodeSet & Dst)376 void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
377 ExplodedNodeSet &Dst) {
378
379 // FIXME: static variables may have an initializer, but the second
380 // time a function is called those values may not be current.
381 // This may need to be reflected in the CFG.
382
383 // Assumption: The CFG has one DeclStmt per Decl.
384 const Decl *D = *DS->decl_begin();
385
386 if (!D || !isa<VarDecl>(D)) {
387 //TODO:AZ: remove explicit insertion after refactoring is done.
388 Dst.insert(Pred);
389 return;
390 }
391
392 // FIXME: all pre/post visits should eventually be handled by ::Visit().
393 ExplodedNodeSet dstPreVisit;
394 getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
395
396 StmtNodeBuilder B(dstPreVisit, Dst, *currentBuilderContext);
397 const VarDecl *VD = dyn_cast<VarDecl>(D);
398 for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
399 I!=E; ++I) {
400 ExplodedNode *N = *I;
401 ProgramStateRef state = N->getState();
402
403 // Decls without InitExpr are not initialized explicitly.
404 const LocationContext *LC = N->getLocationContext();
405
406 if (const Expr *InitEx = VD->getInit()) {
407 SVal InitVal = state->getSVal(InitEx, Pred->getLocationContext());
408
409 // We bound the temp obj region to the CXXConstructExpr. Now recover
410 // the lazy compound value when the variable is not a reference.
411 if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() &&
412 !VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){
413 InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion());
414 assert(isa<nonloc::LazyCompoundVal>(InitVal));
415 }
416
417 // Recover some path-sensitivity if a scalar value evaluated to
418 // UnknownVal.
419 if (InitVal.isUnknown()) {
420 QualType Ty = InitEx->getType();
421 if (InitEx->isLValue()) {
422 Ty = getContext().getPointerType(Ty);
423 }
424
425 InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx, LC, Ty,
426 currentBuilderContext->getCurrentBlockCount());
427 }
428 B.takeNodes(N);
429 ExplodedNodeSet Dst2;
430 evalBind(Dst2, DS, N, state->getLValue(VD, LC), InitVal, true);
431 B.addNodes(Dst2);
432 }
433 else {
434 B.generateNode(DS, N,state->bindDeclWithNoInit(state->getRegion(VD, LC)));
435 }
436 }
437 }
438
VisitLogicalExpr(const BinaryOperator * B,ExplodedNode * Pred,ExplodedNodeSet & Dst)439 void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
440 ExplodedNodeSet &Dst) {
441 assert(B->getOpcode() == BO_LAnd ||
442 B->getOpcode() == BO_LOr);
443
444 StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
445 ProgramStateRef state = Pred->getState();
446 const LocationContext *LCtx = Pred->getLocationContext();
447 SVal X = state->getSVal(B, LCtx);
448 assert(X.isUndef());
449
450 const Expr *Ex = (const Expr*) cast<UndefinedVal>(X).getData();
451 assert(Ex);
452
453 if (Ex == B->getRHS()) {
454 X = state->getSVal(Ex, LCtx);
455
456 // Handle undefined values.
457 if (X.isUndef()) {
458 Bldr.generateNode(B, Pred, state->BindExpr(B, LCtx, X));
459 return;
460 }
461
462 DefinedOrUnknownSVal XD = cast<DefinedOrUnknownSVal>(X);
463
464 // We took the RHS. Because the value of the '&&' or '||' expression must
465 // evaluate to 0 or 1, we must assume the value of the RHS evaluates to 0
466 // or 1. Alternatively, we could take a lazy approach, and calculate this
467 // value later when necessary. We don't have the machinery in place for
468 // this right now, and since most logical expressions are used for branches,
469 // the payoff is not likely to be large. Instead, we do eager evaluation.
470 if (ProgramStateRef newState = state->assume(XD, true))
471 Bldr.generateNode(B, Pred,
472 newState->BindExpr(B, LCtx,
473 svalBuilder.makeIntVal(1U, B->getType())));
474
475 if (ProgramStateRef newState = state->assume(XD, false))
476 Bldr.generateNode(B, Pred,
477 newState->BindExpr(B, LCtx,
478 svalBuilder.makeIntVal(0U, B->getType())));
479 }
480 else {
481 // We took the LHS expression. Depending on whether we are '&&' or
482 // '||' we know what the value of the expression is via properties of
483 // the short-circuiting.
484 X = svalBuilder.makeIntVal(B->getOpcode() == BO_LAnd ? 0U : 1U,
485 B->getType());
486 Bldr.generateNode(B, Pred, state->BindExpr(B, LCtx, X));
487 }
488 }
489
VisitInitListExpr(const InitListExpr * IE,ExplodedNode * Pred,ExplodedNodeSet & Dst)490 void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
491 ExplodedNode *Pred,
492 ExplodedNodeSet &Dst) {
493 StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
494
495 ProgramStateRef state = Pred->getState();
496 const LocationContext *LCtx = Pred->getLocationContext();
497 QualType T = getContext().getCanonicalType(IE->getType());
498 unsigned NumInitElements = IE->getNumInits();
499
500 if (T->isArrayType() || T->isRecordType() || T->isVectorType()) {
501 llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
502
503 // Handle base case where the initializer has no elements.
504 // e.g: static int* myArray[] = {};
505 if (NumInitElements == 0) {
506 SVal V = svalBuilder.makeCompoundVal(T, vals);
507 B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
508 return;
509 }
510
511 for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
512 ei = IE->rend(); it != ei; ++it) {
513 vals = getBasicVals().consVals(state->getSVal(cast<Expr>(*it), LCtx),
514 vals);
515 }
516
517 B.generateNode(IE, Pred,
518 state->BindExpr(IE, LCtx,
519 svalBuilder.makeCompoundVal(T, vals)));
520 return;
521 }
522
523 if (Loc::isLocType(T) || T->isIntegerType()) {
524 assert(IE->getNumInits() == 1);
525 const Expr *initEx = IE->getInit(0);
526 B.generateNode(IE, Pred, state->BindExpr(IE, LCtx,
527 state->getSVal(initEx, LCtx)));
528 return;
529 }
530
531 llvm_unreachable("unprocessed InitListExpr type");
532 }
533
VisitGuardedExpr(const Expr * Ex,const Expr * L,const Expr * R,ExplodedNode * Pred,ExplodedNodeSet & Dst)534 void ExprEngine::VisitGuardedExpr(const Expr *Ex,
535 const Expr *L,
536 const Expr *R,
537 ExplodedNode *Pred,
538 ExplodedNodeSet &Dst) {
539 StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
540
541 ProgramStateRef state = Pred->getState();
542 const LocationContext *LCtx = Pred->getLocationContext();
543 SVal X = state->getSVal(Ex, LCtx);
544 assert (X.isUndef());
545 const Expr *SE = (Expr*) cast<UndefinedVal>(X).getData();
546 assert(SE);
547 X = state->getSVal(SE, LCtx);
548
549 // Make sure that we invalidate the previous binding.
550 B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, X, true));
551 }
552
553 void ExprEngine::
VisitOffsetOfExpr(const OffsetOfExpr * OOE,ExplodedNode * Pred,ExplodedNodeSet & Dst)554 VisitOffsetOfExpr(const OffsetOfExpr *OOE,
555 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
556 StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
557 APSInt IV;
558 if (OOE->EvaluateAsInt(IV, getContext())) {
559 assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
560 assert(OOE->getType()->isIntegerType());
561 assert(IV.isSigned() == OOE->getType()->isSignedIntegerOrEnumerationType());
562 SVal X = svalBuilder.makeIntVal(IV);
563 B.generateNode(OOE, Pred,
564 Pred->getState()->BindExpr(OOE, Pred->getLocationContext(),
565 X));
566 }
567 // FIXME: Handle the case where __builtin_offsetof is not a constant.
568 }
569
570
571 void ExprEngine::
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * Ex,ExplodedNode * Pred,ExplodedNodeSet & Dst)572 VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
573 ExplodedNode *Pred,
574 ExplodedNodeSet &Dst) {
575 StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
576
577 QualType T = Ex->getTypeOfArgument();
578
579 if (Ex->getKind() == UETT_SizeOf) {
580 if (!T->isIncompleteType() && !T->isConstantSizeType()) {
581 assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
582
583 // FIXME: Add support for VLA type arguments and VLA expressions.
584 // When that happens, we should probably refactor VLASizeChecker's code.
585 return;
586 }
587 else if (T->getAs<ObjCObjectType>()) {
588 // Some code tries to take the sizeof an ObjCObjectType, relying that
589 // the compiler has laid out its representation. Just report Unknown
590 // for these.
591 return;
592 }
593 }
594
595 APSInt Value = Ex->EvaluateKnownConstInt(getContext());
596 CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
597
598 ProgramStateRef state = Pred->getState();
599 state = state->BindExpr(Ex, Pred->getLocationContext(),
600 svalBuilder.makeIntVal(amt.getQuantity(),
601 Ex->getType()));
602 Bldr.generateNode(Ex, Pred, state);
603 }
604
VisitUnaryOperator(const UnaryOperator * U,ExplodedNode * Pred,ExplodedNodeSet & Dst)605 void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
606 ExplodedNode *Pred,
607 ExplodedNodeSet &Dst) {
608 StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
609 switch (U->getOpcode()) {
610 default: {
611 Bldr.takeNodes(Pred);
612 ExplodedNodeSet Tmp;
613 VisitIncrementDecrementOperator(U, Pred, Tmp);
614 Bldr.addNodes(Tmp);
615 }
616 break;
617 case UO_Real: {
618 const Expr *Ex = U->getSubExpr()->IgnoreParens();
619
620 // FIXME: We don't have complex SValues yet.
621 if (Ex->getType()->isAnyComplexType()) {
622 // Just report "Unknown."
623 break;
624 }
625
626 // For all other types, UO_Real is an identity operation.
627 assert (U->getType() == Ex->getType());
628 ProgramStateRef state = Pred->getState();
629 const LocationContext *LCtx = Pred->getLocationContext();
630 Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx,
631 state->getSVal(Ex, LCtx)));
632 break;
633 }
634
635 case UO_Imag: {
636 const Expr *Ex = U->getSubExpr()->IgnoreParens();
637 // FIXME: We don't have complex SValues yet.
638 if (Ex->getType()->isAnyComplexType()) {
639 // Just report "Unknown."
640 break;
641 }
642 // For all other types, UO_Imag returns 0.
643 ProgramStateRef state = Pred->getState();
644 const LocationContext *LCtx = Pred->getLocationContext();
645 SVal X = svalBuilder.makeZeroVal(Ex->getType());
646 Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx, X));
647 break;
648 }
649
650 case UO_Plus:
651 assert(!U->isLValue());
652 // FALL-THROUGH.
653 case UO_Deref:
654 case UO_AddrOf:
655 case UO_Extension: {
656 // FIXME: We can probably just have some magic in Environment::getSVal()
657 // that propagates values, instead of creating a new node here.
658 //
659 // Unary "+" is a no-op, similar to a parentheses. We still have places
660 // where it may be a block-level expression, so we need to
661 // generate an extra node that just propagates the value of the
662 // subexpression.
663 const Expr *Ex = U->getSubExpr()->IgnoreParens();
664 ProgramStateRef state = Pred->getState();
665 const LocationContext *LCtx = Pred->getLocationContext();
666 Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx,
667 state->getSVal(Ex, LCtx)));
668 break;
669 }
670
671 case UO_LNot:
672 case UO_Minus:
673 case UO_Not: {
674 assert (!U->isLValue());
675 const Expr *Ex = U->getSubExpr()->IgnoreParens();
676 ProgramStateRef state = Pred->getState();
677 const LocationContext *LCtx = Pred->getLocationContext();
678
679 // Get the value of the subexpression.
680 SVal V = state->getSVal(Ex, LCtx);
681
682 if (V.isUnknownOrUndef()) {
683 Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx, V));
684 break;
685 }
686
687 switch (U->getOpcode()) {
688 default:
689 llvm_unreachable("Invalid Opcode.");
690 case UO_Not:
691 // FIXME: Do we need to handle promotions?
692 state = state->BindExpr(U, LCtx, evalComplement(cast<NonLoc>(V)));
693 break;
694 case UO_Minus:
695 // FIXME: Do we need to handle promotions?
696 state = state->BindExpr(U, LCtx, evalMinus(cast<NonLoc>(V)));
697 break;
698 case UO_LNot:
699 // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
700 //
701 // Note: technically we do "E == 0", but this is the same in the
702 // transfer functions as "0 == E".
703 SVal Result;
704 if (isa<Loc>(V)) {
705 Loc X = svalBuilder.makeNull();
706 Result = evalBinOp(state, BO_EQ, cast<Loc>(V), X,
707 U->getType());
708 }
709 else {
710 nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
711 Result = evalBinOp(state, BO_EQ, cast<NonLoc>(V), X,
712 U->getType());
713 }
714
715 state = state->BindExpr(U, LCtx, Result);
716 break;
717 }
718 Bldr.generateNode(U, Pred, state);
719 break;
720 }
721 }
722
723 }
724
VisitIncrementDecrementOperator(const UnaryOperator * U,ExplodedNode * Pred,ExplodedNodeSet & Dst)725 void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
726 ExplodedNode *Pred,
727 ExplodedNodeSet &Dst) {
728 // Handle ++ and -- (both pre- and post-increment).
729 assert (U->isIncrementDecrementOp());
730 const Expr *Ex = U->getSubExpr()->IgnoreParens();
731
732 const LocationContext *LCtx = Pred->getLocationContext();
733 ProgramStateRef state = Pred->getState();
734 SVal loc = state->getSVal(Ex, LCtx);
735
736 // Perform a load.
737 ExplodedNodeSet Tmp;
738 evalLoad(Tmp, U, Ex, Pred, state, loc);
739
740 ExplodedNodeSet Dst2;
741 StmtNodeBuilder Bldr(Tmp, Dst2, *currentBuilderContext);
742 for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end();I!=E;++I) {
743
744 state = (*I)->getState();
745 assert(LCtx == (*I)->getLocationContext());
746 SVal V2_untested = state->getSVal(Ex, LCtx);
747
748 // Propagate unknown and undefined values.
749 if (V2_untested.isUnknownOrUndef()) {
750 Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V2_untested));
751 continue;
752 }
753 DefinedSVal V2 = cast<DefinedSVal>(V2_untested);
754
755 // Handle all other values.
756 BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
757
758 // If the UnaryOperator has non-location type, use its type to create the
759 // constant value. If the UnaryOperator has location type, create the
760 // constant with int type and pointer width.
761 SVal RHS;
762
763 if (U->getType()->isAnyPointerType())
764 RHS = svalBuilder.makeArrayIndex(1);
765 else
766 RHS = svalBuilder.makeIntVal(1, U->getType());
767
768 SVal Result = evalBinOp(state, Op, V2, RHS, U->getType());
769
770 // Conjure a new symbol if necessary to recover precision.
771 if (Result.isUnknown()){
772 DefinedOrUnknownSVal SymVal =
773 svalBuilder.getConjuredSymbolVal(NULL, Ex, LCtx,
774 currentBuilderContext->getCurrentBlockCount());
775 Result = SymVal;
776
777 // If the value is a location, ++/-- should always preserve
778 // non-nullness. Check if the original value was non-null, and if so
779 // propagate that constraint.
780 if (Loc::isLocType(U->getType())) {
781 DefinedOrUnknownSVal Constraint =
782 svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
783
784 if (!state->assume(Constraint, true)) {
785 // It isn't feasible for the original value to be null.
786 // Propagate this constraint.
787 Constraint = svalBuilder.evalEQ(state, SymVal,
788 svalBuilder.makeZeroVal(U->getType()));
789
790
791 state = state->assume(Constraint, false);
792 assert(state);
793 }
794 }
795 }
796
797 // Since the lvalue-to-rvalue conversion is explicit in the AST,
798 // we bind an l-value if the operator is prefix and an lvalue (in C++).
799 if (U->isLValue())
800 state = state->BindExpr(U, LCtx, loc);
801 else
802 state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);
803
804 // Perform the store.
805 Bldr.takeNodes(*I);
806 ExplodedNodeSet Dst3;
807 evalStore(Dst3, U, U, *I, state, loc, Result);
808 Bldr.addNodes(Dst3);
809 }
810 Dst.insert(Dst2);
811 }
812