diff options
author | Tom Care <tom.care@uqconnect.edu.au> | 2010-09-02 17:49:20 +0000 |
---|---|---|
committer | Tom Care <tom.care@uqconnect.edu.au> | 2010-09-02 17:49:20 +0000 |
commit | 3f0ce9c3ab04d0edb8d28145a8feb4abaa8fb8e6 (patch) | |
tree | 524a69f98fd2b95a8c2ff853a9aef9e68b9aeacb /lib/Checker/BugReporterVisitors.cpp | |
parent | eede61a83e90f3cb03ef8665b67d648dccd6ce42 (diff) |
Improved error reporting in IdempotentOperationChecker
- SourceRange highlighting is only given for the relevant side of the operator (assignments give both)
- Added PostVisitBinaryOperator hook to retrieve the ExplodedNode for an operator
- Added a BugReporterVisitor to display the last store to every VarDecl in a Stmt
- Changed bug reporting to use the new BugReporterVisitor
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112839 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/BugReporterVisitors.cpp')
-rw-r--r-- | lib/Checker/BugReporterVisitors.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/Checker/BugReporterVisitors.cpp b/lib/Checker/BugReporterVisitors.cpp index cddc86ee9d..91cf349107 100644 --- a/lib/Checker/BugReporterVisitors.cpp +++ b/lib/Checker/BugReporterVisitors.cpp @@ -419,3 +419,40 @@ public: void clang::bugreporter::registerNilReceiverVisitor(BugReporterContext &BRC) { BRC.addVisitor(new NilReceiverVisitor()); } + +// Registers every VarDecl inside a Stmt with a last store vistor. +void clang::bugreporter::registerVarDeclsLastStore(BugReporterContext &BRC, + const void *stmt, + const ExplodedNode *N) { + const Stmt *S = static_cast<const Stmt *>(stmt); + + std::deque<const Stmt *> WorkList; + + WorkList.push_back(S); + + while (!WorkList.empty()) { + const Stmt *Head = WorkList.front(); + WorkList.pop_front(); + + GRStateManager &StateMgr = BRC.getStateManager(); + const GRState *state = N->getState(); + + if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Head)) { + if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) { + const VarRegion *R = + StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext()); + + // What did we load? + SVal V = state->getSVal(S); + + if (isa<loc::ConcreteInt>(V) || isa<nonloc::ConcreteInt>(V)) { + ::registerFindLastStore(BRC, R, V); + } + } + } + + for (Stmt::const_child_iterator I = Head->child_begin(); + I != Head->child_end(); ++I) + WorkList.push_back(*I); + } +} |