[cfe-commits] r163749 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/MallocChecker.cpp test/Analysis/malloc.c
Anna Zaks
ganna at apple.com
Wed Sep 12 15:57:34 PDT 2012
Author: zaks
Date: Wed Sep 12 17:57:34 2012
New Revision: 163749
URL: http://llvm.org/viewvc/llvm-project?rev=163749&view=rev
Log:
[analyzer] Fix another false positive in malloc realloc logic.
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/trunk/test/Analysis/malloc.c
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=163749&r1=163748&r2=163749&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Wed Sep 12 17:57:34 2012
@@ -70,24 +70,31 @@
}
};
+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 @@
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 @@
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;
Modified: cfe/trunk/test/Analysis/malloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc.c?rev=163749&r1=163748&r2=163749&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc.c (original)
+++ cfe/trunk/test/Analysis/malloc.c Wed Sep 12 17:57:34 2012
@@ -1020,6 +1020,16 @@
return 0;
}
+// Test realloc with no visible malloc.
+void *test(void *ptr) {
+ void *newPtr = realloc(ptr, 4);
+ if (newPtr == 0) {
+ if (ptr)
+ free(ptr); // no-warning
+ }
+ return newPtr;
+}
+
// ----------------------------------------------------------------------------
// False negatives.
More information about the cfe-commits
mailing list