diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-04-04 18:11:35 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-04-04 18:11:35 +0000 |
commit | 07189521a15d9c088216b943649cb9fe231cbb57 (patch) | |
tree | 649cd12e68237a26ec96485b1ed9ccdde7bf4c83 /lib/StaticAnalyzer/Core | |
parent | f54486acc1cadf2791c3916ece66fded1e57ba0b (diff) |
Include the "issue context" (e.g. function or method) where a static analyzer issue occurred in the plist output.
Fixes <rdar://problem/11004527>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154030 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core')
-rw-r--r-- | lib/StaticAnalyzer/Core/BugReporter.cpp | 27 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/PathDiagnostic.cpp | 9 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/PlistDiagnostics.cpp | 39 |
3 files changed, 63 insertions, 12 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp index e1be6e910b..2752e32e50 100644 --- a/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -1241,6 +1241,18 @@ BugReport::~BugReport() { } } +const Decl *BugReport::getDeclWithIssue() const { + if (DeclWithIssue) + return DeclWithIssue; + + const ExplodedNode *N = getErrorNode(); + if (!N) + return 0; + + const LocationContext *LC = N->getLocationContext(); + return LC->getCurrentStackFrame()->getDecl(); +} + void BugReport::Profile(llvm::FoldingSetNodeID& hash) const { hash.AddPointer(&BT); hash.AddString(Description); @@ -1952,7 +1964,8 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) { BugType& BT = exampleReport->getBugType(); OwningPtr<PathDiagnostic> - D(new PathDiagnostic(exampleReport->getBugType().getName(), + D(new PathDiagnostic(exampleReport->getDeclWithIssue(), + exampleReport->getBugType().getName(), !PD || PD->useVerboseDescription() ? exampleReport->getDescription() : exampleReport->getShortDescription(), @@ -2005,21 +2018,24 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) { PathDiagnosticPiece *piece = new PathDiagnosticEventPiece( exampleReport->getLocation(getSourceManager()), exampleReport->getDescription()); + for ( ; Beg != End; ++Beg) + piece->addRange(*Beg); - for ( ; Beg != End; ++Beg) piece->addRange(*Beg); D->getActivePath().push_back(piece); } PD->HandlePathDiagnostic(D.take()); } -void BugReporter::EmitBasicReport(StringRef name, StringRef str, +void BugReporter::EmitBasicReport(const Decl *DeclWithIssue, + StringRef name, StringRef str, PathDiagnosticLocation Loc, SourceRange* RBeg, unsigned NumRanges) { - EmitBasicReport(name, "", str, Loc, RBeg, NumRanges); + EmitBasicReport(DeclWithIssue, name, "", str, Loc, RBeg, NumRanges); } -void BugReporter::EmitBasicReport(StringRef name, +void BugReporter::EmitBasicReport(const Decl *DeclWithIssue, + StringRef name, StringRef category, StringRef str, PathDiagnosticLocation Loc, SourceRange* RBeg, unsigned NumRanges) { @@ -2027,6 +2043,7 @@ void BugReporter::EmitBasicReport(StringRef name, // 'BT' is owned by BugReporter. BugType *BT = getBugTypeForName(name, category); BugReport *R = new BugReport(*BT, str, Loc); + R->setDeclWithIssue(DeclWithIssue); for ( ; NumRanges > 0 ; --NumRanges, ++RBeg) R->addRange(*RBeg); EmitReport(R); } diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index 989553e375..01dd965ac5 100644 --- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -55,13 +55,16 @@ PathDiagnosticEventPiece::~PathDiagnosticEventPiece() {} PathDiagnosticCallPiece::~PathDiagnosticCallPiece() {} PathDiagnosticControlFlowPiece::~PathDiagnosticControlFlowPiece() {} PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() {} -PathDiagnostic::PathDiagnostic() : path(pathImpl) {} + + PathPieces::~PathPieces() {} PathDiagnostic::~PathDiagnostic() {} -PathDiagnostic::PathDiagnostic(StringRef bugtype, StringRef desc, +PathDiagnostic::PathDiagnostic(const Decl *declWithIssue, + StringRef bugtype, StringRef desc, StringRef category) - : BugType(StripTrailingDots(bugtype)), + : DeclWithIssue(declWithIssue), + BugType(StripTrailingDots(bugtype)), Desc(StripTrailingDots(desc)), Category(StripTrailingDots(category)), path(pathImpl) {} diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp index e94b54c825..323cede778 100644 --- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -145,10 +145,9 @@ static void EmitRange(raw_ostream &o, const SourceManager &SM, Indent(o, indent) << "</array>\n"; } -static raw_ostream &EmitString(raw_ostream &o, - const std::string& s) { +static raw_ostream &EmitString(raw_ostream &o, StringRef s) { o << "<string>"; - for (std::string::const_iterator I=s.begin(), E=s.end(); I!=E; ++I) { + for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) { char c = *I; switch (c) { default: o << c; break; @@ -252,7 +251,7 @@ static void ReportEvent(raw_ostream &o, const PathDiagnosticPiece& P, // FIXME: Really use a short string. Indent(o, indent) << "<key>message</key>\n"; EmitString(o, P.getString()) << '\n'; - + // Finish up. --indent; Indent(o, indent); o << "</dict>\n"; @@ -447,6 +446,38 @@ void PlistDiagnostics::FlushDiagnosticsImpl( EmitString(o, D->getCategory()) << '\n'; o << " <key>type</key>"; EmitString(o, D->getBugType()) << '\n'; + + // Output information about the semantic context where + // the issue occurred. + if (const Decl *DeclWithIssue = D->getDeclWithIssue()) { + // FIXME: handle blocks, which have no name. + if (const NamedDecl *ND = dyn_cast<NamedDecl>(DeclWithIssue)) { + StringRef declKind; + switch (ND->getKind()) { + case Decl::CXXRecord: + declKind = "C++ class"; + break; + case Decl::CXXMethod: + declKind = "C++ method"; + break; + case Decl::ObjCMethod: + declKind = "Objective-C method"; + break; + case Decl::Function: + declKind = "function"; + break; + default: + break; + } + if (!declKind.empty()) { + const std::string &declName = ND->getDeclName().getAsString(); + o << " <key>issue_context_kind</key>"; + EmitString(o, declKind) << '\n'; + o << " <key>issue_context</key>"; + EmitString(o, declName) << '\n'; + } + } + } // Output the location of the bug. o << " <key>location</key>\n"; |