Emit -verify diagnostics even when we have a fatal error.
Previously we'd halt at the fatal error as expected, but not actually emit
any -verify-related diagnostics. This lets us catch cases that emit a
/different/ fatal error from the one we expected.
This is implemented by adding a "force emit" mode to DiagnosticBuilder, which
will cause diagnostics to immediately be emitted regardless of current
suppression. Needless to say this should probably be used /very/ sparingly.
Patch by Andy Gibbs! Tests for all of Andy's -verify patches coming soon.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160053 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index fdc37b6..6e79b85 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -382,17 +382,34 @@
CurDiagID = ~0U;
}
-bool DiagnosticsEngine::EmitCurrentDiagnostic() {
- // Process the diagnostic, sending the accumulated information to the
- // DiagnosticConsumer.
- bool Emitted = ProcessDiag();
+bool DiagnosticsEngine::EmitCurrentDiagnostic(bool Force) {
+ assert(getClient() && "DiagnosticClient not set!");
+
+ bool Emitted;
+ if (Force) {
+ Diagnostic Info(this);
+
+ // Figure out the diagnostic level of this message.
+ DiagnosticIDs::Level DiagLevel
+ = Diags->getDiagnosticLevel(Info.getID(), Info.getLocation(), *this);
+
+ Emitted = (DiagLevel != DiagnosticIDs::Ignored);
+ if (Emitted) {
+ // Emit the diagnostic regardless of suppression level.
+ Diags->EmitDiag(*this, DiagLevel);
+ }
+ } else {
+ // Process the diagnostic, sending the accumulated information to the
+ // DiagnosticConsumer.
+ Emitted = ProcessDiag();
+ }
// Clear out the current diagnostic object.
unsigned DiagID = CurDiagID;
Clear();
// If there was a delayed diagnostic, emit it now.
- if (DelayedDiagID && DelayedDiagID != DiagID)
+ if (!Force && DelayedDiagID && DelayedDiagID != DiagID)
ReportDelayed();
return Emitted;
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index 8c33a96..d00573f 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -357,7 +357,7 @@
return CustomDiagInfo->getLevel(DiagID);
unsigned DiagClass = getBuiltinDiagClass(DiagID);
- assert(DiagClass != CLASS_NOTE && "Cannot get diagnostic level of a note!");
+ if (DiagClass == CLASS_NOTE) return DiagnosticIDs::Note;
return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag);
}
@@ -583,24 +583,9 @@
assert(Diag.getClient() && "DiagnosticClient not set!");
// Figure out the diagnostic level of this message.
- DiagnosticIDs::Level DiagLevel;
unsigned DiagID = Info.getID();
-
- if (DiagID >= diag::DIAG_UPPER_LIMIT) {
- // Handle custom diagnostics, which cannot be mapped.
- DiagLevel = CustomDiagInfo->getLevel(DiagID);
- } else {
- // Get the class of the diagnostic. If this is a NOTE, map it onto whatever
- // the diagnostic level was for the previous diagnostic so that it is
- // filtered the same as the previous diagnostic.
- unsigned DiagClass = getBuiltinDiagClass(DiagID);
- if (DiagClass == CLASS_NOTE) {
- DiagLevel = DiagnosticIDs::Note;
- } else {
- DiagLevel = getDiagnosticLevel(DiagID, DiagClass, Info.getLocation(),
- Diag);
- }
- }
+ DiagnosticIDs::Level DiagLevel
+ = getDiagnosticLevel(DiagID, Info.getLocation(), Diag);
if (DiagLevel != DiagnosticIDs::Note) {
// Record that a fatal error occurred only when we see a second
@@ -658,6 +643,14 @@
}
// Finally, report it.
+ EmitDiag(Diag, DiagLevel);
+ return true;
+}
+
+void DiagnosticIDs::EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const {
+ Diagnostic Info(&Diag);
+ assert(DiagLevel != DiagnosticIDs::Ignored && "Cannot emit ignored diagnostics!");
+
Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info);
if (Diag.Client->IncludeInDiagnosticCounts()) {
if (DiagLevel == DiagnosticIDs::Warning)
@@ -665,8 +658,6 @@
}
Diag.CurDiagID = ~0U;
-
- return true;
}
bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const {
diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp
index 1d9c196..236b700 100644
--- a/lib/Frontend/VerifyDiagnosticConsumer.cpp
+++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp
@@ -387,7 +387,7 @@
OS << ": " << I->second;
}
- Diags.Report(diag::err_verify_inconsistent_diags)
+ Diags.Report(diag::err_verify_inconsistent_diags).setForceEmit()
<< Kind << /*Unexpected=*/true << OS.str();
return std::distance(diag_begin, diag_end);
}
@@ -411,7 +411,7 @@
OS << ": " << D.Text;
}
- Diags.Report(diag::err_verify_inconsistent_diags)
+ Diags.Report(diag::err_verify_inconsistent_diags).setForceEmit()
<< Kind << /*Unexpected=*/false << OS.str();
return DL.size();
}