aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Core/CheckerManager.cpp10
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp11
5 files changed, 34 insertions, 13 deletions
diff --git a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
index 35baef645b..ed89788e90 100644
--- a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
@@ -265,10 +265,12 @@ public:
/// \param Escaped The list of escaped symbols.
/// \param Call The corresponding CallEvent, if the symbols escape as
/// parameters to the given call.
+ /// \param Kind How the symbols have escaped.
/// \returns Checkers can modify the state by returning a new state.
ProgramStateRef checkPointerEscape(ProgramStateRef State,
const InvalidatedSymbols &Escaped,
- const CallEvent *Call) const {
+ const CallEvent *Call,
+ PointerEscapeKind Kind) const {
return State;
}
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 33553a1385..9afd8cff4c 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -158,7 +158,8 @@ public:
ProgramStateRef checkPointerEscape(ProgramStateRef State,
const InvalidatedSymbols &Escaped,
- const CallEvent *Call) const;
+ const CallEvent *Call,
+ PointerEscapeKind Kind) const;
void printState(raw_ostream &Out, ProgramStateRef State,
const char *NL, const char *Sep) const;
@@ -1450,11 +1451,15 @@ bool MallocChecker::doesNotFreeMemory(const CallEvent *Call,
ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State,
const InvalidatedSymbols &Escaped,
- const CallEvent *Call) const {
+ const CallEvent *Call,
+ PointerEscapeKind Kind) const {
// If we know that the call does not free memory, keep tracking the top
// level arguments.
- if (Call && doesNotFreeMemory(Call, State))
+ if ((Kind == PSK_DirectEscapeOnCall ||
+ Kind == PSK_IndirectEscapeOnCall) &&
+ doesNotFreeMemory(Call, State)) {
return State;
+ }
for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
E = Escaped.end();
diff --git a/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp b/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
index e2a19fc2f0..1ccf339bac 100644
--- a/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
@@ -82,7 +82,8 @@ public:
/// Stop tracking addresses which escape.
ProgramStateRef checkPointerEscape(ProgramStateRef State,
const InvalidatedSymbols &Escaped,
- const CallEvent *Call) const;
+ const CallEvent *Call,
+ PointerEscapeKind Kind) const;
};
} // end anonymous namespace
@@ -255,10 +256,14 @@ bool SimpleStreamChecker::guaranteedNotToCloseFile(const CallEvent &Call) const{
ProgramStateRef
SimpleStreamChecker::checkPointerEscape(ProgramStateRef State,
const InvalidatedSymbols &Escaped,
- const CallEvent *Call) const {
+ const CallEvent *Call,
+ PointerEscapeKind Kind) const {
// If we know that the call cannot close a file, there is nothing to do.
- if (Call && guaranteedNotToCloseFile(*Call))
+ if ((Kind == PSK_DirectEscapeOnCall ||
+ Kind == PSK_IndirectEscapeOnCall) &&
+ guaranteedNotToCloseFile(*Call)) {
return State;
+ }
for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
E = Escaped.end();
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index dc0cab72f9..a383799788 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -488,13 +488,19 @@ CheckerManager::runCheckersForRegionChanges(ProgramStateRef state,
ProgramStateRef
CheckerManager::runCheckersForPointerEscape(ProgramStateRef State,
const InvalidatedSymbols &Escaped,
- const CallEvent *Call) {
+ const CallEvent *Call,
+ PointerEscapeKind Kind) {
+ 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);
+ State = PointerEscapeCheckers[i](State, Escaped, Call, Kind);
}
return State;
}
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 636aa3bd0d..f092f1a3d8 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1648,7 +1648,8 @@ ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State,
const InvalidatedSymbols &EscapedSymbols = Scanner.getSymbols();
State = getCheckerManager().runCheckersForPointerEscape(State,
EscapedSymbols,
- /*CallEvent*/ 0);
+ /*CallEvent*/ 0,
+ PSK_EscapeOnBind);
return State;
}
@@ -1665,7 +1666,9 @@ ExprEngine::processPointerEscapedOnInvalidateRegions(ProgramStateRef State,
if (!Call)
return getCheckerManager().runCheckersForPointerEscape(State,
- *Invalidated, 0);
+ *Invalidated,
+ 0,
+ PSK_EscapeOther);
// If the symbols were invalidated by a call, we want to find out which ones
// were invalidated directly due to being arguments to the call.
@@ -1687,12 +1690,12 @@ ExprEngine::processPointerEscapedOnInvalidateRegions(ProgramStateRef State,
if (!SymbolsDirectlyInvalidated.empty())
State = getCheckerManager().runCheckersForPointerEscape(State,
- SymbolsDirectlyInvalidated, Call);
+ SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall);
// Notify about the symbols that get indirectly invalidated by the call.
if (!SymbolsIndirectlyInvalidated.empty())
State = getCheckerManager().runCheckersForPointerEscape(State,
- SymbolsIndirectlyInvalidated, /*CallEvent*/ 0);
+ SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall);
return State;
}