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