aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp16
-rw-r--r--test/Analysis/malloc.c14
2 files changed, 15 insertions, 15 deletions
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 5db85ecb40..0a36071cf7 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -679,14 +679,8 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
SymbolRef Sym = SR->getSymbol();
const RefState *RS = state->get<RegionState>(Sym);
- // If the symbol has not been tracked, return. This is possible when free() is
- // called on a pointer that does not get its pointee directly from malloc().
- // Full support of this requires inter-procedural analysis.
- if (!RS)
- return 0;
-
// Check double free.
- if (RS->isReleased() || RS->isRelinquished()) {
+ if (RS && (RS->isReleased() || RS->isRelinquished())) {
if (ExplodedNode *N = C.generateSink()) {
if (!BT_DoubleFree)
BT_DoubleFree.reset(
@@ -902,10 +896,8 @@ ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero,0,false)){
// The semantics of the return value are:
// If size was equal to 0, either NULL or a pointer suitable to be passed
- // to free() is returned.
- stateFree = stateFree->set<ReallocPairs>(ToPtr,
- ReallocPair(FromPtr, FreesOnFail));
- C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
+ // to free() is returned. We just free the input pointer and do not add
+ // any constrains on the output pointer.
return stateFree;
}
@@ -1518,7 +1510,7 @@ MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N,
const RefState *RS = state->get<RegionState>(Sym);
const RefState *RSPrev = statePrev->get<RegionState>(Sym);
- if (!RS && !RSPrev)
+ if (!RS)
return 0;
const Stmt *S = 0;
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index 377642cc58..964424647f 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -69,7 +69,7 @@ void reallocSizeZero1() {
char *p = malloc(12);
char *r = realloc(p, 0);
if (!r) {
- free(p);
+ free(p); // expected-warning {{Attempt to free released memory}}
} else {
free(r);
}
@@ -79,7 +79,7 @@ void reallocSizeZero2() {
char *p = malloc(12);
char *r = realloc(p, 0);
if (!r) {
- free(p);
+ free(p); // expected-warning {{Attempt to free released memory}}
} else {
free(r);
}
@@ -321,7 +321,7 @@ void nullFree() {
void paramFree(int *p) {
myfoo(p);
free(p); // no warning
- myfoo(p); // TODO: This should be a warning.
+ myfoo(p); // expected-warning {{Use of memory after it is freed}}
}
int* mallocEscapeRet() {
@@ -999,3 +999,11 @@ void foo (xpc_connection_t peer) {
xpc_connection_resume(peer);
}
+// Make sure we catch errors when we free in a function which does not allocate memory.
+void freeButNoMalloc(int *p, int x){
+ if (x) {
+ free(p);
+ //user forgot a return here.
+ }
+ free(p); // expected-warning {{Attempt to free released memory}}
+}