diff options
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 16 | ||||
-rw-r--r-- | test/Analysis/malloc.c | 14 |
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}} +} |