[analyzer] Include inlining call stack depth in plist output.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152584 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index cce75ad..ee2b3f3 100644
--- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -197,7 +197,8 @@
const FIDMap& FM,
const SourceManager &SM,
const LangOptions &LangOpts,
- unsigned indent) {
+ unsigned indent,
+ unsigned depth) {
Indent(o, indent) << "<dict>\n";
++indent;
@@ -223,6 +224,10 @@
--indent;
Indent(o, indent) << "</array>\n";
}
+
+ // Output the call depth.
+ Indent(o, indent) << "<key>depth</key>"
+ << "<integer>" << depth << "</integer>\n";
// Output the text.
assert(!P.getString().empty());
@@ -245,52 +250,58 @@
const FIDMap& FM, const SourceManager &SM,
const LangOptions &LangOpts,
unsigned indent,
+ unsigned depth,
bool includeControlFlow);
static void ReportCall(raw_ostream &o,
const PathDiagnosticCallPiece &P,
const FIDMap& FM, const SourceManager &SM,
const LangOptions &LangOpts,
- unsigned indent) {
+ unsigned indent,
+ unsigned depth) {
IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnter =
P.getCallEnterEvent();
if (callEnter)
- ReportPiece(o, *callEnter, FM, SM, LangOpts, indent, true);
+ ReportPiece(o, *callEnter, FM, SM, LangOpts, indent, depth, true);
IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnterWithinCaller =
P.getCallEnterWithinCallerEvent();
+ ++depth;
+
if (callEnterWithinCaller)
- ReportPiece(o, *callEnterWithinCaller, FM, SM, LangOpts, indent, true);
+ ReportPiece(o, *callEnterWithinCaller, FM, SM, LangOpts,
+ indent, depth, true);
for (PathPieces::const_iterator I = P.path.begin(), E = P.path.end();I!=E;++I)
- ReportPiece(o, **I, FM, SM, LangOpts, indent, true);
+ ReportPiece(o, **I, FM, SM, LangOpts, indent, depth, true);
IntrusiveRefCntPtr<PathDiagnosticEventPiece> callExit =
P.getCallExitEvent();
if (callExit)
- ReportPiece(o, *callExit, FM, SM, LangOpts, indent, true);
+ ReportPiece(o, *callExit, FM, SM, LangOpts, indent, depth, true);
}
static void ReportMacro(raw_ostream &o,
const PathDiagnosticMacroPiece& P,
const FIDMap& FM, const SourceManager &SM,
const LangOptions &LangOpts,
- unsigned indent) {
+ unsigned indent,
+ unsigned depth) {
for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end();
I!=E; ++I) {
- ReportPiece(o, **I, FM, SM, LangOpts, indent, false);
+ ReportPiece(o, **I, FM, SM, LangOpts, indent, depth, false);
}
}
static void ReportDiag(raw_ostream &o, const PathDiagnosticPiece& P,
const FIDMap& FM, const SourceManager &SM,
const LangOptions &LangOpts) {
- ReportPiece(o, P, FM, SM, LangOpts, 4, true);
+ ReportPiece(o, P, FM, SM, LangOpts, 4, 0, true);
}
static void ReportPiece(raw_ostream &o,
@@ -298,6 +309,7 @@
const FIDMap& FM, const SourceManager &SM,
const LangOptions &LangOpts,
unsigned indent,
+ unsigned depth,
bool includeControlFlow) {
switch (P.getKind()) {
case PathDiagnosticPiece::ControlFlow:
@@ -307,15 +319,15 @@
break;
case PathDiagnosticPiece::Call:
ReportCall(o, cast<PathDiagnosticCallPiece>(P), FM, SM, LangOpts,
- indent);
+ indent, depth);
break;
case PathDiagnosticPiece::Event:
ReportEvent(o, cast<PathDiagnosticSpotPiece>(P), FM, SM, LangOpts,
- indent);
+ indent, depth);
break;
case PathDiagnosticPiece::Macro:
ReportMacro(o, cast<PathDiagnosticMacroPiece>(P), FM, SM, LangOpts,
- indent);
+ indent, depth);
break;
}
}
diff --git a/test/Analysis/inline-plist.c b/test/Analysis/inline-plist.c
index f2ef606..08b2aed 100644
--- a/test/Analysis/inline-plist.c
+++ b/test/Analysis/inline-plist.c
@@ -14,6 +14,15 @@
return 5/x;
}
+// Test a bug triggering only when inlined.
+void has_bug(int *p) {
+ *p = 0xDEADBEEF;
+}
+
+void test_has_bug() {
+ has_bug(0);
+}
+
// CHECK: <?xml version="1.0" encoding="UTF-8"?>
// CHECK: <plist version="1.0">
// CHECK: <dict>
@@ -116,6 +125,7 @@
// CHECK: </dict>
// CHECK: </array>
// CHECK: </array>
+// CHECK: <key>depth</key><integer>0</integer>
// CHECK: <key>extended_message</key>
// CHECK: <string>Assuming 'x' is equal to 0</string>
// CHECK: <key>message</key>
@@ -212,6 +222,7 @@
// CHECK: </dict>
// CHECK: </array>
// CHECK: </array>
+// CHECK: <key>depth</key><integer>0</integer>
// CHECK: <key>extended_message</key>
// CHECK: <string>Division by zero</string>
// CHECK: <key>message</key>
@@ -228,7 +239,126 @@
// CHECK: <key>file</key><integer>0</integer>
// CHECK: </dict>
// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>12</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>depth</key><integer>0</integer>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Calling 'has_bug'</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Calling 'has_bug'</string>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>1</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>depth</key><integer>1</integer>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Entered call to 'has_bug'</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Entered call to 'has_bug'</string>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>1</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>1</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>19</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>19</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>19</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>19</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>19</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>depth</key><integer>1</integer>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable 'p')</string>
+// CHECK: <key>category</key><string>Logic error</string>
+// CHECK: <key>type</key><string>Dereference of null pointer</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>19</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </dict>
// CHECK: </array>
// CHECK: </dict>
// CHECK: </plist>
-