22 using namespace clang;
27 class UndefBranchChecker :
public Checker<check::BranchCondition> {
28 mutable std::unique_ptr<BuiltinBug> BT;
30 struct FindUndefExpr {
35 : St(
std::move(S)), LCtx(L) {}
37 const Expr *FindExpr(
const Expr *Ex) {
38 if (!MatchesCriteria(Ex))
42 if (
const Expr *ExI = dyn_cast_or_null<Expr>(SubStmt))
43 if (
const Expr *E2 = FindExpr(ExI))
49 bool MatchesCriteria(
const Expr *Ex) {
50 return St->getSVal(Ex, LCtx).isUndef();
55 void checkBranchCondition(
const Stmt *Condition, CheckerContext &Ctx)
const;
60 void UndefBranchChecker::checkBranchCondition(
const Stmt *Condition,
61 CheckerContext &Ctx)
const {
62 SVal
X = Ctx.getSVal(Condition);
66 ExplodedNode *N = Ctx.generateErrorNode();
69 BT.reset(
new BuiltinBug(
70 this,
"Branch condition evaluates to a garbage value"));
86 assert (!N->pred_empty());
87 const Expr *Ex = cast<Expr>(Condition);
88 ExplodedNode *PrevN = *N->pred_begin();
93 if (PS->getStmt() == Ex)
94 St = PrevN->getState();
96 FindUndefExpr FindIt(St, Ctx.getLocationContext());
97 Ex = FindIt.FindExpr(Ex);
100 auto R = llvm::make_unique<BugReport>(*BT, BT->getDescription(), N);
101 bugreporter::trackExpressionValue(N, Ex, *R);
102 R->addRange(Ex->getSourceRange());
104 Ctx.emitReport(std::move(R));
109 void ento::registerUndefBranchChecker(CheckerManager &mgr) {
110 mgr.registerChecker<UndefBranchChecker>();
Stmt - This represents one statement.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
This represents one expression.
Dataflow Directional Tag Classes.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...