diff options
author | Anna Zaks <ganna@apple.com> | 2012-02-14 00:26:13 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-02-14 00:26:13 +0000 |
commit | b276bd9cc98247331cac8b290ba278b939e53657 (patch) | |
tree | 04ae886c76f99dff195b6e946275551cb3d7f073 /lib/StaticAnalyzer/Checkers/MallocChecker.cpp | |
parent | d764437c9ce6feae11a9fca35bbc4ebc004f69e0 (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.cpp | 15 |
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())); } |