diff options
author | Anna Zaks <ganna@apple.com> | 2012-09-12 22:57:34 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-09-12 22:57:34 +0000 |
commit | 75cfbb60a81854368a9c7c2a7cbad70c943c68c5 (patch) | |
tree | 185be2796028c149020449d48d26e9c110375968 /clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | |
parent | e663b80975b271696cdd5111dc243d93ed0077c5 (diff) | |
download | bcm5719-llvm-75cfbb60a81854368a9c7c2a7cbad70c943c68c5.tar.gz bcm5719-llvm-75cfbb60a81854368a9c7c2a7cbad70c943c68c5.zip |
[analyzer] Fix another false positive in malloc realloc logic.
llvm-svn: 163749
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 45 |
1 files changed, 32 insertions, 13 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index b3107c84476..f57ea12ee07 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -70,24 +70,31 @@ public: } }; +enum ReallocPairKind { + RPToBeFreedAfterFailure, + // The symbol has been freed when reallocation failed. + RPIsFreeOnFailure, + // The symbol does not need to be freed after reallocation fails. + RPDoNotTrackAfterFailure +}; + /// \class ReallocPair /// \brief Stores information about the symbol being reallocated by a call to /// 'realloc' to allow modeling failed reallocation later in the path. struct ReallocPair { // \brief The symbol which realloc reallocated. SymbolRef ReallocatedSym; - // \brief The flag is true if the symbol does not need to be freed after - // reallocation fails. - bool IsFreeOnFailure; + ReallocPairKind Kind; - ReallocPair(SymbolRef S, bool F) : ReallocatedSym(S), IsFreeOnFailure(F) {} + ReallocPair(SymbolRef S, ReallocPairKind K) : + ReallocatedSym(S), Kind(K) {} void Profile(llvm::FoldingSetNodeID &ID) const { - ID.AddInteger(IsFreeOnFailure); + ID.AddInteger(Kind); ID.AddPointer(ReallocatedSym); } bool operator==(const ReallocPair &X) const { return ReallocatedSym == X.ReallocatedSym && - IsFreeOnFailure == X.IsFreeOnFailure; + Kind == X.Kind; } }; @@ -926,10 +933,16 @@ ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C, if (!stateRealloc) return 0; + ReallocPairKind Kind = RPToBeFreedAfterFailure; + if (FreesOnFail) + Kind = RPIsFreeOnFailure; + else if (!ReleasedAllocated) + Kind = RPDoNotTrackAfterFailure; + // Record the info about the reallocated symbol so that we could properly // process failed reallocation. stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr, - ReallocPair(FromPtr, FreesOnFail || !ReleasedAllocated)); + ReallocPair(FromPtr, Kind)); // The reallocated symbol should stay alive for as long as the new symbol. C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr); return stateRealloc; @@ -1285,15 +1298,21 @@ ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state, ReallocMap RP = state->get<ReallocPairs>(); for (ReallocMap::iterator I = RP.begin(), E = RP.end(); I != E; ++I) { // If the symbol is assumed to be NULL, remove it from consideration. - if (state->getConstraintManager().isNull(state, I.getKey()).isTrue()) { - SymbolRef ReallocSym = I.getData().ReallocatedSym; - if (const RefState *RS = state->get<RegionState>(ReallocSym)) { - if (RS->isReleased() && ! I.getData().IsFreeOnFailure) + if (!state->getConstraintManager().isNull(state, I.getKey()).isTrue()) + continue; + SymbolRef ReallocSym = I.getData().ReallocatedSym; + if (const RefState *RS = state->get<RegionState>(ReallocSym)) { + if (RS->isReleased()) { + if (I.getData().Kind == RPToBeFreedAfterFailure) state = state->set<RegionState>(ReallocSym, - RefState::getAllocated(RS->getStmt())); + RefState::getAllocated(RS->getStmt())); + else if (I.getData().Kind == RPDoNotTrackAfterFailure) + state = state->remove<RegionState>(ReallocSym); + else + assert(I.getData().Kind == RPIsFreeOnFailure); } - state = state->remove<ReallocPairs>(I.getKey()); } + state = state->remove<ReallocPairs>(I.getKey()); } return state; |