Malloc checker basically works now.

llvm-svn: 87094
This commit is contained in:
Zhongxing Xu 2009-11-13 07:48:11 +00:00
parent c4902a52a0
commit c7460964ac
2 changed files with 37 additions and 2 deletions

View File

@ -30,11 +30,12 @@ class VISIBILITY_HIDDEN RegionState {};
class VISIBILITY_HIDDEN MallocChecker : public CheckerVisitor<MallocChecker> {
BuiltinBug *BT_DoubleFree;
BuiltinBug *BT_Leak;
IdentifierInfo *II_malloc;
IdentifierInfo *II_free;
public:
MallocChecker() : BT_DoubleFree(0) {}
MallocChecker() : BT_DoubleFree(0), BT_Leak(0), II_malloc(0), II_free(0) {}
static void *getTag();
void PostVisitCallExpr(CheckerContext &C, const CallExpr *CE);
void EvalDeadSymbols(CheckerContext &C,const Stmt *S,SymbolReaper &SymReaper);
@ -81,7 +82,7 @@ void MallocChecker::PostVisitCallExpr(CheckerContext &C, const CallExpr *CE) {
if (!II_malloc)
II_malloc = &Ctx.Idents.get("malloc");
if (!II_free)
II_malloc = &Ctx.Idents.get("free");
II_free = &Ctx.Idents.get("free");
if (FD->getIdentifier() == II_malloc) {
MallocMem(C, CE);
@ -135,4 +136,25 @@ void MallocChecker::FreeMem(CheckerContext &C, const CallExpr *CE) {
void MallocChecker::EvalDeadSymbols(CheckerContext &C, const Stmt *S,
SymbolReaper &SymReaper) {
for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
E = SymReaper.dead_end(); I != E; ++I) {
SymbolRef Sym = *I;
const GRState *state = C.getState();
const RefState *RS = state->get<RegionState>(Sym);
if (!RS)
return;
if (*RS == Allocated) {
ExplodedNode *N = C.GenerateNode(S, true);
if (N) {
if (!BT_Leak)
BT_Leak = new BuiltinBug("Memory leak",
"Allocated memory never released. Potential memory leak.");
// FIXME: where it is allocated.
BugReport *R = new BugReport(*BT_Leak,
BT_Leak->getDescription().c_str(), N);
C.EmitReport(R);
}
}
}
}

View File

@ -0,0 +1,13 @@
// RUN: clang-cc -analyze -checker-cfref -analyzer-experimental-checks -analyzer-store=region -verify %s
#include <stdlib.h>
void f1() {
int *p = malloc(10);
return; // expected-warning{{Allocated memory never released. Potential memory leak.}}
}
void f2() {
int *p = malloc(10);
free(p);
free(p); // expected-warning{{Try to free a memory block that has been released}}
}