void GRTransferFuncs::EvalBinOpNN(GRStateSet& OStates, GRExprEngine& Eng, const GRState *St, Expr* Ex, BinaryOperator::Opcode Op, NonLoc L, NonLoc R, QualType T) { OStates.Add(Eng.getStateManager().BindExpr(St, Ex, DetermEvalBinOpNN(Eng, Op, L, R, T))); }
void UndefBranchChecker::VisitBranchCondition(GRBranchNodeBuilder &Builder, GRExprEngine &Eng, Stmt *Condition, void *tag) { const GRState *state = Builder.getState(); SVal X = state->getSVal(Condition); if (X.isUndef()) { ExplodedNode *N = Builder.generateNode(state, true); if (N) { N->markAsSink(); if (!BT) BT = new BuiltinBug("Branch condition evaluates to a garbage value"); // What's going on here: we want to highlight the subexpression of the // condition that is the most likely source of the "uninitialized // branch condition." We do a recursive walk of the condition's // subexpressions and roughly look for the most nested subexpression // that binds to Undefined. We then highlight that expression's range. BlockEdge B = cast<BlockEdge>(N->getLocation()); Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition()); assert (Ex && "Block must have a terminator."); // Get the predecessor node and check if is a PostStmt with the Stmt // being the terminator condition. We want to inspect the state // of that node instead because it will contain main information about // the subexpressions. assert (!N->pred_empty()); // Note: any predecessor will do. They should have identical state, // since all the BlockEdge did was act as an error sink since the value // had to already be undefined. ExplodedNode *PrevN = *N->pred_begin(); ProgramPoint P = PrevN->getLocation(); const GRState* St = N->getState(); if (PostStmt* PS = dyn_cast<PostStmt>(&P)) if (PS->getStmt() == Ex) St = PrevN->getState(); FindUndefExpr FindIt(Eng.getStateManager(), St); Ex = FindIt.FindExpr(Ex); // Emit the bug report. EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getDescription(),N); R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, Ex); R->addRange(Ex->getSourceRange()); Eng.getBugReporter().EmitReport(R); } Builder.markInfeasible(true); Builder.markInfeasible(false); } }
void GRSimpleVals::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst, GRExprEngine& Eng, GRStmtNodeBuilder<GRState>& Builder, ObjCMessageExpr* ME, ExplodedNode<GRState>* Pred) { // The basic transfer function logic for message expressions does nothing. // We just invalidate all arguments passed in by references. GRStateManager& StateMgr = Eng.getStateManager(); const GRState* St = Builder.GetState(Pred); for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end(); I != E; ++I) { SVal V = StateMgr.GetSVal(St, *I); if (isa<Loc>(V)) St = StateMgr.BindLoc(St, cast<Loc>(V), UnknownVal()); } Builder.MakeNode(Dst, ME, Pred, St); }
void GRSimpleVals::EvalCall(ExplodedNodeSet<GRState>& Dst, GRExprEngine& Eng, GRStmtNodeBuilder<GRState>& Builder, CallExpr* CE, SVal L, ExplodedNode<GRState>* Pred) { GRStateManager& StateMgr = Eng.getStateManager(); const GRState* St = Builder.GetState(Pred); // Invalidate all arguments passed in by reference (Locs). for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) { SVal V = StateMgr.GetSVal(St, *I); if (isa<loc::MemRegionVal>(V)) St = StateMgr.BindLoc(St, cast<Loc>(V), UnknownVal()); else if (isa<nonloc::LocAsInteger>(V)) St = StateMgr.BindLoc(St, cast<nonloc::LocAsInteger>(V).getLoc(), UnknownVal()); } // Make up a symbol for the return value of this function. // FIXME: We eventually should handle structs and other compound types // that are returned by value. QualType T = CE->getType(); if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) { unsigned Count = Builder.getCurrentBlockCount(); SVal X = Eng.getValueManager().getConjuredSymbolVal(CE, Count); St = StateMgr.BindExpr(St, CE, X, Eng.getCFG().isBlkExpr(CE), false); } Builder.MakeNode(Dst, CE, Pred, St); }