aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2013-04-15 22:38:04 +0000
committerAnna Zaks <ganna@apple.com>2013-04-15 22:38:04 +0000
commit07d8470effc0b0364801adddb6ff92bd22334402 (patch)
treed5c234e8217b47e12f0508407665b9a14c69f8d6
parent79d0cceb8847bfe6dc9da8eb2ea2f3c6bb73b813 (diff)
[analyzer] Add pretty printing to CXXBaseObjectRegion.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179573 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h4
-rw-r--r--lib/StaticAnalyzer/Core/MemRegion.cpp6
-rw-r--r--test/Analysis/inlining/path-notes.cpp118
3 files changed, 127 insertions, 1 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 0d513f8326..f8f9e6db4d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -1095,6 +1095,10 @@ public:
static bool classof(const MemRegion *region) {
return region->getKind() == CXXBaseObjectRegionKind;
}
+
+ bool canPrintPrettyAsExpr() const;
+
+ void printPrettyAsExpr(raw_ostream &os) const;
};
template<typename RegionTy>
diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp
index 32e7f7713b..8f9f8c6dcd 100644
--- a/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -616,10 +616,14 @@ void FieldRegion::printPretty(raw_ostream &os) const {
return;
}
-bool FieldRegion::canPrintPrettyAsExpr() const {
+bool CXXBaseObjectRegion::canPrintPrettyAsExpr() const {
return superRegion->canPrintPrettyAsExpr();
}
+void CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const {
+ superRegion->printPrettyAsExpr(os);
+}
+
//===----------------------------------------------------------------------===//
// MemRegionManager methods.
//===----------------------------------------------------------------------===//
diff --git a/test/Analysis/inlining/path-notes.cpp b/test/Analysis/inlining/path-notes.cpp
index 5393fa2fcb..01af5313b1 100644
--- a/test/Analysis/inlining/path-notes.cpp
+++ b/test/Analysis/inlining/path-notes.cpp
@@ -213,6 +213,15 @@ int testNonPrintableAssignment(int **p) {
// expected-note@-1 {{Dereference of null pointer (loaded from variable 'y')}}
}
+struct Base { int *x; };
+struct Derived : public Base {};
+
+void test(Derived d) {
+ d.x = 0; //expected-note {{Null pointer value stored to 'd.x'}}
+ *d.x = 1; // expected-warning {{Dereference of null pointer (loaded from field 'x')}}
+ // expected-note@-1 {{Dereference of null pointer (loaded from field 'x')}}
+}
+
// CHECK: <key>diagnostics</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
@@ -3819,4 +3828,113 @@ int testNonPrintableAssignment(int **p) {
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>path</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
+// CHECK-NEXT: <key>col</key><integer>9</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Null pointer value stored to &apos;d.x&apos;</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Null pointer value stored to &apos;d.x&apos;</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>control</string>
+// CHECK-NEXT: <key>edges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>start</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>220</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>end</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>kind</key><string>event</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <key>ranges</key>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <array>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
+// CHECK-NEXT: <key>col</key><integer>6</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>depth</key><integer>0</integer>
+// CHECK-NEXT: <key>extended_message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from field &apos;x&apos;)</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Dereference of null pointer (loaded from field &apos;x&apos;)</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </array>
+// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from field &apos;x&apos;)</string>
+// CHECK-NEXT: <key>category</key><string>Logic error</string>
+// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT: <key>issue_context</key><string>test</string>
+// CHECK-NEXT: <key>issue_hash</key><string>2</string>
+// CHECK-NEXT: <key>location</key>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>221</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>