diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-08-29 02:11:01 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-08-29 02:11:01 +0000 |
commit | 9a5bca34ca09d3a88c2ccb4f53b27cf99de4f182 (patch) | |
tree | 6c970cf343368cccd9e6ca4a278fbe814597e72f /lib/Analysis/GRExprEngineInternalChecks.cpp | |
parent | 8c57a66a2aa59939a902ffa8c4ad0ddd5b949a21 (diff) |
Refactor undefined argument checking into a Checker.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80417 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngineInternalChecks.cpp')
-rw-r--r-- | lib/Analysis/GRExprEngineInternalChecks.cpp | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/lib/Analysis/GRExprEngineInternalChecks.cpp b/lib/Analysis/GRExprEngineInternalChecks.cpp index 1b2fd1cb9f..35ca0c5dfb 100644 --- a/lib/Analysis/GRExprEngineInternalChecks.cpp +++ b/lib/Analysis/GRExprEngineInternalChecks.cpp @@ -245,7 +245,12 @@ public: ExplodedNode *n, const Stmt *arg) : BuiltinBugReport(bt, shortDesc, desc, n), Arg(arg) {} - const Stmt *getArg() const { return Arg; } + const Stmt *getArg() const { return Arg; } + + void registerInitialVisitors(BugReporterContext& BRC, + const ExplodedNode* N) { + registerTrackNullOrUndefValue(BRC, getArg(), N); + } }; class VISIBILITY_HIDDEN BadArg : public BuiltinBug { @@ -629,6 +634,44 @@ public: }; } // end anonymous namespace +// Undefined arguments checking. +namespace { +class VISIBILITY_HIDDEN CheckUndefinedArg + : public CheckerVisitor<CheckUndefinedArg> { + + BugType *BT; + +public: + CheckUndefinedArg() : BT(0) {} + ~CheckUndefinedArg() {} + + const void *getTag() { + static int x = 0; + return &x; + } + + void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE); +}; + +void CheckUndefinedArg::PreVisitCallExpr(CheckerContext &C, const CallExpr *CE){ + for (CallExpr::const_arg_iterator I = CE->arg_begin(), E = CE->arg_end(); + I != E; ++I) { + if (C.getState()->getSVal(*I).isUndef()) { + if (ExplodedNode *ErrorNode = C.generateNode(CE, C.getState(), true)) { + if (!BT) + BT = new BugType("Uninitialized argument.", "Logic Errors."); + // Generate a report for this bug. + ArgReport *Report = new ArgReport(*BT, + "Pass-by-value argument in function call is undefined.", + ErrorNode, *I); + Report->addRange((*I)->getSourceRange()); + C.EmitReport(Report); + } + } + } +} + +} //===----------------------------------------------------------------------===// // Check registration. //===----------------------------------------------------------------------===// @@ -647,7 +690,6 @@ void GRExprEngine::RegisterInternalChecks() { BR.Register(new BadCall(this)); BR.Register(new RetStack(this)); BR.Register(new RetUndef(this)); - BR.Register(new BadArg(this)); BR.Register(new BadMsgExprArg(this)); BR.Register(new BadReceiver(this)); BR.Register(new OutOfBoundMemoryAccess(this)); @@ -661,4 +703,5 @@ void GRExprEngine::RegisterInternalChecks() { // automatically. Note that the check itself is owned by the GRExprEngine // object. registerCheck(new CheckAttrNonNull()); + registerCheck(new CheckUndefinedArg()); } |