From fc7ac8f0b9ffd83b9e7329926e9e184586b49138 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Fri, 13 Nov 2009 07:48:11 +0000 Subject: [PATCH] Malloc checker basically works now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@87094 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/MallocChecker.cpp | 26 ++++++++++++++++++++++++-- test/Analysis/malloc.c | 13 +++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 test/Analysis/malloc.c diff --git a/lib/Analysis/MallocChecker.cpp b/lib/Analysis/MallocChecker.cpp index f007aa65da..6655194d5e 100644 --- a/lib/Analysis/MallocChecker.cpp +++ b/lib/Analysis/MallocChecker.cpp @@ -30,11 +30,12 @@ class VISIBILITY_HIDDEN RegionState {}; class VISIBILITY_HIDDEN MallocChecker : public CheckerVisitor { 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(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); + } + } + } } diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c new file mode 100644 index 0000000000..270b3d1b69 --- /dev/null +++ b/test/Analysis/malloc.c @@ -0,0 +1,13 @@ +// RUN: clang-cc -analyze -checker-cfref -analyzer-experimental-checks -analyzer-store=region -verify %s +#include + +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}} +} -- 2.40.0