21 using namespace clang;
26 class UndefBranchChecker :
public Checker<check::BranchCondition> {
27 mutable std::unique_ptr<BuiltinBug> BT;
29 struct FindUndefExpr {
34 : St(
std::move(S)), LCtx(L) {}
36 const Expr *FindExpr(
const Expr *Ex) {
37 if (!MatchesCriteria(Ex))
41 if (
const Expr *ExI = dyn_cast_or_null<Expr>(SubStmt))
42 if (
const Expr *E2 = FindExpr(ExI))
48 bool MatchesCriteria(
const Expr *Ex) {
49 return St->getSVal(Ex, LCtx).isUndef();
54 void checkBranchCondition(
const Stmt *Condition, CheckerContext &Ctx)
const;
59 void UndefBranchChecker::checkBranchCondition(
const Stmt *Condition,
60 CheckerContext &Ctx)
const {
61 SVal
X = Ctx.getSVal(Condition);
65 ExplodedNode *N = Ctx.generateErrorNode();
68 BT.reset(
new BuiltinBug(
69 this,
"Branch condition evaluates to a garbage value"));
85 assert (!N->pred_empty());
86 const Expr *Ex = cast<Expr>(Condition);
87 ExplodedNode *PrevN = *N->pred_begin();
92 if (PS->getStmt() == Ex)
93 St = PrevN->getState();
95 FindUndefExpr FindIt(St, Ctx.getLocationContext());
96 Ex = FindIt.FindExpr(Ex);
99 auto R = llvm::make_unique<BugReport>(*BT, BT->getDescription(), N);
100 bugreporter::trackExpressionValue(N, Ex, *R);
101 R->addRange(Ex->getSourceRange());
103 Ctx.emitReport(std::move(R));
108 void ento::registerUndefBranchChecker(CheckerManager &mgr) {
109 mgr.registerChecker<UndefBranchChecker>();
112 bool ento::shouldRegisterUndefBranchChecker(
const LangOptions &LO) {
Stmt - This represents one statement.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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...