aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h12
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp5
-rw-r--r--lib/StaticAnalyzer/Core/MemRegion.cpp22
-rw-r--r--test/Analysis/malloc.c12
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;