SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, const GRState *state, BinaryOperator::Opcode Op, Loc L, NonLoc R) { // Special case: 'R' is an integer that has the same width as a pointer and // we are using the integer location in a comparison. Normally this cannot be // triggered, but transfer functions like those for OSCommpareAndSwapBarrier32 // can generate comparisons that trigger this code. // FIXME: Are all locations guaranteed to have pointer width? if (BinaryOperator::isEqualityOp(Op)) { if (nonloc::ConcreteInt *RInt = dyn_cast<nonloc::ConcreteInt>(&R)) { const llvm::APSInt *X = &RInt->getValue(); ASTContext &C = Eng.getContext(); if (C.getTypeSize(C.VoidPtrTy) == X->getBitWidth()) { // Convert the signedness of the integer (if necessary). if (X->isSigned()) X = &Eng.getBasicVals().getValue(*X, true); return EvalBinOp(Eng, Op, L, loc::ConcreteInt(*X)); } } } // Delegate pointer arithmetic to store manager. return Eng.getStoreManager().EvalBinOp(state, Op, L, R); }
void clang::RegisterNSAutoreleasePoolChecks(GRExprEngine &Eng) { ASTContext &Ctx = Eng.getContext(); if (Ctx.getLangOptions().getGCMode() != LangOptions::NonGC) { Eng.registerCheck(new NSAutoreleasePoolChecker(GetNullarySelector("release", Ctx))); } }
SVal GRSimpleVals::EvalCast(GRExprEngine& Eng, Loc X, QualType T) { // Casts from pointers -> pointers, just return the lval. // // Casts from pointers -> references, just return the lval. These // can be introduced by the frontend for corner cases, e.g // casting from va_list* to __builtin_va_list&. // assert (!X.isUnknownOrUndef()); if (Loc::IsLocType(T) || T->isReferenceType()) return X; // FIXME: Handle transparent unions where a value can be "transparently" // lifted into a union type. if (T->isUnionType()) return UnknownVal(); assert (T->isIntegerType()); BasicValueFactory& BasicVals = Eng.getBasicVals(); unsigned BitWidth = Eng.getContext().getTypeSize(T); if (!isa<loc::ConcreteInt>(X)) return nonloc::LocAsInteger::Make(BasicVals, X, BitWidth); llvm::APSInt V = cast<loc::ConcreteInt>(X).getValue(); V.setIsUnsigned(T->isUnsignedIntegerType() || Loc::IsLocType(T)); V.extOrTrunc(BitWidth); return nonloc::ConcreteInt(BasicVals.getValue(V)); }
SVal GRSimpleVals::EvalEquality(GRExprEngine& Eng, Loc L, Loc R, bool isEqual) { BasicValueFactory& BasicVals = Eng.getBasicVals(); switch (L.getSubKind()) { default: assert(false && "EQ/NE not implemented for this Loc."); return UnknownVal(); case loc::ConcreteIntKind: if (isa<loc::ConcreteInt>(R)) { bool b = cast<loc::ConcreteInt>(L).getValue() == cast<loc::ConcreteInt>(R).getValue(); // Are we computing '!='? Flip the result. if (!isEqual) b = !b; return NonLoc::MakeIntTruthVal(BasicVals, b); } else if (SymbolRef Sym = R.getAsSymbol()) { const SymIntExpr * SE = Eng.getSymbolManager().getSymIntExpr(Sym, isEqual ? BinaryOperator::EQ : BinaryOperator::NE, cast<loc::ConcreteInt>(L).getValue(), Eng.getContext().IntTy); return nonloc::SymExprVal(SE); } break; case loc::MemRegionKind: { if (SymbolRef LSym = L.getAsLocSymbol()) { if (isa<loc::ConcreteInt>(R)) { const SymIntExpr *SE = Eng.getSymbolManager().getSymIntExpr(LSym, isEqual ? BinaryOperator::EQ : BinaryOperator::NE, cast<loc::ConcreteInt>(R).getValue(), Eng.getContext().IntTy); return nonloc::SymExprVal(SE); } } } // Fall-through. case loc::GotoLabelKind: return NonLoc::MakeIntTruthVal(BasicVals, isEqual ? L == R : L != R); } return NonLoc::MakeIntTruthVal(BasicVals, isEqual ? false : true); }
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 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))); }
SVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLoc X) { switch (X.getSubKind()) { case nonloc::ConcreteIntKind: return cast<nonloc::ConcreteInt>(X).EvalComplement(Eng.getBasicVals()); default: return UnknownVal(); } }
SVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLoc X){ switch (X.getSubKind()) { case nonloc::ConcreteIntKind: return cast<nonloc::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U); default: return UnknownVal(); } }
SVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLoc X, QualType T) { if (!isa<nonloc::ConcreteInt>(X)) return UnknownVal(); bool isLocType = Loc::IsLocType(T); // Only handle casts from integers to integers. if (!isLocType && !T->isIntegerType()) return UnknownVal(); BasicValueFactory& BasicVals = Eng.getBasicVals(); llvm::APSInt V = cast<nonloc::ConcreteInt>(X).getValue(); V.setIsUnsigned(T->isUnsignedIntegerType() || Loc::IsLocType(T)); V.extOrTrunc(Eng.getContext().getTypeSize(T)); if (isLocType) return loc::ConcreteInt(BasicVals.getValue(V)); else return nonloc::ConcreteInt(BasicVals.getValue(V)); }
void CallInliner::EvalCall(ExplodedNodeSet& Dst, GRExprEngine& Engine, GRStmtNodeBuilder& Builder, CallExpr* CE, SVal L, ExplodedNode* Pred) { FunctionDecl const *FD = L.getAsFunctionDecl(); if (!FD) return; // GRExprEngine is responsible for the autotransition. // Make a new LocationContext. StackFrameContext const *LocCtx = Engine.getAnalysisManager().getStackFrame(FD, Pred->getLocationContext(), CE); CFGBlock const *Entry = &(LocCtx->getCFG()->getEntry()); assert (Entry->empty() && "Entry block must be empty."); assert (Entry->succ_size() == 1 && "Entry block must have 1 successor."); // Get the solitary successor. CFGBlock const *SuccB = *(Entry->succ_begin()); // Construct an edge representing the starting location in the function. BlockEdge Loc(Entry, SuccB, LocCtx); GRState const *state = Builder.GetState(Pred); state = Engine.getStoreManager().EnterStackFrame(state, LocCtx); bool isNew; ExplodedNode *SuccN = Engine.getGraph().getNode(Loc, state, &isNew); SuccN->addPredecessor(Pred, Engine.getGraph()); Builder.Deferred.erase(Pred); // This is a hack. We really should not use the GRStmtNodeBuilder. if (isNew) Builder.getWorkList()->Enqueue(SuccN); Builder.HasGeneratedNode = true; }
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); }
void clang::RegisterAppleChecks(GRExprEngine& Eng, const Decl &D) { ASTContext& Ctx = Eng.getContext(); BugReporter &BR = Eng.getBugReporter(); Eng.AddCheck(CreateBasicObjCFoundationChecks(Ctx, BR), Stmt::ObjCMessageExprClass); Eng.AddCheck(CreateAuditCFNumberCreate(Ctx, BR), Stmt::CallExprClass); Eng.AddCheck(CreateAuditCFRetainRelease(Ctx, BR), Stmt::CallExprClass); RegisterNSErrorChecks(BR, Eng, D); RegisterNSAutoreleasePoolChecks(Eng); Eng.registerCheck(new ClassReleaseChecker(Ctx)); }
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 clang::RegisterAdjustedReturnValueChecker(GRExprEngine &Eng) { Eng.registerCheck(new AdjustedReturnValueChecker()); }
void clang::RegisterVLASizeChecker(GRExprEngine &Eng) { Eng.registerCheck(new VLASizeChecker()); }
void clang::RegisterFixedAddressChecker(GRExprEngine &Eng) { Eng.registerCheck(new FixedAddressChecker()); }
void clang::RegisterReturnUndefChecker(GRExprEngine &Eng) { Eng.registerCheck(new ReturnUndefChecker()); }
void clang::RegisterDivZeroChecker(GRExprEngine &Eng) { Eng.registerCheck(new DivZeroChecker()); }
void clang::RegisterUndefinedArraySubscriptChecker(GRExprEngine &Eng) { Eng.registerCheck(new UndefinedArraySubscriptChecker()); }
void clang::RegisterAttrNonNullChecker(GRExprEngine &Eng) { Eng.registerCheck(new AttrNonNullChecker()); }
void clang::RegisterOSAtomicChecker(GRExprEngine &Eng) { Eng.registerCheck(new OSAtomicChecker()); }
void clang::RegisterCallInliner(GRExprEngine &Eng) { Eng.registerCheck(new CallInliner()); }
void clang::RegisterDereferenceChecker(GRExprEngine &Eng) { Eng.registerCheck(new DereferenceChecker()); }
void clang::RegisterUndefBranchChecker(GRExprEngine &Eng) { Eng.registerCheck(new UndefBranchChecker()); }
void clang::RegisterMacOSXAPIChecker(GRExprEngine &Eng) { if (Eng.getContext().Target.getTriple().getVendor() == llvm::Triple::Apple) Eng.registerCheck(new MacOSXAPIChecker()); }
SVal GRSimpleVals::DetermEvalBinOpNN(GRExprEngine& Eng, BinaryOperator::Opcode Op, NonLoc L, NonLoc R, QualType T) { BasicValueFactory& BasicVals = Eng.getBasicVals(); unsigned subkind = L.getSubKind(); while (1) { switch (subkind) { default: return UnknownVal(); case nonloc::LocAsIntegerKind: { Loc LL = cast<nonloc::LocAsInteger>(L).getLoc(); switch (R.getSubKind()) { case nonloc::LocAsIntegerKind: return EvalBinOp(Eng, Op, LL, cast<nonloc::LocAsInteger>(R).getLoc()); case nonloc::ConcreteIntKind: { // Transform the integer into a location and compare. ASTContext& Ctx = Eng.getContext(); llvm::APSInt V = cast<nonloc::ConcreteInt>(R).getValue(); V.setIsUnsigned(true); V.extOrTrunc(Ctx.getTypeSize(Ctx.VoidPtrTy)); return EvalBinOp(Eng, Op, LL, loc::ConcreteInt(BasicVals.getValue(V))); } default: switch (Op) { case BinaryOperator::EQ: return NonLoc::MakeIntTruthVal(BasicVals, false); case BinaryOperator::NE: return NonLoc::MakeIntTruthVal(BasicVals, true); default: // This case also handles pointer arithmetic. return UnknownVal(); } } } case nonloc::SymExprValKind: { // Logical not? if (!(Op == BinaryOperator::EQ && R.isZeroConstant())) return UnknownVal(); const SymExpr &SE=*cast<nonloc::SymExprVal>(L).getSymbolicExpression(); // Only handle ($sym op constant) for now. if (const SymIntExpr *E = dyn_cast<SymIntExpr>(&SE)) { BinaryOperator::Opcode Opc = E->getOpcode(); if (Opc < BinaryOperator::LT || Opc > BinaryOperator::NE) return UnknownVal(); // For comparison operators, translate the constraint by // changing the opcode. int idx = (unsigned) Opc - (unsigned) BinaryOperator::LT; assert (idx >= 0 && (unsigned) idx < sizeof(LNotOpMap)/sizeof(unsigned char)); Opc = (BinaryOperator::Opcode) LNotOpMap[idx]; assert(E->getType(Eng.getContext()) == T); E = Eng.getSymbolManager().getSymIntExpr(E->getLHS(), Opc, E->getRHS(), T); return nonloc::SymExprVal(E); } return UnknownVal(); } case nonloc::ConcreteIntKind: if (isa<nonloc::ConcreteInt>(R)) { const nonloc::ConcreteInt& L_CI = cast<nonloc::ConcreteInt>(L); const nonloc::ConcreteInt& R_CI = cast<nonloc::ConcreteInt>(R); return L_CI.EvalBinOp(BasicVals, Op, R_CI); } else { subkind = R.getSubKind(); NonLoc tmp = R; R = L; L = tmp; // Swap the operators. switch (Op) { case BinaryOperator::LT: Op = BinaryOperator::GT; break; case BinaryOperator::GT: Op = BinaryOperator::LT; break; case BinaryOperator::LE: Op = BinaryOperator::GE; break; case BinaryOperator::GE: Op = BinaryOperator::LE; break; default: break; } continue; } case nonloc::SymbolValKind: if (isa<nonloc::ConcreteInt>(R)) { ValueManager &ValMgr = Eng.getValueManager(); return ValMgr.makeNonLoc(cast<nonloc::SymbolVal>(L).getSymbol(), Op, cast<nonloc::ConcreteInt>(R).getValue(), T); } else return UnknownVal(); } } }
void clang::RegisterReturnPointerRangeChecker(GRExprEngine &Eng) { Eng.registerCheck(new ReturnPointerRangeChecker()); }
void clang::RegisterCastToStructChecker(GRExprEngine &Eng) { Eng.registerCheck(new CastToStructChecker()); }