}
};
-class VISIBILITY_HIDDEN ArgReport : public BuiltinBugReport {
- const Stmt *Arg;
-public:
- ArgReport(BugType& bt, const char* desc, ExplodedNode *n,
- const Stmt *arg)
- : BuiltinBugReport(bt, desc, n), Arg(arg) {}
-
- ArgReport(BugType& bt, const char *shortDesc, const char *desc,
- ExplodedNode *n, const Stmt *arg)
- : BuiltinBugReport(bt, shortDesc, desc, n), Arg(arg) {}
-
- const Stmt *getArg() const { return Arg; }
-};
-
-class VISIBILITY_HIDDEN UndefBranch : public BuiltinBug {
- struct VISIBILITY_HIDDEN FindUndefExpr {
- GRStateManager& VM;
- const GRState* St;
-
- FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}
-
- Expr* FindExpr(Expr* Ex) {
- if (!MatchesCriteria(Ex))
- return 0;
-
- for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end();I!=E;++I)
- if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
- Expr* E2 = FindExpr(ExI);
- if (E2) return E2;
- }
-
- return Ex;
- }
-
- bool MatchesCriteria(Expr* Ex) { return St->getSVal(Ex).isUndef(); }
- };
-
-public:
- UndefBranch(GRExprEngine *eng)
- : BuiltinBug(eng,"Use of garbage value",
- "Branch condition evaluates to an undefined or garbage value")
- {}
-
- void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
- for (GRExprEngine::undef_branch_iterator I=Eng.undef_branches_begin(),
- E=Eng.undef_branches_end(); I!=E; ++I) {
-
- // 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>((*I)->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 (!(*I)->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 *N = *(*I)->pred_begin();
- ProgramPoint P = N->getLocation();
- const GRState* St = (*I)->getState();
-
- if (PostStmt* PS = dyn_cast<PostStmt>(&P))
- if (PS->getStmt() == Ex)
- St = N->getState();
-
- FindUndefExpr FindIt(Eng.getStateManager(), St);
- Ex = FindIt.FindExpr(Ex);
-
- ArgReport *R = new ArgReport(*this, desc.c_str(), *I, Ex);
- R->addRange(Ex->getSourceRange());
- BR.EmitReport(R);
- }
- }
-
- void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode* N,
- BuiltinBugReport *R) {
- registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
- N);
- }
-};
-
} // end clang namespace
//===----------------------------------------------------------------------===//
class VISIBILITY_HIDDEN UndefBranchChecker : public Checker {
BuiltinBug *BT;
+
+ struct VISIBILITY_HIDDEN FindUndefExpr {
+ GRStateManager& VM;
+ const GRState* St;
+
+ FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}
+
+ Expr* FindExpr(Expr* Ex) {
+ if (!MatchesCriteria(Ex))
+ return 0;
+
+ for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end();I!=E;++I)
+ if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
+ Expr* E2 = FindExpr(ExI);
+ if (E2) return E2;
+ }
+
+ return Ex;
+ }
+
+ bool MatchesCriteria(Expr* Ex) { return St->getSVal(Ex).isUndef(); }
+ };
+
public:
UndefBranchChecker() : BT(0) {}
static void *getTag();
EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getDescription(),N);
R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
Condition);
+
+ // 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);
+ R->addRange(Ex->getSourceRange());
+
Eng.getBugReporter().EmitReport(R);
}