diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -888,7 +888,10 @@ StringRef Arg2 = "", StringRef Arg3 = ""); /// Clear out the current diagnostic. - void Clear() { CurDiagID = std::numeric_limits::max(); } + void Clear() { + CurDiagID = std::numeric_limits::max(); + CurDelayedDiagID = 0; + } /// Return the value associated with this diagnostic flag. StringRef getFlagValue() const { return FlagValue; } @@ -918,6 +921,11 @@ /// diagnostic in flight. unsigned CurDiagID; + /// The ID of the current delayed diagnostic being reported. + // + // This is set to 0 when there is no delayed diagnostic in flight + unsigned CurDelayedDiagID; + enum { /// The maximum number of arguments we can hold. /// diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -132,6 +132,7 @@ CurDiagID = std::numeric_limits::max(); LastDiagLevel = DiagnosticIDs::Ignored; DelayedDiagID = 0; + CurDelayedDiagID = 0; // Clear state related to #pragma diagnostic. DiagStates.clear(); @@ -146,7 +147,7 @@ void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1, StringRef Arg2, StringRef Arg3) { - if (DelayedDiagID) + if (CurDelayedDiagID || DelayedDiagID) return; DelayedDiagID = DiagID; @@ -156,9 +157,11 @@ } void DiagnosticsEngine::ReportDelayed() { - unsigned ID = DelayedDiagID; + CurDelayedDiagID = DelayedDiagID; DelayedDiagID = 0; - Report(ID) << DelayedDiagArg1 << DelayedDiagArg2 << DelayedDiagArg3; + Report(CurDelayedDiagID) << DelayedDiagArg1 << DelayedDiagArg2 + << DelayedDiagArg3; + CurDelayedDiagID = 0; } void DiagnosticsEngine::DiagStateMap::appendFirst(DiagState *State) { @@ -521,7 +524,9 @@ Clear(); // If there was a delayed diagnostic, emit it now. - if (!Force && DelayedDiagID) + // unless we are currently emitting a delayed diagnostic, + // as that leads to the potential of endless reporting. + if (!Force && DelayedDiagID && !CurDelayedDiagID) ReportDelayed(); return Emitted;