diff options
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h | 12 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 5 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/MemRegion.cpp | 22 | ||||
-rw-r--r-- | test/Analysis/malloc.c | 12 |
4 files changed, 37 insertions, 14 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index 9bdeb3e09b..2018bd2e44 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -150,8 +150,11 @@ public: void dump() const; + /// \brief Returns true if this region can be printed in a user-friendly way. + virtual bool canPrintPretty() const; + /// \brief Print the region for use in diagnostics. - virtual void dumpPretty(raw_ostream &os) const; + virtual void printPretty(raw_ostream &os) const; Kind getKind() const { return kind; } @@ -846,7 +849,8 @@ public: return R->getKind() == VarRegionKind; } - void dumpPretty(raw_ostream &os) const; + bool canPrintPretty() const; + void printPretty(raw_ostream &os) const; }; /// CXXThisRegion - Represents the region for the implicit 'this' parameter @@ -905,7 +909,9 @@ public: } void dumpToStream(raw_ostream &os) const; - void dumpPretty(raw_ostream &os) const; + + bool canPrintPretty() const; + void printPretty(raw_ostream &os) const; }; class ObjCIvarRegion : public DeclRegion { diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index d384bc34f9..56221801e5 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1000,10 +1000,9 @@ void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N, SmallString<200> buf; llvm::raw_svector_ostream os(buf); os << "Memory is never released; potential leak"; - // FIXME: Make all region pretty-printing nice enough to show. - if (Region && isa<VarRegion>(Region)) { + if (Region && Region->canPrintPretty()) { os << " of memory pointed to by '"; - Region->dumpPretty(os); + Region->printPretty(os); os << '\''; } diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp index f3a1ff447c..b2e7055c31 100644 --- a/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -546,17 +546,29 @@ void StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const { os << "StackLocalsSpaceRegion"; } -void MemRegion::dumpPretty(raw_ostream &os) const { +bool MemRegion::canPrintPretty() const { + return false; +} + +void MemRegion::printPretty(raw_ostream &os) const { return; } -void VarRegion::dumpPretty(raw_ostream &os) const { +bool VarRegion::canPrintPretty() const { + return true; +} + +void VarRegion::printPretty(raw_ostream &os) const { os << getDecl()->getName(); } -void FieldRegion::dumpPretty(raw_ostream &os) const { - superRegion->dumpPretty(os); - os << "->" << getDecl(); +bool FieldRegion::canPrintPretty() const { + return superRegion->canPrintPretty(); +} + +void FieldRegion::printPretty(raw_ostream &os) const { + superRegion->printPretty(os); + os << "." << getDecl()->getName(); } //===----------------------------------------------------------------------===// diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c index 24fa30baa8..f60271f39f 100644 --- a/test/Analysis/malloc.c +++ b/test/Analysis/malloc.c @@ -19,7 +19,7 @@ char *fooRetPtr(); void f1() { int *p = malloc(12); - return; // expected-warning{{Memory is never released; potential leak}} + return; // expected-warning{{Memory is never released; potential leak of memory pointed to by 'p'}} } void f2() { @@ -44,7 +44,7 @@ void reallocNotNullPtr(unsigned sizeIn) { char *p = (char*)malloc(size); if (p) { char *q = (char*)realloc(p, sizeIn); - char x = *q; // expected-warning {{Memory is never released; potential leak}} + char x = *q; // expected-warning {{Memory is never released; potential leak of memory pointed to by 'q'}} } } @@ -102,7 +102,7 @@ void reallocSizeZero5() { } void reallocPtrZero1() { - char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential leak}} + char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential leak of memory pointed to by 'r'}} } void reallocPtrZero2() { @@ -529,6 +529,12 @@ int *testMalloc3() { return y; // no-warning } +void testStructLeak() { + StructWithPtr St; + St.memP = malloc(12); + return; // expected-warning {{Memory is never released; potential leak of memory pointed to by 'St.memP'}} +} + void testElemRegion1() { char *x = (void*)malloc(2); int *ix = (int*)x; |