summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-04-20 21:59:08 +0000
committerAnna Zaks <ganna@apple.com>2012-04-20 21:59:08 +0000
commit7e53bd6fb01b062ece426252fb94c76bcce58941 (patch)
tree24ece716d1b30e1d35bfc9196ce924f3c387e94f /clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
parent20492bf0b601f9480e05f3d39820d4c93587fa7d (diff)
downloadbcm5719-llvm-7e53bd6fb01b062ece426252fb94c76bcce58941.tar.gz
bcm5719-llvm-7e53bd6fb01b062ece426252fb94c76bcce58941.zip
[analyzer] Run remove dead bindings right before leaving a function.
This is needed to ensure that we always report issues in the correct function. For example, leaks are identified when we call remove dead bindings. In order to make sure we report a callee's leak in the callee, we have to run the operation in the callee's context. This change required quite a bit of infrastructure work since: - We used to only run remove dead bindings before a given statement; here we need to run it after the last statement in the function. For this, we added additional Program Point and special mode in the SymbolReaper to remove all symbols in context lower than the current one. - The call exit operation turned into a sequence of nodes, which are now guarded by CallExitBegin and CallExitEnd nodes for clarity and convenience. (Sorry for the long diff.) llvm-svn: 155244
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/CheckerManager.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/CheckerManager.cpp17
1 files changed, 11 insertions, 6 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
index 0bcc343fba8..8a6ea1d0f80 100644
--- a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -381,21 +381,25 @@ namespace {
SymbolReaper &SR;
const Stmt *S;
ExprEngine &Eng;
+ ProgramPoint::Kind ProgarmPointKind;
CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
CheckDeadSymbolsContext(const CheckersTy &checkers, SymbolReaper &sr,
- const Stmt *s, ExprEngine &eng)
- : Checkers(checkers), SR(sr), S(s), Eng(eng) { }
+ const Stmt *s, ExprEngine &eng,
+ ProgramPoint::Kind K)
+ : Checkers(checkers), SR(sr), S(s), Eng(eng), ProgarmPointKind(K) { }
void runChecker(CheckerManager::CheckDeadSymbolsFunc checkFn,
NodeBuilder &Bldr, ExplodedNode *Pred) {
- ProgramPoint::Kind K = ProgramPoint::PostPurgeDeadSymbolsKind;
- const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
+ const ProgramPoint &L = ProgramPoint::getProgramPoint(S, ProgarmPointKind,
Pred->getLocationContext(), checkFn.Checker);
CheckerContext C(Bldr, Eng, Pred, L);
+ // Note, do not pass the statement to the checkers without letting them
+ // differentiate if we ran remove dead bindings before or after the
+ // statement.
checkFn(SR, C);
}
};
@@ -406,8 +410,9 @@ void CheckerManager::runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
SymbolReaper &SymReaper,
const Stmt *S,
- ExprEngine &Eng) {
- CheckDeadSymbolsContext C(DeadSymbolsCheckers, SymReaper, S, Eng);
+ ExprEngine &Eng,
+ ProgramPoint::Kind K) {
+ CheckDeadSymbolsContext C(DeadSymbolsCheckers, SymReaper, S, Eng, K);
expandGraphWithCheckers(C, Dst, Src);
}
OpenPOWER on IntegriCloud