ExprEngineC.cpp revision 8ad8c546372fe602708cb7ceeaf0ebbb866735c6
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: 77b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("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: 206b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("LValueToRValue casts handled earlier."); 207294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_GetObjCProperty: 208b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("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. 21433e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCProduceObject: 21533e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCConsumeObject: 21633e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCReclaimReturnedObject: 21733e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCExtendBlockObject: // Fall-through. 218294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // True no-ops. 219294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_NoOp: 220294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FunctionToPointerDecay: { 221294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Copy the SVal of Ex to CastE. 222294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 223294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = state->getSVal(Ex); 224294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(CastE, V); 225294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, CastE, Pred, state); 226294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 227294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 228294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_Dependent: 229294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ArrayToPointerDecay: 230294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_BitCast: 231294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_LValueBitCast: 232294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralCast: 233294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_NullToPointer: 234294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralToPointer: 235294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_PointerToIntegral: 236294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_PointerToBoolean: 237294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralToBoolean: 238294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralToFloating: 239294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingToIntegral: 240294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingToBoolean: 241294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingCast: 242294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingRealToComplex: 243294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingComplexToReal: 244294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingComplexToBoolean: 245294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingComplexCast: 246294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingComplexToIntegralComplex: 247294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralRealToComplex: 248294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralComplexToReal: 249294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralComplexToBoolean: 250294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralComplexCast: 251294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralComplexToFloatingComplex: 2521d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall case CK_CPointerToObjCPointerCast: 2531d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall case CK_BlockPointerToObjCPointerCast: 254294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_AnyPointerToBlockPointerCast: 255294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ObjCObjectLValueCast: { 256294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Delegate to SValBuilder to process. 257294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 258294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = state->getSVal(Ex); 259294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek V = svalBuilder.evalCast(V, T, ExTy); 260294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(CastE, V); 261294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, CastE, Pred, state); 262294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 263294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 264294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_DerivedToBase: 265294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_UncheckedDerivedToBase: { 266294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // For DerivedToBase cast, delegate to the store manager. 267294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 268294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal val = state->getSVal(Ex); 269294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek val = getStoreManager().evalDerivedToBase(val, T); 270294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(CastE, val); 271294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, CastE, Pred, state); 272294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 273294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 274294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Various C++ casts that are not handled yet. 275294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_Dynamic: 276294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ToUnion: 277294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_BaseToDerived: 278294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_NullToMemberPointer: 279294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_BaseToDerivedMemberPointer: 280294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_DerivedToBaseMemberPointer: 281294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_UserDefinedConversion: 282294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ConstructorConversion: 283294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_VectorSplat: 284294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_MemberPointerToBoolean: { 285294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Recover some path-sensitivty by conjuring a new value. 286294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek QualType resultType = CastE->getType(); 287294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (CastE->isLValue()) 288294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek resultType = getContext().getPointerType(resultType); 289294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 290294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal result = 291294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek svalBuilder.getConjuredSymbolVal(NULL, CastE, resultType, 292294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Builder->getCurrentBlockCount()); 293294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 294294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState()->BindExpr(CastE, result); 295294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, CastE, Pred, state); 296294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 297294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 298294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 299294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 300294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 301294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 302294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, 303294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 304294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 305294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const InitListExpr *ILE 306294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek = cast<InitListExpr>(CL->getInitializer()->IgnoreParens()); 307294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 308294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 309294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal ILV = state->getSVal(ILE); 310294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const LocationContext *LC = Pred->getLocationContext(); 311294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->bindCompoundLiteral(CL, LC, ILV); 312294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 313294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (CL->isLValue()) 314294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, CL, Pred, state->BindExpr(CL, state->getLValue(CL, LC))); 315294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else 316294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, CL, Pred, state->BindExpr(CL, ILV)); 317294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 318294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 319294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, 320294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 321294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 322294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: static variables may have an initializer, but the second 323294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // time a function is called those values may not be current. 324294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // This may need to be reflected in the CFG. 325294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 326294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Assumption: The CFG has one DeclStmt per Decl. 327294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Decl *D = *DS->decl_begin(); 328294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 329294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (!D || !isa<VarDecl>(D)) 330294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 331294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 332294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: all pre/post visits should eventually be handled by ::Visit(). 333294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet dstPreVisit; 334294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this); 335294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 336294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const VarDecl *VD = dyn_cast<VarDecl>(D); 337294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 338294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end(); 339294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek I!=E; ++I) { 340294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *N = *I; 341294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = N->getState(); 342294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 343294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Decls without InitExpr are not initialized explicitly. 344294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const LocationContext *LC = N->getLocationContext(); 345294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 346294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (const Expr *InitEx = VD->getInit()) { 347294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal InitVal = state->getSVal(InitEx); 348294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 349294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // We bound the temp obj region to the CXXConstructExpr. Now recover 350294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // the lazy compound value when the variable is not a reference. 351294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (AMgr.getLangOptions().CPlusPlus && VD->getType()->isRecordType() && 352294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek !VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){ 353294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion()); 354294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(isa<nonloc::LazyCompoundVal>(InitVal)); 355294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 356294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 357294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Recover some path-sensitivity if a scalar value evaluated to 358294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // UnknownVal. 359294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if ((InitVal.isUnknown() || 360294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek !getConstraintManager().canReasonAbout(InitVal)) && 361294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek !VD->getType()->isReferenceType()) { 362294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx, 363294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Builder->getCurrentBlockCount()); 364294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 365294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 36693bd5ca766c4d7906878f4ffe76ce1b2080e540bJordy Rose evalBind(Dst, DS, N, state->getLValue(VD, LC), InitVal, true); 367294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 368294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else { 369294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, DS, N, state->bindDeclWithNoInit(state->getRegion(VD, LC))); 370294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 371294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 372294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 373294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 374294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, 375294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 376294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 377294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(B->getOpcode() == BO_LAnd || 378294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek B->getOpcode() == BO_LOr); 379294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 380294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 381294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal X = state->getSVal(B); 382294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(X.isUndef()); 383294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 384294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = (const Expr*) cast<UndefinedVal>(X).getData(); 385294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(Ex); 386294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 387294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Ex == B->getRHS()) { 388294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek X = state->getSVal(Ex); 389294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 390294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Handle undefined values. 391294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (X.isUndef()) { 392294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, B, Pred, state->BindExpr(B, X)); 393294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 394294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 395294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 396294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek DefinedOrUnknownSVal XD = cast<DefinedOrUnknownSVal>(X); 397294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 398294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // We took the RHS. Because the value of the '&&' or '||' expression must 399294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // evaluate to 0 or 1, we must assume the value of the RHS evaluates to 0 400294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // or 1. Alternatively, we could take a lazy approach, and calculate this 401294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // value later when necessary. We don't have the machinery in place for 402294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // this right now, and since most logical expressions are used for branches, 403294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // the payoff is not likely to be large. Instead, we do eager evaluation. 404294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (const ProgramState *newState = state->assume(XD, true)) 405294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, B, Pred, 406294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek newState->BindExpr(B, svalBuilder.makeIntVal(1U, B->getType()))); 407294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 408294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (const ProgramState *newState = state->assume(XD, false)) 409294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, B, Pred, 410294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek newState->BindExpr(B, svalBuilder.makeIntVal(0U, B->getType()))); 411294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 412294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else { 413294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // We took the LHS expression. Depending on whether we are '&&' or 414294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // '||' we know what the value of the expression is via properties of 415294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // the short-circuiting. 416294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek X = svalBuilder.makeIntVal(B->getOpcode() == BO_LAnd ? 0U : 1U, 417294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek B->getType()); 418294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, B, Pred, state->BindExpr(B, X)); 419294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 420294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 421294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 422294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitInitListExpr(const InitListExpr *IE, 423294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 424294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 425294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 426294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 427294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek QualType T = getContext().getCanonicalType(IE->getType()); 428294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek unsigned NumInitElements = IE->getNumInits(); 429294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 430294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (T->isArrayType() || T->isRecordType() || T->isVectorType()) { 431294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList(); 432294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 433294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Handle base case where the initializer has no elements. 434294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // e.g: static int* myArray[] = {}; 435294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (NumInitElements == 0) { 436294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = svalBuilder.makeCompoundVal(T, vals); 437294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, IE, Pred, state->BindExpr(IE, V)); 438294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 439294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 440294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 441294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (InitListExpr::const_reverse_iterator it = IE->rbegin(), 442294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ei = IE->rend(); it != ei; ++it) { 443294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek vals = getBasicVals().consVals(state->getSVal(cast<Expr>(*it)), vals); 444294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 445294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 446294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, IE, Pred, 447294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state->BindExpr(IE, svalBuilder.makeCompoundVal(T, vals))); 448294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 449294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 450294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 451294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Loc::isLocType(T) || T->isIntegerType()) { 452294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(IE->getNumInits() == 1); 453294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *initEx = IE->getInit(0); 454294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, IE, Pred, state->BindExpr(IE, state->getSVal(initEx))); 455294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 456294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 457294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 458294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek llvm_unreachable("unprocessed InitListExpr type"); 459294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 460294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 461294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitGuardedExpr(const Expr *Ex, 462294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *L, 463294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *R, 464294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 465294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 466294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 467294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 468294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal X = state->getSVal(Ex); 469294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert (X.isUndef()); 470294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *SE = (Expr*) cast<UndefinedVal>(X).getData(); 471294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(SE); 472294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek X = state->getSVal(SE); 473294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 474294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Make sure that we invalidate the previous binding. 475294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, X, true)); 476294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 477294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 478294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine:: 479294fd0a62b95f512637910bf85c7efa6c2354b50Ted KremenekVisitOffsetOfExpr(const OffsetOfExpr *OOE, 480294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst) { 481294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Expr::EvalResult Res; 482294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (OOE->Evaluate(Res, getContext()) && Res.Val.isInt()) { 483294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const APSInt &IV = Res.Val.getInt(); 484294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType())); 485294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(OOE->getType()->isIntegerType()); 486294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(IV.isSigned() == OOE->getType()->isSignedIntegerOrEnumerationType()); 487294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal X = svalBuilder.makeIntVal(IV); 488294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, OOE, Pred, Pred->getState()->BindExpr(OOE, X)); 489294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 490294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 491294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: Handle the case where __builtin_offsetof is not a constant. 492294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Dst.Add(Pred); 493294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 494294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 495294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 496294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine:: 497294fd0a62b95f512637910bf85c7efa6c2354b50Ted KremenekVisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, 498294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 499294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 500294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 501294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek QualType T = Ex->getTypeOfArgument(); 502294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 503294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Ex->getKind() == UETT_SizeOf) { 504294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (!T->isIncompleteType() && !T->isConstantSizeType()) { 505294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(T->isVariableArrayType() && "Unknown non-constant-sized type."); 506294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 507540dda6f2e4982b3eab0300c804345f5b6104c11Ted Kremenek // FIXME: Add support for VLA type arguments and VLA expressions. 508294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // When that happens, we should probably refactor VLASizeChecker's code. 509540dda6f2e4982b3eab0300c804345f5b6104c11Ted Kremenek Dst.Add(Pred); 510294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 511294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 512294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else if (T->getAs<ObjCObjectType>()) { 513294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Some code tries to take the sizeof an ObjCObjectType, relying that 514294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // the compiler has laid out its representation. Just report Unknown 515294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // for these. 516294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Dst.Add(Pred); 517294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 518294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 519294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 520294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 521294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Expr::EvalResult Result; 522294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Ex->Evaluate(Result, getContext()); 523294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek CharUnits amt = CharUnits::fromQuantity(Result.Val.getInt().getZExtValue()); 524294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 525294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 526294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(Ex, svalBuilder.makeIntVal(amt.getQuantity(), 527294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Ex->getType())); 528294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, Ex, Pred, state); 529294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 530294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 531294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitUnaryOperator(const UnaryOperator* U, 532294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 5338ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks ExplodedNodeSet &Dst) { 5348ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks Builder->takeNodes(Pred); 5358ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks PureStmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 5368ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks bool IncDec = false; 537294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek switch (U->getOpcode()) { 538294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek default: 5398ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks Builder->addNodes(Pred); 5408ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks IncDec = true; 5418ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks VisitIncrementDecrementOperator(U, Pred, Dst); 542294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek break; 543294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Real: { 544294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 545294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 546294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 547294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 548294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { 549294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 550294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: We don't have complex SValues yet. 551294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Ex->getType()->isAnyComplexType()) { 552294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Just report "Unknown." 553294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 554294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 555294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 556294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // For all other types, UO_Real is an identity operation. 557294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert (U->getType() == Ex->getType()); 558294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 5598ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks Bldr.generateNode(U, *I, state->BindExpr(U, state->getSVal(Ex))); 560294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 561294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 5628ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks break; 563294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 564294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 565294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Imag: { 566294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 567294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 568294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 569294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 570294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 571294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { 572294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: We don't have complex SValues yet. 573294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Ex->getType()->isAnyComplexType()) { 574294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Just report "Unknown." 575294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 576294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 577294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 578294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // For all other types, UO_Imag returns 0. 579294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 580294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal X = svalBuilder.makeZeroVal(Ex->getType()); 5818ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks Bldr.generateNode(U, *I, state->BindExpr(U, X)); 582294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 583294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 5848ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks break; 585294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 586294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 587294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Plus: 588294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(!U->isLValue()); 589294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FALL-THROUGH. 590294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Deref: 591294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_AddrOf: 592294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Extension: { 593294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 594294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Unary "+" is a no-op, similar to a parentheses. We still have places 595294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // where it may be a block-level expression, so we need to 596294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // generate an extra node that just propagates the value of the 597294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // subexpression. 598294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 599294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 600294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 601294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 602294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 603294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { 604294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 6058ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks Bldr.generateNode(U, *I, state->BindExpr(U, state->getSVal(Ex))); 606294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 607294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 6088ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks break; 609294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 610294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 611294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_LNot: 612294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Minus: 613294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Not: { 614294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert (!U->isLValue()); 615294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 616294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 617294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 618294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 619294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { 620294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 621294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 622294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Get the value of the subexpression. 623294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = state->getSVal(Ex); 624294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 625294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (V.isUnknownOrUndef()) { 6268ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks Bldr.generateNode(U, *I, state->BindExpr(U, V)); 627294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 628294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 629294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 630294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek switch (U->getOpcode()) { 631294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek default: 632b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Invalid Opcode."); 633294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 634294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Not: 635294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: Do we need to handle promotions? 636294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, evalComplement(cast<NonLoc>(V))); 637294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek break; 638294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 639294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Minus: 640294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: Do we need to handle promotions? 641294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, evalMinus(cast<NonLoc>(V))); 642294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek break; 643294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 644294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_LNot: 645294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 646294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // C99 6.5.3.3: "The expression !E is equivalent to (0==E)." 647294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // 648294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Note: technically we do "E == 0", but this is the same in the 649294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // transfer functions as "0 == E". 650294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal Result; 651294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 652294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (isa<Loc>(V)) { 653294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Loc X = svalBuilder.makeNull(); 654294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Result = evalBinOp(state, BO_EQ, cast<Loc>(V), X, 655294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek U->getType()); 656294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 657294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else { 658294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType())); 659294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Result = evalBinOp(state, BO_EQ, cast<NonLoc>(V), X, 660294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek U->getType()); 661294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 662294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 663294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, Result); 664294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 665294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek break; 666294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 6678ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks Bldr.generateNode(U, *I, state); 668294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 6698ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks break; 670294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 671294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 6728ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks 6738ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks if (!IncDec) 6748ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks Builder->addNodes(Dst); 6758ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks} 6768ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks 6778ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaksvoid ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U, 6788ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks ExplodedNode *Pred, 6798ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks ExplodedNodeSet &Dst) { 680294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Handle ++ and -- (both pre- and post-increment). 681294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert (U->isIncrementDecrementOp()); 682294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 683294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 684294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 685294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 686294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) { 687294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 688294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 689294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal loc = state->getSVal(Ex); 690294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 691294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Perform a load. 692294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp2; 693294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek evalLoad(Tmp2, Ex, *I, state, loc); 694294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 695294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end();I2!=E2;++I2) { 696294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 697294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = (*I2)->getState(); 698294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V2_untested = state->getSVal(Ex); 699294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 700294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Propagate unknown and undefined values. 701294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (V2_untested.isUnknownOrUndef()) { 702294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek MakeNode(Dst, U, *I2, state->BindExpr(U, V2_untested)); 703294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 704294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 705294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek DefinedSVal V2 = cast<DefinedSVal>(V2_untested); 706294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 707294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Handle all other values. 708294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add 709294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek : BO_Sub; 710294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 711294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // If the UnaryOperator has non-location type, use its type to create the 712294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // constant value. If the UnaryOperator has location type, create the 713294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // constant with int type and pointer width. 714294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal RHS; 715294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 716294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (U->getType()->isAnyPointerType()) 717294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek RHS = svalBuilder.makeArrayIndex(1); 718294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else 719294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek RHS = svalBuilder.makeIntVal(1, U->getType()); 720294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 721294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal Result = evalBinOp(state, Op, V2, RHS, U->getType()); 722294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 723294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Conjure a new symbol if necessary to recover precision. 724294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)){ 725294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek DefinedOrUnknownSVal SymVal = 726294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek svalBuilder.getConjuredSymbolVal(NULL, Ex, 727294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Builder->getCurrentBlockCount()); 728294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Result = SymVal; 729294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 730294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // If the value is a location, ++/-- should always preserve 731294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // non-nullness. Check if the original value was non-null, and if so 732294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // propagate that constraint. 733294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Loc::isLocType(U->getType())) { 734294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek DefinedOrUnknownSVal Constraint = 735294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType())); 736294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 737294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (!state->assume(Constraint, true)) { 738294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // It isn't feasible for the original value to be null. 739294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Propagate this constraint. 740294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Constraint = svalBuilder.evalEQ(state, SymVal, 7418ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks svalBuilder.makeZeroVal(U->getType())); 742294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 743294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 744294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->assume(Constraint, false); 745294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(state); 746294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 747294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 748294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 749294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 750294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Since the lvalue-to-rvalue conversion is explicit in the AST, 751294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // we bind an l-value if the operator is prefix and an lvalue (in C++). 752294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (U->isLValue()) 753294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, loc); 754294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else 755294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, U->isPostfix() ? V2 : Result); 756294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 757294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Perform the store. 758294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek evalStore(Dst, NULL, U, *I2, state, loc, Result); 759294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 760294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 761294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 762