[analyzer] Solve another source of non-determinism in the diagnostic
engine.
The code that was supposed to split the tie in a deterministic way is
not deterministic. Most likely one of the profile methods uses a
pointer. After this change we do finally get the consistent diagnostic
output. Testing this requires running the analyzer on large code bases
and diffing the results.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161224 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 1eaf1f9..7ba2fa7 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -1536,6 +1536,8 @@
I = bugTypes.begin(), E = bugTypes.end(); I != E; ++I)
const_cast<BugType*>(*I)->FlushReports(*this);
+ // We need to flush reports in deterministic order to ensure the order
+ // of the reports is consistent between runs.
typedef std::vector<BugReportEquivClass *> ContVecTy;
for (ContVecTy::iterator EI=EQClassesVector.begin(), EE=EQClassesVector.end();
EI != EE; ++EI){
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index 394e975..b4c9068 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -148,23 +148,14 @@
if (PathDiagnostic *orig = Diags.FindNodeOrInsertPos(profile, InsertPos)) {
// Keep the PathDiagnostic with the shorter path.
+ // Note, the enclosing rutine is called in deterministic order, so the
+ // results will be consistent between runs (no reason to break ties if the
+ // size is the same).
const unsigned orig_size = orig->full_size();
const unsigned new_size = D->full_size();
-
- if (orig_size <= new_size) {
- bool shouldKeepOriginal = true;
- if (orig_size == new_size) {
- // Here we break ties in a fairly arbitrary, but deterministic, way.
- llvm::FoldingSetNodeID fullProfile, fullProfileOrig;
- D->FullProfile(fullProfile);
- orig->FullProfile(fullProfileOrig);
- if (fullProfile.ComputeHash() < fullProfileOrig.ComputeHash())
- shouldKeepOriginal = false;
- }
+ if (orig_size <= new_size)
+ return;
- if (shouldKeepOriginal)
- return;
- }
Diags.RemoveNode(orig);
delete orig;
}