ExprEngineC.cpp revision aa0aeb1cbe117db68d35700cb3a34aace0f99b99
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)) { 49ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks unsigned Count = currentBuilderContext->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()) { 60aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder Bldr(*it, Tmp2, *currentBuilderContext); 61d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // Process non-assignments except commas or short-circuited 62d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // logical expressions (LAnd and LOr). 63d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType()); 64d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek if (Result.isUnknown()) { 65ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(B, *it, state); 66294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 67d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek } 68d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 69d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek state = state->BindExpr(B, Result); 70ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(B, *it, state); 71d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek continue; 72d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek } 73294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 74d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek assert (B->isCompoundAssignmentOp()); 75d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 76d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek switch (Op) { 77d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek default: 78b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Invalid opcode for compound assignment."); 79d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_MulAssign: Op = BO_Mul; break; 80d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_DivAssign: Op = BO_Div; break; 81d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_RemAssign: Op = BO_Rem; break; 82d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_AddAssign: Op = BO_Add; break; 83d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_SubAssign: Op = BO_Sub; break; 84d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_ShlAssign: Op = BO_Shl; break; 85d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_ShrAssign: Op = BO_Shr; break; 86d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_AndAssign: Op = BO_And; break; 87d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_XorAssign: Op = BO_Xor; break; 88d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek case BO_OrAssign: Op = BO_Or; break; 89d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek } 90294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 91d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // Perform a load (the LHS). This performs the checks for 92d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // null dereferences, and so on. 93d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek ExplodedNodeSet Tmp; 94d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek SVal location = LeftV; 95d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek evalLoad(Tmp, LHS, *it, state, location); 96d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 97d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; 98d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek ++I) { 99d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 100d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek state = (*I)->getState(); 101d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek SVal V = state->getSVal(LHS); 102294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 103d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // Get the computation type. 104d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek QualType CTy = 105294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek cast<CompoundAssignOperator>(B)->getComputationResultType(); 106d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek CTy = getContext().getCanonicalType(CTy); 107d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 108d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek QualType CLHSTy = 109294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek cast<CompoundAssignOperator>(B)->getComputationLHSType(); 110d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek CLHSTy = getContext().getCanonicalType(CLHSTy); 111d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 112d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek QualType LTy = getContext().getCanonicalType(LHS->getType()); 113d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 114d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // Promote LHS. 115d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek V = svalBuilder.evalCast(V, CLHSTy, LTy); 116d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 117d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // Compute the result of the operation. 118d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy), 119d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek B->getType(), CTy); 120d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 121d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // EXPERIMENTAL: "Conjured" symbols. 122d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // FIXME: Handle structs. 123d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 124d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek SVal LHSVal; 125d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 126d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek if (Result.isUnknown() || 127d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek !getConstraintManager().canReasonAbout(Result)) { 128294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 129ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks unsigned Count = currentBuilderContext->getCurrentBlockCount(); 130294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 131d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // The symbolic value is actually for the type of the left-hand side 132d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // expression, not the computation type, as this is the value the 133d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // LValue on the LHS will bind to. 134d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek LHSVal = svalBuilder.getConjuredSymbolVal(NULL, B->getRHS(), LTy, 135d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek Count); 136294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 137d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // However, we need to convert the symbol to the computation type. 138d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek Result = svalBuilder.evalCast(LHSVal, CTy, LTy); 139d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek } 140d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek else { 141d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // The left-hand side may bind to a different value then the 142d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // computation type. 143d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek LHSVal = svalBuilder.evalCast(Result, LTy, CTy); 144294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 145d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 146d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // In C++, assignment and compound assignment operators return an 147d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // lvalue. 148d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek if (B->isLValue()) 149d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek state = state->BindExpr(B, location); 150d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek else 151d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek state = state->BindExpr(B, Result); 152d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek 153d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek evalStore(Tmp2, B, LHS, *I, state, location, LHSVal); 154294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 155294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 156294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 157d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek // FIXME: postvisits eventually go in ::Visit() 158d203c026c6f836e79abfbf2171ac4ba30e52db76Ted Kremenek getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this); 159294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 160294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 161294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, 162294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 163294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 164294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek CanQualType T = getContext().getCanonicalType(BE->getType()); 165294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = svalBuilder.getBlockPointer(BE->getBlockDecl(), T, 166294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Pred->getLocationContext()); 167294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 168294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 169aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder Bldr(Pred, Tmp, *currentBuilderContext); 170ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(BE, Pred, Pred->getState()->BindExpr(BE, V), false, 0, 171ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ProgramPoint::PostLValueKind); 172294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 173294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: Move all post/pre visits to ::Visit(). 174294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this); 175294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 176294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 177294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, 178294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst) { 179294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 180294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet dstPreStmt; 181294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this); 182294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 183294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (CastE->getCastKind() == CK_LValueToRValue || 184294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek CastE->getCastKind() == CK_GetObjCProperty) { 185294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end(); 186294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek I!=E; ++I) { 187294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *subExprNode = *I; 188294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = subExprNode->getState(); 189294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek evalLoad(Dst, CastE, subExprNode, state, state->getSVal(Ex)); 190294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 191294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 192294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 193294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 194294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // All other casts. 195294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek QualType T = CastE->getType(); 196294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek QualType ExTy = Ex->getType(); 197294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 198294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE)) 199294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek T = ExCast->getTypeAsWritten(); 200294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 201aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder Bldr(dstPreStmt, Dst, *currentBuilderContext); 202294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end(); 203294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek I != E; ++I) { 204294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 205294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Pred = *I; 206294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 207294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek switch (CastE->getCastKind()) { 208294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_LValueToRValue: 209b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("LValueToRValue casts handled earlier."); 210294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_GetObjCProperty: 211b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("GetObjCProperty casts handled earlier."); 212294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ToVoid: 213294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 214294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // The analyzer doesn't do anything special with these casts, 215294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // since it understands retain/release semantics already. 21633e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCProduceObject: 21733e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCConsumeObject: 21833e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCReclaimReturnedObject: 21933e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCExtendBlockObject: // Fall-through. 220294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // True no-ops. 221294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_NoOp: 222294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FunctionToPointerDecay: { 223294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Copy the SVal of Ex to CastE. 224294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 225294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = state->getSVal(Ex); 226294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(CastE, V); 227ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(CastE, Pred, state); 228294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 229294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 230294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_Dependent: 231294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ArrayToPointerDecay: 232294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_BitCast: 233294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_LValueBitCast: 234294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralCast: 235294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_NullToPointer: 236294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralToPointer: 237294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_PointerToIntegral: 238294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_PointerToBoolean: 239294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralToBoolean: 240294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralToFloating: 241294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingToIntegral: 242294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingToBoolean: 243294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingCast: 244294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingRealToComplex: 245294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingComplexToReal: 246294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingComplexToBoolean: 247294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingComplexCast: 248294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_FloatingComplexToIntegralComplex: 249294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralRealToComplex: 250294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralComplexToReal: 251294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralComplexToBoolean: 252294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralComplexCast: 253294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_IntegralComplexToFloatingComplex: 2541d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall case CK_CPointerToObjCPointerCast: 2551d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall case CK_BlockPointerToObjCPointerCast: 256294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_AnyPointerToBlockPointerCast: 257294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ObjCObjectLValueCast: { 258294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Delegate to SValBuilder to process. 259294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 260294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = state->getSVal(Ex); 261294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek V = svalBuilder.evalCast(V, T, ExTy); 262294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(CastE, V); 263ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(CastE, Pred, state); 264294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 265294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 266294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_DerivedToBase: 267294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_UncheckedDerivedToBase: { 268294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // For DerivedToBase cast, delegate to the store manager. 269294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 270294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal val = state->getSVal(Ex); 271294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek val = getStoreManager().evalDerivedToBase(val, T); 272294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(CastE, val); 273ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(CastE, Pred, state); 274294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 275294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 276294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Various C++ casts that are not handled yet. 277294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_Dynamic: 278294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ToUnion: 279294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_BaseToDerived: 280294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_NullToMemberPointer: 281294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_BaseToDerivedMemberPointer: 282294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_DerivedToBaseMemberPointer: 283294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_UserDefinedConversion: 284294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_ConstructorConversion: 285294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_VectorSplat: 286294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case CK_MemberPointerToBoolean: { 287294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Recover some path-sensitivty by conjuring a new value. 288294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek QualType resultType = CastE->getType(); 289294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (CastE->isLValue()) 290294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek resultType = getContext().getPointerType(resultType); 291294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 292294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal result = 293294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek svalBuilder.getConjuredSymbolVal(NULL, CastE, resultType, 294ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks currentBuilderContext->getCurrentBlockCount()); 295294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 296294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState()->BindExpr(CastE, result); 297ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(CastE, Pred, state); 298294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 299294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 300294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 301294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 302294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 303294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 304294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, 305294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 306294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 307aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder B(Pred, Dst, *currentBuilderContext); 308d231d0130a95336610ab9a42eaeb2cdac19992f3Anna Zaks 309294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const InitListExpr *ILE 310294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek = cast<InitListExpr>(CL->getInitializer()->IgnoreParens()); 311294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 312294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 313294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal ILV = state->getSVal(ILE); 314294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const LocationContext *LC = Pred->getLocationContext(); 315294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->bindCompoundLiteral(CL, LC, ILV); 316294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 317294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (CL->isLValue()) 318d231d0130a95336610ab9a42eaeb2cdac19992f3Anna Zaks B.generateNode(CL, Pred, state->BindExpr(CL, state->getLValue(CL, LC))); 319294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else 320d231d0130a95336610ab9a42eaeb2cdac19992f3Anna Zaks B.generateNode(CL, Pred, state->BindExpr(CL, ILV)); 321294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 322294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 323294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, 324294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 325294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 326294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: static variables may have an initializer, but the second 327294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // time a function is called those values may not be current. 328294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // This may need to be reflected in the CFG. 329294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 330294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Assumption: The CFG has one DeclStmt per Decl. 331294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Decl *D = *DS->decl_begin(); 332294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 333ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks if (!D || !isa<VarDecl>(D)) { 334ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks //TODO:AZ: remove explicit insertion after refactoring is done. 335ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Dst.insert(Pred); 336294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 337ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks } 338294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 339294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: all pre/post visits should eventually be handled by ::Visit(). 340294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet dstPreVisit; 341294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this); 342294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 343aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder B(dstPreVisit, Dst, *currentBuilderContext); 344294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const VarDecl *VD = dyn_cast<VarDecl>(D); 345294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end(); 346294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek I!=E; ++I) { 347294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *N = *I; 348294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = N->getState(); 349294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 350294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Decls without InitExpr are not initialized explicitly. 351294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const LocationContext *LC = N->getLocationContext(); 352294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 353294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (const Expr *InitEx = VD->getInit()) { 354294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal InitVal = state->getSVal(InitEx); 355294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 356294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // We bound the temp obj region to the CXXConstructExpr. Now recover 357294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // the lazy compound value when the variable is not a reference. 358294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (AMgr.getLangOptions().CPlusPlus && VD->getType()->isRecordType() && 359294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek !VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){ 360294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion()); 361294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(isa<nonloc::LazyCompoundVal>(InitVal)); 362294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 363294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 364294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Recover some path-sensitivity if a scalar value evaluated to 365294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // UnknownVal. 366294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if ((InitVal.isUnknown() || 367294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek !getConstraintManager().canReasonAbout(InitVal)) && 368294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek !VD->getType()->isReferenceType()) { 369294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx, 370ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks currentBuilderContext->getCurrentBlockCount()); 371294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 372d231d0130a95336610ab9a42eaeb2cdac19992f3Anna Zaks B.takeNodes(N); 37393bd5ca766c4d7906878f4ffe76ce1b2080e540bJordy Rose evalBind(Dst, DS, N, state->getLValue(VD, LC), InitVal, true); 374d231d0130a95336610ab9a42eaeb2cdac19992f3Anna Zaks B.addNodes(Dst); 375294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 376294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else { 377d231d0130a95336610ab9a42eaeb2cdac19992f3Anna Zaks B.generateNode(DS, N,state->bindDeclWithNoInit(state->getRegion(VD, LC))); 378294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 379294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 380294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 381294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 382294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, 383294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 384294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(B->getOpcode() == BO_LAnd || 385294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek B->getOpcode() == BO_LOr); 386ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 387aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 388294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 389294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal X = state->getSVal(B); 390294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(X.isUndef()); 391294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 392294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = (const Expr*) cast<UndefinedVal>(X).getData(); 393294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(Ex); 394294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 395294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Ex == B->getRHS()) { 396294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek X = state->getSVal(Ex); 397294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 398294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Handle undefined values. 399294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (X.isUndef()) { 4006b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks Bldr.generateNode(B, Pred, state->BindExpr(B, X)); 401294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 402294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 403294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 404294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek DefinedOrUnknownSVal XD = cast<DefinedOrUnknownSVal>(X); 405294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 406294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // We took the RHS. Because the value of the '&&' or '||' expression must 407294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // evaluate to 0 or 1, we must assume the value of the RHS evaluates to 0 408294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // or 1. Alternatively, we could take a lazy approach, and calculate this 409294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // value later when necessary. We don't have the machinery in place for 410294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // this right now, and since most logical expressions are used for branches, 411294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // the payoff is not likely to be large. Instead, we do eager evaluation. 412294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (const ProgramState *newState = state->assume(XD, true)) 4136b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks Bldr.generateNode(B, Pred, 414294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek newState->BindExpr(B, svalBuilder.makeIntVal(1U, B->getType()))); 415294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 416294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (const ProgramState *newState = state->assume(XD, false)) 4176b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks Bldr.generateNode(B, Pred, 418294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek newState->BindExpr(B, svalBuilder.makeIntVal(0U, B->getType()))); 419294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 420294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else { 421294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // We took the LHS expression. Depending on whether we are '&&' or 422294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // '||' we know what the value of the expression is via properties of 423294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // the short-circuiting. 424294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek X = svalBuilder.makeIntVal(B->getOpcode() == BO_LAnd ? 0U : 1U, 425294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek B->getType()); 4266b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks Bldr.generateNode(B, Pred, state->BindExpr(B, X)); 427294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 428294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 429294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 430294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitInitListExpr(const InitListExpr *IE, 431294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 432294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 433aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder B(Pred, Dst, *currentBuilderContext); 434294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 435294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 436294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek QualType T = getContext().getCanonicalType(IE->getType()); 437294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek unsigned NumInitElements = IE->getNumInits(); 438294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 439294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (T->isArrayType() || T->isRecordType() || T->isVectorType()) { 440294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList(); 441294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 442294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Handle base case where the initializer has no elements. 443294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // e.g: static int* myArray[] = {}; 444294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (NumInitElements == 0) { 445294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = svalBuilder.makeCompoundVal(T, vals); 4466b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks B.generateNode(IE, Pred, state->BindExpr(IE, V)); 447294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 448294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 449294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 450294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (InitListExpr::const_reverse_iterator it = IE->rbegin(), 451294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ei = IE->rend(); it != ei; ++it) { 452294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek vals = getBasicVals().consVals(state->getSVal(cast<Expr>(*it)), vals); 453294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 454294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 4556b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks B.generateNode(IE, Pred, 4566b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks state->BindExpr(IE, svalBuilder.makeCompoundVal(T, vals))); 457294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 458294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 459294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 460294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Loc::isLocType(T) || T->isIntegerType()) { 461294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(IE->getNumInits() == 1); 462294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *initEx = IE->getInit(0); 4636b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks B.generateNode(IE, Pred, state->BindExpr(IE, state->getSVal(initEx))); 464294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 465294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 466294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 467294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek llvm_unreachable("unprocessed InitListExpr type"); 468294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 469294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 470294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitGuardedExpr(const Expr *Ex, 471294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *L, 472294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *R, 473294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 474294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 475aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder B(Pred, Dst, *currentBuilderContext); 476294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 477294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 478294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal X = state->getSVal(Ex); 479294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert (X.isUndef()); 480294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *SE = (Expr*) cast<UndefinedVal>(X).getData(); 481294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(SE); 482294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek X = state->getSVal(SE); 483294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 484294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Make sure that we invalidate the previous binding. 4856b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks B.generateNode(Ex, Pred, state->BindExpr(Ex, X, true)); 486294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 487294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 488294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine:: 489294fd0a62b95f512637910bf85c7efa6c2354b50Ted KremenekVisitOffsetOfExpr(const OffsetOfExpr *OOE, 490294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst) { 491aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder B(Pred, Dst, *currentBuilderContext); 492294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Expr::EvalResult Res; 493294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (OOE->Evaluate(Res, getContext()) && Res.Val.isInt()) { 494294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const APSInt &IV = Res.Val.getInt(); 495294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType())); 496294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(OOE->getType()->isIntegerType()); 497294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(IV.isSigned() == OOE->getType()->isSignedIntegerOrEnumerationType()); 498294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal X = svalBuilder.makeIntVal(IV); 4996b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks B.generateNode(OOE, Pred, Pred->getState()->BindExpr(OOE, X)); 500294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 501294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: Handle the case where __builtin_offsetof is not a constant. 502294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 503294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 504294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 505294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine:: 506294fd0a62b95f512637910bf85c7efa6c2354b50Ted KremenekVisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, 507294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 508294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet &Dst) { 509aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 510294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 511294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek QualType T = Ex->getTypeOfArgument(); 512294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 513294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Ex->getKind() == UETT_SizeOf) { 514294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (!T->isIncompleteType() && !T->isConstantSizeType()) { 515294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(T->isVariableArrayType() && "Unknown non-constant-sized type."); 516294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 517540dda6f2e4982b3eab0300c804345f5b6104c11Ted Kremenek // FIXME: Add support for VLA type arguments and VLA expressions. 518294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // When that happens, we should probably refactor VLASizeChecker's code. 519294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 520294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 521294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else if (T->getAs<ObjCObjectType>()) { 522294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Some code tries to take the sizeof an ObjCObjectType, relying that 523294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // the compiler has laid out its representation. Just report Unknown 524294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // for these. 525294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek return; 526294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 527294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 528294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 529294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Expr::EvalResult Result; 530294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Ex->Evaluate(Result, getContext()); 531294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek CharUnits amt = CharUnits::fromQuantity(Result.Val.getInt().getZExtValue()); 532294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 533294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = Pred->getState(); 534294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(Ex, svalBuilder.makeIntVal(amt.getQuantity(), 535294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Ex->getType())); 536ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(Ex, Pred, state); 537294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 538294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 539294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekvoid ExprEngine::VisitUnaryOperator(const UnaryOperator* U, 540294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNode *Pred, 5418ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks ExplodedNodeSet &Dst) { 542aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 5438ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks bool IncDec = false; 544294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek switch (U->getOpcode()) { 545ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks default: { 546ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 5478ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks IncDec = true; 548ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNodeSet Tmp; 549ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks VisitIncrementDecrementOperator(U, Pred, Tmp); 550ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Tmp); 551ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks } 552294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek break; 553294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Real: { 554294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 555294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 556294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 557294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 558294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { 559294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 560294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: We don't have complex SValues yet. 561294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Ex->getType()->isAnyComplexType()) { 562294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Just report "Unknown." 563294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 564294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 565294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 566294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // For all other types, UO_Real is an identity operation. 567294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert (U->getType() == Ex->getType()); 568294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 5698ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks Bldr.generateNode(U, *I, state->BindExpr(U, state->getSVal(Ex))); 570294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 571294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 5728ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks break; 573294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 574294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 575294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Imag: { 576294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 577294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 578294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 579294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 580294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 581294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { 582294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: We don't have complex SValues yet. 583294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Ex->getType()->isAnyComplexType()) { 584294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Just report "Unknown." 585294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 586294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 587294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 588294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // For all other types, UO_Imag returns 0. 589294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 590294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal X = svalBuilder.makeZeroVal(Ex->getType()); 5918ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks Bldr.generateNode(U, *I, state->BindExpr(U, X)); 592294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 593294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 5948ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks break; 595294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 596294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 597294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Plus: 598294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(!U->isLValue()); 599294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FALL-THROUGH. 600294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Deref: 601294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_AddrOf: 602294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Extension: { 603294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 604294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Unary "+" is a no-op, similar to a parentheses. We still have places 605294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // where it may be a block-level expression, so we need to 606294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // generate an extra node that just propagates the value of the 607294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // subexpression. 608294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 609294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 610294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 611294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 612294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 613294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { 614294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 6158ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks Bldr.generateNode(U, *I, state->BindExpr(U, state->getSVal(Ex))); 616294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 617294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 6188ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks break; 619294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 620294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 621294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_LNot: 622294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Minus: 623294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Not: { 624294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert (!U->isLValue()); 625294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 626294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 627294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 628294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 629294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { 630294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 631294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 632294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Get the value of the subexpression. 633294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V = state->getSVal(Ex); 634294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 635294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (V.isUnknownOrUndef()) { 6368ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks Bldr.generateNode(U, *I, state->BindExpr(U, V)); 637294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 638294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 639294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 640294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek switch (U->getOpcode()) { 641294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek default: 642b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Invalid Opcode."); 643294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 644294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Not: 645294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: Do we need to handle promotions? 646294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, evalComplement(cast<NonLoc>(V))); 647294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek break; 648294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 649294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_Minus: 650294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // FIXME: Do we need to handle promotions? 651294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, evalMinus(cast<NonLoc>(V))); 652294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek break; 653294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 654294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek case UO_LNot: 655294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 656294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // C99 6.5.3.3: "The expression !E is equivalent to (0==E)." 657294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // 658294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Note: technically we do "E == 0", but this is the same in the 659294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // transfer functions as "0 == E". 660294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal Result; 661294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 662294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (isa<Loc>(V)) { 663294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Loc X = svalBuilder.makeNull(); 664294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Result = evalBinOp(state, BO_EQ, cast<Loc>(V), X, 665294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek U->getType()); 666294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 667294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else { 668294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType())); 669294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Result = evalBinOp(state, BO_EQ, cast<NonLoc>(V), X, 670294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek U->getType()); 671294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 672294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 673294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, Result); 674294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 675294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek break; 676294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 6778ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks Bldr.generateNode(U, *I, state); 678294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 6798ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks break; 680294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 681294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 6828ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks 6838ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks} 6848ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks 6858ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaksvoid ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U, 6868ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks ExplodedNode *Pred, 6878ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks ExplodedNodeSet &Dst) { 688294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Handle ++ and -- (both pre- and post-increment). 689294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert (U->isIncrementDecrementOp()); 690294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp; 691294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Expr *Ex = U->getSubExpr()->IgnoreParens(); 692294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Visit(Ex, Pred, Tmp); 693294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 694294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) { 695294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 696294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const ProgramState *state = (*I)->getState(); 697294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal loc = state->getSVal(Ex); 698294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 699294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Perform a load. 700294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ExplodedNodeSet Tmp2; 701294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek evalLoad(Tmp2, Ex, *I, state, loc); 702294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 703ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNodeSet Dst2; 704aa0aeb1cbe117db68d35700cb3a34aace0f99b99Anna Zaks StmtNodeBuilder Bldr(Tmp2, Dst2, *currentBuilderContext); 705294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek for (ExplodedNodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end();I2!=E2;++I2) { 706294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 707294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = (*I2)->getState(); 708294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal V2_untested = state->getSVal(Ex); 709294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 710294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Propagate unknown and undefined values. 711294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (V2_untested.isUnknownOrUndef()) { 712ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(U, *I2, state->BindExpr(U, V2_untested)); 713294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek continue; 714294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 715294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek DefinedSVal V2 = cast<DefinedSVal>(V2_untested); 716294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 717294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Handle all other values. 718294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add 719294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek : BO_Sub; 720294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 721294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // If the UnaryOperator has non-location type, use its type to create the 722294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // constant value. If the UnaryOperator has location type, create the 723294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // constant with int type and pointer width. 724294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal RHS; 725294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 726294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (U->getType()->isAnyPointerType()) 727294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek RHS = svalBuilder.makeArrayIndex(1); 728294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else 729294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek RHS = svalBuilder.makeIntVal(1, U->getType()); 730294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 731294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek SVal Result = evalBinOp(state, Op, V2, RHS, U->getType()); 732294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 733294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Conjure a new symbol if necessary to recover precision. 734294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)){ 735294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek DefinedOrUnknownSVal SymVal = 736294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek svalBuilder.getConjuredSymbolVal(NULL, Ex, 737ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks currentBuilderContext->getCurrentBlockCount()); 738294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Result = SymVal; 739294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 740294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // If the value is a location, ++/-- should always preserve 741294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // non-nullness. Check if the original value was non-null, and if so 742294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // propagate that constraint. 743294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (Loc::isLocType(U->getType())) { 744294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek DefinedOrUnknownSVal Constraint = 745294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType())); 746294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 747294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (!state->assume(Constraint, true)) { 748294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // It isn't feasible for the original value to be null. 749294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Propagate this constraint. 750294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek Constraint = svalBuilder.evalEQ(state, SymVal, 7518ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks svalBuilder.makeZeroVal(U->getType())); 752294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 753294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 754294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->assume(Constraint, false); 755294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek assert(state); 756294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 757294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 758294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 759294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 760294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Since the lvalue-to-rvalue conversion is explicit in the AST, 761294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // we bind an l-value if the operator is prefix and an lvalue (in C++). 762294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek if (U->isLValue()) 763294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, loc); 764294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek else 765294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek state = state->BindExpr(U, U->isPostfix() ? V2 : Result); 766294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek 767294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek // Perform the store. 768ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(*I2); 769ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNodeSet Dst4; 770ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks evalStore(Dst4, NULL, U, *I2, state, loc, Result); 771ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst4); 772294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 773ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Dst.insert(Dst2); 774294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek } 775294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek} 776