ExprEngineC.cpp revision 540dda6f2e4982b3eab0300c804345f5b6104c11
1294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek//=-- ExprEngineC.cpp - ExprEngine support for C expressions ----*- C++ -*-===// 2294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// 3294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// The LLVM Compiler Infrastructure 4294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// 5294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// This file is distributed under the University of Illinois Open Source 6294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// License. See LICENSE.TXT for details. 7294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// 8294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek//===----------------------------------------------------------------------===// 9294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// 10294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// This file defines ExprEngine's support for C expressions. 11294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// 12294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek//===----------------------------------------------------------------------===// 13294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 14294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek#include "clang/StaticAnalyzer/Core/CheckerManager.h" 15294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 16294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek#include "clang/Analysis/Support/SaveAndRestore.h" 17294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 18294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekusing namespace clang; 19294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekusing namespace ento; 20294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekusing llvm::APSInt; 21294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 22294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitBinaryOperator(const BinaryOperator* B, 23294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 24294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 25d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 26294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Expr *LHS = B->getLHS()->IgnoreParens(); 27294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Expr *RHS = B->getRHS()->IgnoreParens(); 28294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 29d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // FIXME: Prechecks eventually go in ::Visit(). 30d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek ExplodedNodeSet CheckedSet; 31d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek ExplodedNodeSet Tmp2; 32d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this); 33294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 34d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // With both the LHS and RHS evaluated, process the operation itself. 35d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end(); 36d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek it != ei; ++it) { 37d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 38d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek const ProgramState *state = (*it)->getState(); 39d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek SVal LeftV = state->getSVal(LHS); 40d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek SVal RightV = state->getSVal(RHS); 41d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 42d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek BinaryOperator::Opcode Op = B->getOpcode(); 43d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 44d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek if (Op == BO_Assign) { 45d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // EXPERIMENTAL: "Conjured" symbols. 46d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // FIXME: Handle structs. 47d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek if (RightV.isUnknown() || 48d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek !getConstraintManager().canReasonAbout(RightV)) { 49d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek unsigned Count = Builder->getCurrentBlockCount(); 50d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek RightV = svalBuilder.getConjuredSymbolVal(NULL, B->getRHS(), Count); 51294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 52d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // Simulate the effects of a "store": bind the value of the RHS 53d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // to the L-Value represented by the LHS. 54d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek SVal ExprVal = B->isLValue() ? LeftV : RightV; 55d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, ExprVal), LeftV, RightV); 56d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek continue; 57d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek } 58294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 59d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek if (!B->isAssignmentOp()) { 60d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // Process non-assignments except commas or short-circuited 61d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // logical expressions (LAnd and LOr). 62d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType()); 63d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek if (Result.isUnknown()) { 64d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek MakeNode(Tmp2, B, *it, state); 65294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 66d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek } 67d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 68d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek state = state->BindExpr(B, Result); 69d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek MakeNode(Tmp2, B, *it, state); 70d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek continue; 71d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek } 72294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 73d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek assert (B->isCompoundAssignmentOp()); 74d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 75d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek switch (Op) { 76d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek default: 77d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek assert(0 && "Invalid opcode for compound assignment."); 78d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_MulAssign: Op = BO_Mul; break; 79d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_DivAssign: Op = BO_Div; break; 80d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_RemAssign: Op = BO_Rem; break; 81d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_AddAssign: Op = BO_Add; break; 82d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_SubAssign: Op = BO_Sub; break; 83d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_ShlAssign: Op = BO_Shl; break; 84d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_ShrAssign: Op = BO_Shr; break; 85d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_AndAssign: Op = BO_And; break; 86d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_XorAssign: Op = BO_Xor; break; 87d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_OrAssign: Op = BO_Or; break; 88d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek } 89294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 90d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // Perform a load (the LHS). This performs the checks for 91d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // null dereferences, and so on. 92d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek ExplodedNodeSet Tmp; 93d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek SVal location = LeftV; 94d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek evalLoad(Tmp, LHS, *it, state, location); 95d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 96d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; 97d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek ++I) { 98d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 99d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek state = (*I)->getState(); 100d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek SVal V = state->getSVal(LHS); 101294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 102d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // Get the computation type. 103d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek QualType CTy = 104294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek cast<CompoundAssignOperator>(B)->getComputationResultType(); 105d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek CTy = getContext().getCanonicalType(CTy); 106d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 107d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek QualType CLHSTy = 108294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek cast<CompoundAssignOperator>(B)->getComputationLHSType(); 109d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek CLHSTy = getContext().getCanonicalType(CLHSTy); 110d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 111d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek QualType LTy = getContext().getCanonicalType(LHS->getType()); 112d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 113d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // Promote LHS. 114d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek V = svalBuilder.evalCast(V, CLHSTy, LTy); 115d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 116d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // Compute the result of the operation. 117d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy), 118d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek B->getType(), CTy); 119d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 120d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // EXPERIMENTAL: "Conjured" symbols. 121d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // FIXME: Handle structs. 122d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 123d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek SVal LHSVal; 124d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 125d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek if (Result.isUnknown() || 126d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek !getConstraintManager().canReasonAbout(Result)) { 127294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 128d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek unsigned Count = Builder->getCurrentBlockCount(); 129294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 130d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // The symbolic value is actually for the type of the left-hand side 131d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // expression, not the computation type, as this is the value the 132d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // LValue on the LHS will bind to. 133d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek LHSVal = svalBuilder.getConjuredSymbolVal(NULL, B->getRHS(), LTy, 134d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek Count); 135294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 136d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // However, we need to convert the symbol to the computation type. 137d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek Result = svalBuilder.evalCast(LHSVal, CTy, LTy); 138d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek } 139d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek else { 140d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // The left-hand side may bind to a different value then the 141d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // computation type. 142d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek LHSVal = svalBuilder.evalCast(Result, LTy, CTy); 143294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 144d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 145d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // In C++, assignment and compound assignment operators return an 146d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // lvalue. 147d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek if (B->isLValue()) 148d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek state = state->BindExpr(B, location); 149d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek else 150d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek state = state->BindExpr(B, Result); 151d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 152d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek evalStore(Tmp2, B, LHS, *I, state, location, LHSVal); 153294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 154294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 155294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 156d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // FIXME: postvisits eventually go in ::Visit() 157d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this); 158294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 159294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 160294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, 161294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 162294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 163294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek CanQualType T = getContext().getCanonicalType(BE->getType()); 164294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = svalBuilder.getBlockPointer(BE->getBlockDecl(), T, 165294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Pred->getLocationContext()); 166294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 167294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 168294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Tmp, BE, Pred, Pred->getState()->BindExpr(BE, V), 169294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ProgramPoint::PostLValueKind); 170294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 171294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: Move all post/pre visits to ::Visit(). 172294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this); 173294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 174294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 175294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, 176294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst) { 177294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 178294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet dstPreStmt; 179294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this); 180294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 181294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (CastE->getCastKind() == CK_LValueToRValue || 182294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek CastE->getCastKind() == CK_GetObjCProperty) { 183294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end(); 184294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek I!=E; ++I) { 185294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *subExprNode = *I; 186294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = subExprNode->getState(); 187294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek evalLoad(Dst, CastE, subExprNode, state, state->getSVal(Ex)); 188294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 189294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 190294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 191294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 192294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // All other casts. 193294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek QualType T = CastE->getType(); 194294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek QualType ExTy = Ex->getType(); 195294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 196294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE)) 197294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek T = ExCast->getTypeAsWritten(); 198294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 199294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end(); 200294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek I != E; ++I) { 201294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 202294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Pred = *I; 203294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 204294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek switch (CastE->getCastKind()) { 205294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_LValueToRValue: 206294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(false && "LValueToRValue casts handled earlier."); 207294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_GetObjCProperty: 208294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(false && "GetObjCProperty casts handled earlier."); 209294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ToVoid: 210294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Dst.Add(Pred); 211294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 212294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // The analyzer doesn't do anything special with these casts, 213294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // since it understands retain/release semantics already. 214294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ObjCProduceObject: 215294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ObjCConsumeObject: 216294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ObjCReclaimReturnedObject: // Fall-through. 217294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // True no-ops. 218294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_NoOp: 219294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FunctionToPointerDecay: { 220294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Copy the SVal of Ex to CastE. 221294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 222294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = state->getSVal(Ex); 223294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(CastE, V); 224294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, CastE, Pred, state); 225294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 226294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 227294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_Dependent: 228294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ArrayToPointerDecay: 229294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_BitCast: 230294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_LValueBitCast: 231294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralCast: 232294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_NullToPointer: 233294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralToPointer: 234294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_PointerToIntegral: 235294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_PointerToBoolean: 236294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralToBoolean: 237294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralToFloating: 238294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingToIntegral: 239294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingToBoolean: 240294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingCast: 241294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingRealToComplex: 242294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingComplexToReal: 243294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingComplexToBoolean: 244294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingComplexCast: 245294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingComplexToIntegralComplex: 246294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralRealToComplex: 247294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralComplexToReal: 248294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralComplexToBoolean: 249294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralComplexCast: 250294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralComplexToFloatingComplex: 251294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_AnyPointerToObjCPointerCast: 252294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_AnyPointerToBlockPointerCast: 253294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ObjCObjectLValueCast: { 254294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Delegate to SValBuilder to process. 255294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 256294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = state->getSVal(Ex); 257294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek V = svalBuilder.evalCast(V, T, ExTy); 258294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(CastE, V); 259294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, CastE, Pred, state); 260294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 261294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 262294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_DerivedToBase: 263294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_UncheckedDerivedToBase: { 264294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // For DerivedToBase cast, delegate to the store manager. 265294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 266294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal val = state->getSVal(Ex); 267294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek val = getStoreManager().evalDerivedToBase(val, T); 268294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(CastE, val); 269294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, CastE, Pred, state); 270294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 271294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 272294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Various C++ casts that are not handled yet. 273294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_Dynamic: 274294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ToUnion: 275294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_BaseToDerived: 276294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_NullToMemberPointer: 277294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_BaseToDerivedMemberPointer: 278294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_DerivedToBaseMemberPointer: 279294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_UserDefinedConversion: 280294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ConstructorConversion: 281294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_VectorSplat: 282294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_MemberPointerToBoolean: { 283294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Recover some path-sensitivty by conjuring a new value. 284294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek QualType resultType = CastE->getType(); 285294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (CastE->isLValue()) 286294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek resultType = getContext().getPointerType(resultType); 287294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 288294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal result = 289294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek svalBuilder.getConjuredSymbolVal(NULL, CastE, resultType, 290294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Builder->getCurrentBlockCount()); 291294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 292294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState()->BindExpr(CastE, result); 293294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, CastE, Pred, state); 294294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 295294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 296294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 297294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 298294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 299294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 300294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, 301294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 302294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 303294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const InitListExpr *ILE 304294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek = cast<InitListExpr>(CL->getInitializer()->IgnoreParens()); 305294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 306294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 307294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal ILV = state->getSVal(ILE); 308294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const LocationContext *LC = Pred->getLocationContext(); 309294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->bindCompoundLiteral(CL, LC, ILV); 310294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 311294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (CL->isLValue()) 312294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, CL, Pred, state->BindExpr(CL, state->getLValue(CL, LC))); 313294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else 314294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, CL, Pred, state->BindExpr(CL, ILV)); 315294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 316294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 317294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, 318294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 319294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 320294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: static variables may have an initializer, but the second 321294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // time a function is called those values may not be current. 322294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // This may need to be reflected in the CFG. 323294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 324294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Assumption: The CFG has one DeclStmt per Decl. 325294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Decl *D = *DS->decl_begin(); 326294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 327294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (!D || !isa<VarDecl>(D)) 328294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 329294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 330294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: all pre/post visits should eventually be handled by ::Visit(). 331294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet dstPreVisit; 332294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this); 333294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 334294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const VarDecl *VD = dyn_cast<VarDecl>(D); 335294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 336294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end(); 337294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek I!=E; ++I) { 338294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *N = *I; 339294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = N->getState(); 340294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 341294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Decls without InitExpr are not initialized explicitly. 342294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const LocationContext *LC = N->getLocationContext(); 343294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 344294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (const Expr *InitEx = VD->getInit()) { 345294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal InitVal = state->getSVal(InitEx); 346294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 347294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // We bound the temp obj region to the CXXConstructExpr. Now recover 348294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // the lazy compound value when the variable is not a reference. 349294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (AMgr.getLangOptions().CPlusPlus && VD->getType()->isRecordType() && 350294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek !VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){ 351294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion()); 352294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(isa<nonloc::LazyCompoundVal>(InitVal)); 353294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 354294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 355294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Recover some path-sensitivity if a scalar value evaluated to 356294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // UnknownVal. 357294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if ((InitVal.isUnknown() || 358294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek !getConstraintManager().canReasonAbout(InitVal)) && 359294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek !VD->getType()->isReferenceType()) { 360294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx, 361294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Builder->getCurrentBlockCount()); 362294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 363294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 364294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek evalBind(Dst, DS, N, state, 365294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true); 366294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 367294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else { 368294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, DS, N, state->bindDeclWithNoInit(state->getRegion(VD, LC))); 369294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 370294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 371294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 372294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 373294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, 374294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 375294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 376294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(B->getOpcode() == BO_LAnd || 377294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek B->getOpcode() == BO_LOr); 378294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 379294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 380294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal X = state->getSVal(B); 381294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(X.isUndef()); 382294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 383294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = (const Expr*) cast<UndefinedVal>(X).getData(); 384294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(Ex); 385294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 386294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Ex == B->getRHS()) { 387294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek X = state->getSVal(Ex); 388294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 389294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Handle undefined values. 390294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (X.isUndef()) { 391294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, B, Pred, state->BindExpr(B, X)); 392294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 393294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 394294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 395294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek DefinedOrUnknownSVal XD = cast<DefinedOrUnknownSVal>(X); 396294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 397294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // We took the RHS. Because the value of the '&&' or '||' expression must 398294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // evaluate to 0 or 1, we must assume the value of the RHS evaluates to 0 399294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // or 1. Alternatively, we could take a lazy approach, and calculate this 400294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // value later when necessary. We don't have the machinery in place for 401294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // this right now, and since most logical expressions are used for branches, 402294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // the payoff is not likely to be large. Instead, we do eager evaluation. 403294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (const ProgramState *newState = state->assume(XD, true)) 404294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, B, Pred, 405294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek newState->BindExpr(B, svalBuilder.makeIntVal(1U, B->getType()))); 406294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 407294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (const ProgramState *newState = state->assume(XD, false)) 408294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, B, Pred, 409294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek newState->BindExpr(B, svalBuilder.makeIntVal(0U, B->getType()))); 410294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 411294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else { 412294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // We took the LHS expression. Depending on whether we are '&&' or 413294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // '||' we know what the value of the expression is via properties of 414294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // the short-circuiting. 415294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek X = svalBuilder.makeIntVal(B->getOpcode() == BO_LAnd ? 0U : 1U, 416294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek B->getType()); 417294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, B, Pred, state->BindExpr(B, X)); 418294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 419294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 420294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 421294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitInitListExpr(const InitListExpr *IE, 422294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 423294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 424294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 425294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 426294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek QualType T = getContext().getCanonicalType(IE->getType()); 427294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek unsigned NumInitElements = IE->getNumInits(); 428294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 429294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (T->isArrayType() || T->isRecordType() || T->isVectorType()) { 430294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList(); 431294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 432294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Handle base case where the initializer has no elements. 433294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // e.g: static int* myArray[] = {}; 434294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (NumInitElements == 0) { 435294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = svalBuilder.makeCompoundVal(T, vals); 436294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, IE, Pred, state->BindExpr(IE, V)); 437294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 438294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 439294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 440294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (InitListExpr::const_reverse_iterator it = IE->rbegin(), 441294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ei = IE->rend(); it != ei; ++it) { 442294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek vals = getBasicVals().consVals(state->getSVal(cast<Expr>(*it)), vals); 443294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 444294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 445294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, IE, Pred, 446294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state->BindExpr(IE, svalBuilder.makeCompoundVal(T, vals))); 447294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 448294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 449294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 450294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Loc::isLocType(T) || T->isIntegerType()) { 451294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(IE->getNumInits() == 1); 452294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *initEx = IE->getInit(0); 453294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, IE, Pred, state->BindExpr(IE, state->getSVal(initEx))); 454294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 455294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 456294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 457294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek llvm_unreachable("unprocessed InitListExpr type"); 458294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 459294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 460294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitGuardedExpr(const Expr *Ex, 461294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *L, 462294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *R, 463294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 464294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 465294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 466294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 467294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal X = state->getSVal(Ex); 468294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert (X.isUndef()); 469294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *SE = (Expr*) cast<UndefinedVal>(X).getData(); 470294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(SE); 471294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek X = state->getSVal(SE); 472294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 473294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Make sure that we invalidate the previous binding. 474294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, X, true)); 475294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 476294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 477294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine:: 478294fd0a62b95f512637910bf85c7efa6c2354b50Ted KremenekVisitOffsetOfExpr(const OffsetOfExpr *OOE, 479294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst) { 480294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Expr::EvalResult Res; 481294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (OOE->Evaluate(Res, getContext()) && Res.Val.isInt()) { 482294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const APSInt &IV = Res.Val.getInt(); 483294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType())); 484294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(OOE->getType()->isIntegerType()); 485294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(IV.isSigned() == OOE->getType()->isSignedIntegerOrEnumerationType()); 486294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal X = svalBuilder.makeIntVal(IV); 487294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, OOE, Pred, Pred->getState()->BindExpr(OOE, X)); 488294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 489294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 490294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: Handle the case where __builtin_offsetof is not a constant. 491294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Dst.Add(Pred); 492294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 493294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 494294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 495294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine:: 496294fd0a62b95f512637910bf85c7efa6c2354b50Ted KremenekVisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, 497294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 498294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 499294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 500294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek QualType T = Ex->getTypeOfArgument(); 501294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 502294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Ex->getKind() == UETT_SizeOf) { 503294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (!T->isIncompleteType() && !T->isConstantSizeType()) { 504294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(T->isVariableArrayType() && "Unknown non-constant-sized type."); 505294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 506540dda6f2e4982b3eab0300c804345f5b6104c11Ted Kremenek // FIXME: Add support for VLA type arguments and VLA expressions. 507294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // When that happens, we should probably refactor VLASizeChecker's code. 508540dda6f2e4982b3eab0300c804345f5b6104c11Ted Kremenek Dst.Add(Pred); 509294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 510294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 511294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else if (T->getAs<ObjCObjectType>()) { 512294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Some code tries to take the sizeof an ObjCObjectType, relying that 513294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // the compiler has laid out its representation. Just report Unknown 514294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // for these. 515294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Dst.Add(Pred); 516294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 517294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 518294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 519294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 520294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Expr::EvalResult Result; 521294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Ex->Evaluate(Result, getContext()); 522294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek CharUnits amt = CharUnits::fromQuantity(Result.Val.getInt().getZExtValue()); 523294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 524294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 525294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(Ex, svalBuilder.makeIntVal(amt.getQuantity(), 526294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Ex->getType())); 527294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, Ex, Pred, state); 528294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 529294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 530294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitUnaryOperator(const UnaryOperator* U, 531294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 532294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 533294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek switch (U->getOpcode()) { 534294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek default: 535294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek break; 536294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Real: { 537294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 538294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 539294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 540294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 541294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { 542294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 543294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: We don't have complex SValues yet. 544294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Ex->getType()->isAnyComplexType()) { 545294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Just report "Unknown." 546294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Dst.Add(*I); 547294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 548294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 549294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 550294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // For all other types, UO_Real is an identity operation. 551294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert (U->getType() == Ex->getType()); 552294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 553294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, U, *I, state->BindExpr(U, state->getSVal(Ex))); 554294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 555294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 556294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 557294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 558294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 559294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Imag: { 560294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 561294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 562294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 563294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 564294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 565294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { 566294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: We don't have complex SValues yet. 567294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Ex->getType()->isAnyComplexType()) { 568294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Just report "Unknown." 569294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Dst.Add(*I); 570294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 571294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 572294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 573294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // For all other types, UO_Imag returns 0. 574294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 575294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal X = svalBuilder.makeZeroVal(Ex->getType()); 576294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, U, *I, state->BindExpr(U, X)); 577294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 578294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 579294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 580294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 581294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 582294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Plus: 583294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(!U->isLValue()); 584294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FALL-THROUGH. 585294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Deref: 586294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_AddrOf: 587294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Extension: { 588294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 589294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Unary "+" is a no-op, similar to a parentheses. We still have places 590294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // where it may be a block-level expression, so we need to 591294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // generate an extra node that just propagates the value of the 592294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // subexpression. 593294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 594294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 595294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 596294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 597294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 598294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { 599294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 600294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, U, *I, state->BindExpr(U, state->getSVal(Ex))); 601294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 602294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 603294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 604294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 605294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 606294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_LNot: 607294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Minus: 608294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Not: { 609294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert (!U->isLValue()); 610294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 611294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 612294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 613294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 614294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { 615294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 616294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 617294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Get the value of the subexpression. 618294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = state->getSVal(Ex); 619294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 620294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (V.isUnknownOrUndef()) { 621294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, U, *I, state->BindExpr(U, V)); 622294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 623294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 624294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 625294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek switch (U->getOpcode()) { 626294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek default: 627294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(false && "Invalid Opcode."); 628294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek break; 629294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 630294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Not: 631294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: Do we need to handle promotions? 632294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, evalComplement(cast<NonLoc>(V))); 633294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek break; 634294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 635294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Minus: 636294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: Do we need to handle promotions? 637294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, evalMinus(cast<NonLoc>(V))); 638294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek break; 639294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 640294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_LNot: 641294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 642294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // C99 6.5.3.3: "The expression !E is equivalent to (0==E)." 643294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // 644294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Note: technically we do "E == 0", but this is the same in the 645294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // transfer functions as "0 == E". 646294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal Result; 647294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 648294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (isa<Loc>(V)) { 649294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Loc X = svalBuilder.makeNull(); 650294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Result = evalBinOp(state, BO_EQ, cast<Loc>(V), X, 651294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek U->getType()); 652294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 653294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else { 654294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType())); 655294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Result = evalBinOp(state, BO_EQ, cast<NonLoc>(V), X, 656294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek U->getType()); 657294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 658294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 659294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, Result); 660294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 661294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek break; 662294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 663294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 664294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, U, *I, state); 665294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 666294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 667294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 668294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 669294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 670294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 671294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Handle ++ and -- (both pre- and post-increment). 672294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert (U->isIncrementDecrementOp()); 673294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 674294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 675294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 676294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 677294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) { 678294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 679294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 680294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal loc = state->getSVal(Ex); 681294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 682294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Perform a load. 683294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp2; 684294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek evalLoad(Tmp2, Ex, *I, state, loc); 685294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 686294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end();I2!=E2;++I2) { 687294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 688294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = (*I2)->getState(); 689294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V2_untested = state->getSVal(Ex); 690294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 691294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Propagate unknown and undefined values. 692294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (V2_untested.isUnknownOrUndef()) { 693294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, U, *I2, state->BindExpr(U, V2_untested)); 694294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 695294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 696294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek DefinedSVal V2 = cast<DefinedSVal>(V2_untested); 697294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 698294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Handle all other values. 699294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add 700294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek : BO_Sub; 701294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 702294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // If the UnaryOperator has non-location type, use its type to create the 703294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // constant value. If the UnaryOperator has location type, create the 704294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // constant with int type and pointer width. 705294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal RHS; 706294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 707294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (U->getType()->isAnyPointerType()) 708294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek RHS = svalBuilder.makeArrayIndex(1); 709294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else 710294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek RHS = svalBuilder.makeIntVal(1, U->getType()); 711294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 712294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal Result = evalBinOp(state, Op, V2, RHS, U->getType()); 713294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 714294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Conjure a new symbol if necessary to recover precision. 715294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)){ 716294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek DefinedOrUnknownSVal SymVal = 717294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek svalBuilder.getConjuredSymbolVal(NULL, Ex, 718294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Builder->getCurrentBlockCount()); 719294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Result = SymVal; 720294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 721294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // If the value is a location, ++/-- should always preserve 722294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // non-nullness. Check if the original value was non-null, and if so 723294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // propagate that constraint. 724294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Loc::isLocType(U->getType())) { 725294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek DefinedOrUnknownSVal Constraint = 726294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType())); 727294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 728294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (!state->assume(Constraint, true)) { 729294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // It isn't feasible for the original value to be null. 730294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Propagate this constraint. 731294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Constraint = svalBuilder.evalEQ(state, SymVal, 732294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek svalBuilder.makeZeroVal(U->getType())); 733294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 734294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 735294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->assume(Constraint, false); 736294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(state); 737294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 738294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 739294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 740294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 741294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Since the lvalue-to-rvalue conversion is explicit in the AST, 742294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // we bind an l-value if the operator is prefix and an lvalue (in C++). 743294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (U->isLValue()) 744294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, loc); 745294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else 746294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, U->isPostfix() ? V2 : Result); 747294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 748294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Perform the store. 749294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek evalStore(Dst, NULL, U, *I2, state, loc, Result); 750294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 751294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 752294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 753