diff options
author | Anna Zaks <ganna@apple.com> | 2012-11-13 19:47:40 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-11-13 19:47:40 +0000 |
commit | a14c1d09f6720c46396e2e0537807267affeb418 (patch) | |
tree | 9fd061ed1fa3f5e2aad79fdd3f4ffb41cbaff46f /clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | |
parent | 38d2284eeb0c0675688233f14a3326632cb377c1 (diff) | |
download | bcm5719-llvm-a14c1d09f6720c46396e2e0537807267affeb418.tar.gz bcm5719-llvm-a14c1d09f6720c46396e2e0537807267affeb418.zip |
[analyzer] Address Jordan's code review for r167813.
This simplifies logic, fixes a bug, and adds a test case.
Thanks Jordan!
llvm-svn: 167868
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 887f3878f2e..caf70ca3706 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/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) { |