aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-11-13 19:47:40 +0000
committerAnna Zaks <ganna@apple.com>2012-11-13 19:47:40 +0000
commit2ccecfaa4852c134191d4075d94e09399ab46fea (patch)
tree1fb5a120ab1fedb015662df5bccd0056e82379bf /lib/StaticAnalyzer
parent6e649737898ffb627c377fd8fa0a437d0a42ae4a (diff)
[analyzer] Address Jordan's code review for r167813.
This simplifies logic, fixes a bug, and adds a test case. Thanks Jordan! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167868 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer')
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp35
1 files changed, 15 insertions, 20 deletions
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 887f3878f2..caf70ca370 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -627,24 +627,19 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
ReleasedAllocated, ReturnsNullOnFailure);
}
-/// Check if the previous call to free on the given symbol failed.
-///
-/// For example, if free failed, returns true. In addition, cleans out the
-/// state from the corresponding failure info. Retuns the cleaned out state
-/// and the corresponding return value symbol.
-static std::pair<bool, ProgramStateRef>
-checkAndCleanFreeFailedInfo(ProgramStateRef State,
- SymbolRef Sym, const SymbolRef *Ret) {
- Ret = State->get<FreeReturnValue>(Sym);
+/// Checks if the previous call to free on the given symbol failed - if free
+/// failed, returns true. Also, returns the corresponding return value symbol.
+bool didPreviousFreeFail(ProgramStateRef State,
+ SymbolRef Sym, SymbolRef &RetStatusSymbol) {
+ const SymbolRef *Ret = State->get<FreeReturnValue>(Sym);
if (Ret) {
assert(*Ret && "We should not store the null return symbol");
ConstraintManager &CMgr = State->getConstraintManager();
ConditionTruthVal FreeFailed = CMgr.isNull(State, *Ret);
- State = State->remove<FreeReturnValue>(Sym);
- return std::pair<bool, ProgramStateRef>(FreeFailed.isConstrainedTrue(),
- State);
+ RetStatusSymbol = *Ret;
+ return FreeFailed.isConstrainedTrue();
}
- return std::pair<bool, ProgramStateRef>(false, State);
+ return false;
}
ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
@@ -716,15 +711,12 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
SymbolRef Sym = SR->getSymbol();
const RefState *RS = State->get<RegionState>(Sym);
- bool FailedToFree = false;
- const SymbolRef *RetStatusSymbolPtr = 0;
- llvm::tie(FailedToFree, State) =
- checkAndCleanFreeFailedInfo(State, Sym, RetStatusSymbolPtr);
+ SymbolRef PreviousRetStatusSymbol = 0;
// Check double free.
if (RS &&
(RS->isReleased() || RS->isRelinquished()) &&
- !FailedToFree) {
+ !didPreviousFreeFail(State, Sym, PreviousRetStatusSymbol)) {
if (ExplodedNode *N = C.generateSink()) {
if (!BT_DoubleFree)
@@ -735,8 +727,8 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
"Attempt to free non-owned memory"), N);
R->addRange(ArgExpr->getSourceRange());
R->markInteresting(Sym);
- if (RetStatusSymbolPtr)
- R->markInteresting(*RetStatusSymbolPtr);
+ if (PreviousRetStatusSymbol)
+ R->markInteresting(PreviousRetStatusSymbol);
R->addVisitor(new MallocBugVisitor(Sym));
C.emitReport(R);
}
@@ -745,6 +737,9 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
ReleasedAllocated = (RS != 0);
+ // Clean out the info on previous call to free return info.
+ State = State->remove<FreeReturnValue>(Sym);
+
// Keep track of the return value. If it is NULL, we will know that free
// failed.
if (ReturnsNullOnFailure) {