diff options
author | Anna Zaks <ganna@apple.com> | 2013-03-28 23:15:29 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2013-03-28 23:15:29 +0000 |
commit | 41988f331a74a72cf243a2a68ffb56418e9a174e (patch) | |
tree | ab722ed0a8b1c5b6686d45cf7765b0e85564d7a8 /lib/StaticAnalyzer/Core/CheckerManager.cpp | |
parent | aabb4c5eacca6d78ef778f33ec5cd4c755d71a39 (diff) |
[analyzer] Add support for escape of const pointers and use it to allow “newed” pointers to escape
Add a new callback that notifies checkers when a const pointer escapes. Currently, this only works
for const pointers passed as a top level parameter into a function. We need to differentiate the const
pointers escape from regular escape since the content pointed by const pointer will not change;
if it’s a file handle, a file cannot be closed; but delete is allowed on const pointers.
This should suppress several false positives reported by the NewDelete checker on llvm codebase.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178310 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/CheckerManager.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/CheckerManager.cpp | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp index a383799788..8adf3262b3 100644 --- a/lib/StaticAnalyzer/Core/CheckerManager.cpp +++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp @@ -489,19 +489,19 @@ ProgramStateRef CheckerManager::runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, - PointerEscapeKind Kind) { + PointerEscapeKind Kind, + bool IsConst) { assert((Call != NULL || (Kind != PSK_DirectEscapeOnCall && Kind != PSK_IndirectEscapeOnCall)) && "Call must not be NULL when escaping on call"); - - for (unsigned i = 0, e = PointerEscapeCheckers.size(); i != e; ++i) { - // If any checker declares the state infeasible (or if it starts that way), - // bail out. - if (!State) - return NULL; - State = PointerEscapeCheckers[i](State, Escaped, Call, Kind); - } + for (unsigned i = 0, e = PointerEscapeCheckers.size(); i != e; ++i) { + // If any checker declares the state infeasible (or if it starts that + // way), bail out. + if (!State) + return NULL; + State = PointerEscapeCheckers[i](State, Escaped, Call, Kind, IsConst); + } return State; } @@ -666,6 +666,11 @@ void CheckerManager::_registerForPointerEscape(CheckPointerEscapeFunc checkfn){ PointerEscapeCheckers.push_back(checkfn); } +void CheckerManager::_registerForConstPointerEscape( + CheckPointerEscapeFunc checkfn) { + PointerEscapeCheckers.push_back(checkfn); +} + void CheckerManager::_registerForEvalAssume(EvalAssumeFunc checkfn) { EvalAssumeCheckers.push_back(checkfn); } |