23 using namespace clang;
28 class UndefBranchChecker :
public Checker<check::BranchCondition> {
29 mutable std::unique_ptr<BuiltinBug> BT;
31 struct FindUndefExpr {
36 : St(
std::move(S)), LCtx(L) {}
38 const Expr *FindExpr(
const Expr *Ex) {
39 if (!MatchesCriteria(Ex))
43 if (
const Expr *ExI = dyn_cast_or_null<Expr>(SubStmt))
44 if (
const Expr *E2 = FindExpr(ExI))
50 bool MatchesCriteria(
const Expr *Ex) {
51 return St->getSVal(Ex, LCtx).isUndef();
56 void checkBranchCondition(
const Stmt *Condition, CheckerContext &Ctx)
const;
61 void UndefBranchChecker::checkBranchCondition(
const Stmt *Condition,
62 CheckerContext &Ctx)
const {
64 if (isa<ObjCForCollectionStmt>(Condition))
66 SVal
X = Ctx.getSVal(Condition);
70 ExplodedNode *N = Ctx.generateErrorNode();
73 BT.reset(
new BuiltinBug(
74 this,
"Branch condition evaluates to a garbage value"));
90 assert (!N->pred_empty());
91 const Expr *Ex = cast<Expr>(Condition);
92 ExplodedNode *PrevN = *N->pred_begin();
97 if (PS->getStmt() == Ex)
98 St = PrevN->getState();
100 FindUndefExpr FindIt(St, Ctx.getLocationContext());
101 Ex = FindIt.FindExpr(Ex);
104 auto R = std::make_unique<PathSensitiveBugReport>(
105 *BT, BT->getDescription(), N);
109 Ctx.emitReport(std::move(R));
114 void ento::registerUndefBranchChecker(CheckerManager &mgr) {
115 mgr.registerChecker<UndefBranchChecker>();
118 bool ento::shouldRegisterUndefBranchChecker(
const CheckerManager &mgr) {