diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-03-12 22:10:57 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-03-12 22:10:57 +0000 |
commit | e881efe78596a6ce9219237b737ced4adb1f8251 (patch) | |
tree | f2a6c87be9c5c9d7d968d0f215c00f4321bf8d89 | |
parent | 3d7171582b026e043916fc5d65a7d7aada547206 (diff) |
[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
-rw-r--r-- | lib/StaticAnalyzer/Core/PlistDiagnostics.cpp | 36 | ||||
-rw-r--r-- | test/Analysis/inline-plist.c | 132 |
2 files changed, 155 insertions, 13 deletions
diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp index cce75ad555..ee2b3f35fb 100644 --- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -197,7 +197,8 @@ static void ReportEvent(raw_ostream &o, const PathDiagnosticPiece& P, 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 @@ static void ReportEvent(raw_ostream &o, const PathDiagnosticPiece& P, --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 @@ static void ReportPiece(raw_ostream &o, 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 @@ static void ReportPiece(raw_ostream &o, 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 @@ static void ReportPiece(raw_ostream &o, 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 f2ef606601..08b2aedc67 100644 --- a/test/Analysis/inline-plist.c +++ b/test/Analysis/inline-plist.c @@ -14,6 +14,15 @@ int foo(int x, int y) { 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 @@ int foo(int x, int y) { // 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 @@ int foo(int x, int y) { // 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 @@ int foo(int x, int y) { // 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> - |