Got it. Attached is an updated patch, please review.
http://reviews.llvm.org/D9040
Files:
lib/StaticAnalyzer/Checkers/MallocChecker.cpp
test/Analysis/malloc.c
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -152,6 +152,18 @@
}
};
+/// \class ReallocSizeZero
+/// \brief Indicates zero-size reallocation. Used to catch references to
+/// zero-allocated memory returned by 'realloc(ptr, 0)'.
+struct ReallocSizeZero {
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddString("ReallocSizeZero");
+ };
+ bool operator==(const ReallocSizeZero &X) const {
+ return true;
+ }
+};
+
typedef std::pair<const ExplodedNode*, const MemRegion*> LeakInfo;
class MallocChecker : public Checker<check::DeadSymbols,
@@ -509,6 +521,7 @@
REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState)
REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair)
+REGISTER_MAP_WITH_PROGRAMSTATE(ReallocSizeZeroFlag, SymbolRef, ReallocSizeZero)
// A map from the freed symbol to the symbol representing the return value of
// the free function.
@@ -892,15 +905,19 @@
return State;
const RefState *RS = State->get<RegionState>(Sym);
- if (!RS)
- return State; // TODO: change to assert(RS); after realloc() will
- // guarantee have a RegionState attached.
-
- if (!RS->isAllocated())
- return State;
-
- return TrueState->set<RegionState>(Sym,
- RefState::getAllocatedOfSizeZero(RS));
+ if (RS) {
+ if (RS->isAllocated())
+ return TrueState->set<RegionState>(Sym,
+ RefState::getAllocatedOfSizeZero(RS));
+ else
+ return State;
+ } else {
+ // Case of zero-size realloc. Historically 'realloc(ptr, 0)' is treated as
+ // 'free(ptr)' and the returned value from 'realloc(ptr, 0)' is not
+ // tracked. Here we add ReallocSizeZeroFlag mark to catch references
+ // to zero-allocated memory.
+ return TrueState->set<ReallocSizeZeroFlag>(Sym, ReallocSizeZero());
+ }
}
// Assume the value is non-zero going forward.
@@ -1488,6 +1505,9 @@
Optional<MallocChecker::CheckKind>
MallocChecker::getCheckIfTracked(CheckerContext &C, SymbolRef Sym,
bool IsALeakCheck) const {
+ if (C.getState()->get<ReallocSizeZeroFlag>(Sym))
+ return CK_MallocChecker;
+
const RefState *RS = C.getState()->get<RegionState>(Sym);
assert(RS);
return getCheckIfTracked(RS->getAllocationFamily(), IsALeakCheck);
@@ -1929,7 +1949,7 @@
}
if (PrtIsNull && SizeIsZero)
- return nullptr;
+ return State;
// Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size).
assert(!PrtIsNull);
@@ -2291,10 +2311,14 @@
void MallocChecker::checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
const Stmt *S) const {
assert(Sym);
- const RefState *RS = C.getState()->get<RegionState>(Sym);
- if (RS && RS->isAllocatedOfSizeZero())
- ReportUseZeroAllocated(C, RS->getStmt()->getSourceRange(), Sym);
+ if (const RefState *RS = C.getState()->get<RegionState>(Sym)) {
+ if (RS->isAllocatedOfSizeZero())
+ ReportUseZeroAllocated(C, RS->getStmt()->getSourceRange(), Sym);
+ }
+ else if (C.getState()->get<ReallocSizeZeroFlag>(Sym)) {
+ ReportUseZeroAllocated(C, S->getSourceRange(), Sym);
+ }
}
bool MallocChecker::checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const {
Index: test/Analysis/malloc.c
===================================================================
--- test/Analysis/malloc.c
+++ test/Analysis/malloc.c
@@ -263,21 +263,21 @@
void CheckUseZeroAllocated7() {
int *p = realloc(0, 0);
- *p = 1; //TODO: warn about use of zero-allocated memory
+ *p = 1; // expected-warning {{Use of zero-allocated memory}}
free(p);
}
void CheckUseZeroAllocated8() {
int *p = malloc(8);
int *q = realloc(p, 0);
- *q = 1; //TODO: warn about use of zero-allocated memory
+ *q = 1; // expected-warning {{Use of zero-allocated memory}}
free(q);
}
void CheckUseZeroAllocated9() {
int *p = realloc(0, 0);
int *q = realloc(p, 0);
- *q = 1; //TODO: warn about use of zero-allocated memory
+ *q = 1; // expected-warning {{Use of zero-allocated memory}}
free(q);
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits