aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-02-14 00:26:13 +0000
committerAnna Zaks <ganna@apple.com>2012-02-14 00:26:13 +0000
commitb276bd9cc98247331cac8b290ba278b939e53657 (patch)
tree04ae886c76f99dff195b6e946275551cb3d7f073 /lib/StaticAnalyzer/Checkers/MallocChecker.cpp
parentd764437c9ce6feae11a9fca35bbc4ebc004f69e0 (diff)
[analyzer] Malloc Checker: realloc: add dependency between the symbols
in realloc map. If there is no dependency, the reallocated ptr will get garbage collected before we know that realloc failed, which would lead us to missing a memory leak warning. Also added new test cases, which we can handle now. Plus minor cleanups. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150446 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/MallocChecker.cpp')
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp15
1 files changed, 6 insertions, 9 deletions
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 9329d5251f..7cbb49e2d8 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -409,17 +409,12 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
if (!isa<Loc>(location))
return 0;
- // FIXME: Technically using 'Assume' here can result in a path
- // bifurcation. In such cases we need to return two states, not just one.
+ // The explicit NULL case, no operation is performed.
ProgramStateRef notNullState, nullState;
llvm::tie(notNullState, nullState) = state->assume(location);
-
- // The explicit NULL case, no operation is performed.
if (nullState && !notNullState)
return 0;
- assert(notNullState);
-
// Unknown values could easily be okay
// Undefined values are handled elsewhere
if (ArgVal.isUnknownOrUndef())
@@ -490,8 +485,8 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
// Normal free.
if (Hold)
- return notNullState->set<RegionState>(Sym, RefState::getRelinquished(CE));
- return notNullState->set<RegionState>(Sym, RefState::getReleased(CE));
+ return state->set<RegionState>(Sym, RefState::getRelinquished(CE));
+ return state->set<RegionState>(Sym, RefState::getReleased(CE));
}
bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
@@ -685,6 +680,7 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
// If size was equal to 0, either NULL or a pointer suitable to be passed
// to free() is returned.
stateFree = stateFree->set<ReallocPairs>(ToPtr, FromPtr);
+ C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
C.addTransition(stateFree);
return;
}
@@ -697,6 +693,7 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
if (!stateRealloc)
return;
stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr, FromPtr);
+ C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
C.addTransition(stateRealloc);
return;
}
@@ -918,7 +915,7 @@ ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
if (RS->isReleased())
state = state->set<RegionState>(I.getData(),
RefState::getAllocateUnchecked(RS->getStmt()));
- if (RS->isAllocated())
+ else if (RS->isAllocated())
state = state->set<RegionState>(I.getData(),
RefState::getReleased(RS->getStmt()));
}