aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-08-31 00:36:26 +0000
committerJordan Rose <jordan_rose@apple.com>2012-08-31 00:36:26 +0000
commit3a46f5fd1709f6df03bbb8b0abf84052dc0f39ff (patch)
tree8e352cf671af63dced741dd82f9038521f8e8e6a /lib
parent8c916ee23c7c16e859eb55a907385f94039f8b27 (diff)
[analyzer] Ensure that PathDiagnostics profile the same regardless of path.
PathDiagnostics are actually profiled and uniqued independently of the path on which the bug occurred. This is used to merge diagnostics that refer to the same issue along different paths, as well as by the plist diagnostics to reference files created by the HTML diagnostics. However, there are two problems with the current implementation: 1) The bug description is included in the profile, but some PathDiagnosticConsumers prefer abbreviated descriptions and some prefer verbose descriptions. Fixed by including both descriptions in the PathDiagnostic objects and always using the verbose one in the profile. 2) The "minimal" path generation scheme provides extra information about which events came from macros that the "extensive" scheme does not. This resulted not only in different locations for the plist and HTML diagnostics, but also in diagnostics being uniqued in the plist output but not in the HTML output. Fixed by storing the "end path" location explicitly in the PathDiagnostic object, rather than trying to find the last piece of the path when the diagnostic is requested. This should hopefully finish unsticking our internal buildbot. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162965 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp11
-rw-r--r--lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp8
-rw-r--r--lib/StaticAnalyzer/Core/PathDiagnostic.cpp45
-rw-r--r--lib/StaticAnalyzer/Core/PlistDiagnostics.cpp3
-rw-r--r--lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp1
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp3
6 files changed, 21 insertions, 50 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 1866a27f72..68cc7d88b1 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -1898,7 +1898,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
visitors.push_back((*I)->clone());
// Clear out the active path from any previous work.
- PD.getActivePath().clear();
+ PD.resetPath();
originalReportConfigToken = R->getConfigurationChangeToken();
// Generate the very last diagnostic piece - the piece is visible before
@@ -1915,7 +1915,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
if (!LastPiece)
LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R);
if (LastPiece)
- PD.getActivePath().push_back(LastPiece);
+ PD.setEndOfPath(LastPiece);
else
return;
@@ -2106,9 +2106,8 @@ void BugReporter::FlushReport(BugReport *exampleReport,
OwningPtr<PathDiagnostic>
D(new PathDiagnostic(exampleReport->getDeclWithIssue(),
exampleReport->getBugType().getName(),
- PD.useVerboseDescription()
- ? exampleReport->getDescription()
- : exampleReport->getShortDescription(),
+ exampleReport->getDescription(),
+ exampleReport->getShortDescription(/*Fallback=*/false),
BT.getCategory()));
// Generate the full path diagnostic, using the generation scheme
@@ -2128,7 +2127,7 @@ void BugReporter::FlushReport(BugReport *exampleReport,
llvm::tie(Beg, End) = exampleReport->getRanges();
for ( ; Beg != End; ++Beg)
piece->addRange(*Beg);
- D->getActivePath().push_back(piece);
+ D->setEndOfPath(piece);
}
// Get the meta data.
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index 46adfbd795..211bcb9124 100644
--- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -189,7 +189,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
<< (*path.rbegin())->getLocation().asLocation().getExpansionColumnNumber()
<< "</a></td></tr>\n"
"<tr><td class=\"rowname\">Description:</td><td>"
- << D.getDescription() << "</td></tr>\n";
+ << D.getVerboseDescription() << "</td></tr>\n";
// Output any other meta data.
@@ -209,15 +209,15 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
std::string s;
llvm::raw_string_ostream os(s);
- const std::string& BugDesc = D.getDescription();
+ StringRef BugDesc = D.getVerboseDescription();
if (!BugDesc.empty())
os << "\n<!-- BUGDESC " << BugDesc << " -->\n";
- const std::string& BugType = D.getBugType();
+ StringRef BugType = D.getBugType();
if (!BugType.empty())
os << "\n<!-- BUGTYPE " << BugType << " -->\n";
- const std::string& BugCategory = D.getCategory();
+ StringRef BugCategory = D.getCategory();
if (!BugCategory.empty())
os << "\n<!-- BUGCATEGORY " << BugCategory << " -->\n";
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index 97ef906cac..d010a668d9 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -104,11 +104,12 @@ void PathPieces::flattenTo(PathPieces &Primary, PathPieces &Current,
PathDiagnostic::~PathDiagnostic() {}
PathDiagnostic::PathDiagnostic(const Decl *declWithIssue,
- StringRef bugtype, StringRef desc,
- StringRef category)
+ StringRef bugtype, StringRef verboseDesc,
+ StringRef shortDesc, StringRef category)
: DeclWithIssue(declWithIssue),
BugType(StripTrailingDots(bugtype)),
- Desc(StripTrailingDots(desc)),
+ VerboseDesc(StripTrailingDots(verboseDesc)),
+ ShortDesc(StripTrailingDots(shortDesc)),
Category(StripTrailingDots(category)),
path(pathImpl) {}
@@ -227,8 +228,8 @@ struct CompareDiagnostics {
return false;
// Next, compare by bug description.
- StringRef XDesc = X->getDescription();
- StringRef YDesc = Y->getDescription();
+ StringRef XDesc = X->getVerboseDescription();
+ StringRef YDesc = Y->getVerboseDescription();
if (XDesc < YDesc)
return true;
if (XDesc != YDesc)
@@ -271,18 +272,11 @@ void PathDiagnosticConsumer::FlushDiagnostics(
}
}
-static void ProfileDiagnostic(const PathDiagnostic &PD,
- llvm::FoldingSetNodeID &NodeID) {
- NodeID.AddString(PD.getBugType());
- NodeID.AddString(PD.getDescription());
- NodeID.Add(PD.getLocation());
-}
-
void PathDiagnosticConsumer::FilesMade::addDiagnostic(const PathDiagnostic &PD,
StringRef ConsumerName,
StringRef FileName) {
llvm::FoldingSetNodeID NodeID;
- ProfileDiagnostic(PD, NodeID);
+ NodeID.Add(PD);
void *InsertPos;
PDFileEntry *Entry = FindNodeOrInsertPos(NodeID, InsertPos);
if (!Entry) {
@@ -303,7 +297,7 @@ void PathDiagnosticConsumer::FilesMade::addDiagnostic(const PathDiagnostic &PD,
PathDiagnosticConsumer::PDFileEntry::ConsumerFiles *
PathDiagnosticConsumer::FilesMade::getFiles(const PathDiagnostic &PD) {
llvm::FoldingSetNodeID NodeID;
- ProfileDiagnostic(PD, NodeID);
+ NodeID.Add(PD);
void *InsertPos;
PDFileEntry *Entry = FindNodeOrInsertPos(NodeID, InsertPos);
if (!Entry)
@@ -627,24 +621,6 @@ void PathDiagnosticLocation::flatten() {
}
}
-PathDiagnosticLocation PathDiagnostic::getLocation() const {
- assert(path.size() > 0 &&
- "getLocation() requires a non-empty PathDiagnostic.");
-
- PathDiagnosticPiece *p = path.rbegin()->getPtr();
-
- while (true) {
- if (PathDiagnosticCallPiece *cp = dyn_cast<PathDiagnosticCallPiece>(p)) {
- assert(!cp->path.empty());
- p = cp->path.rbegin()->getPtr();
- continue;
- }
- break;
- }
-
- return p->getLocation();
-}
-
//===----------------------------------------------------------------------===//
// Manipulation of PathDiagnosticCallPieces.
//===----------------------------------------------------------------------===//
@@ -793,10 +769,9 @@ void PathDiagnosticMacroPiece::Profile(llvm::FoldingSetNodeID &ID) const {
}
void PathDiagnostic::Profile(llvm::FoldingSetNodeID &ID) const {
- if (!path.empty())
- getLocation().Profile(ID);
+ ID.Add(getLocation());
ID.AddString(BugType);
- ID.AddString(Desc);
+ ID.AddString(VerboseDesc);
ID.AddString(Category);
}
diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index c1c46c293a..0a534bf7c0 100644
--- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -47,7 +47,6 @@ namespace {
PathGenerationScheme getGenerationScheme() const { return Extensive; }
bool supportsLogicalOpControlFlow() const { return true; }
bool supportsAllBlockEdges() const { return true; }
- virtual bool useVerboseDescription() const { return false; }
virtual bool supportsCrossFileDiagnostics() const {
return SupportsCrossFileDiagnostics;
}
@@ -443,7 +442,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
// Output the bug type and bug category.
o << " <key>description</key>";
- EmitString(o, D->getDescription()) << '\n';
+ EmitString(o, D->getShortDescription()) << '\n';
o << " <key>category</key>";
EmitString(o, D->getCategory()) << '\n';
o << " <key>type</key>";
diff --git a/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp b/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp
index 66bf4bb222..e09f4e3653 100644
--- a/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp
@@ -41,7 +41,6 @@ public:
PathGenerationScheme getGenerationScheme() const { return Minimal; }
bool supportsLogicalOpControlFlow() const { return true; }
bool supportsAllBlockEdges() const { return true; }
- virtual bool useVerboseDescription() const { return true; }
virtual bool supportsCrossFileDiagnostics() const { return true; }
};
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index bd643bab03..53747d4b4d 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -78,7 +78,6 @@ public:
ClangDiagPathDiagConsumer(DiagnosticsEngine &Diag) : Diag(Diag) {}
virtual ~ClangDiagPathDiagConsumer() {}
virtual StringRef getName() const { return "ClangDiags"; }
- virtual bool useVerboseDescription() const { return false; }
virtual PathGenerationScheme getGenerationScheme() const { return None; }
void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
@@ -86,7 +85,7 @@ public:
for (std::vector<const PathDiagnostic*>::iterator I = Diags.begin(),
E = Diags.end(); I != E; ++I) {
const PathDiagnostic *PD = *I;
- StringRef desc = PD->getDescription();
+ StringRef desc = PD->getShortDescription();
SmallString<512> TmpStr;
llvm::raw_svector_ostream Out(TmpStr);
for (StringRef::iterator I=desc.begin(), E=desc.end(); I!=E; ++I) {