Author: arphaman Date: Thu May 4 08:56:51 2017 New Revision: 302151 URL: http://llvm.org/viewvc/llvm-project?rev=302151&view=rev Log: DiagnosticsEngine should clear DelayedDiagID before reporting the delayed diagnostic
This fix avoids an infinite recursion that was uncovered in one of our internal tests by r301992. The testcase is the most reduced version of that auto-generated test. This is an improved version of the reverted commit r302037. The previous fix actually managed to expose another subtle bug whereby `fatal_too_many_errors` error was reported twice, with the second report setting the `FatalErrorOccurred` flag. That prevented the notes that followed the diagnostic the caused `fatal_too_many_errors` to be emitted. This commit ensures that notes that follow `fatal_too_many_errors` but that belong to the diagnostic that caused `fatal_too_many_errors` won't be emitted by setting the `FatalErrorOccurred` when emitting `fatal_too_many_errors`. rdar://31962618 Added: cfe/trunk/test/Index/KeepGoingWithLotsOfErrors.mm Modified: cfe/trunk/lib/Basic/Diagnostic.cpp cfe/trunk/lib/Basic/DiagnosticIDs.cpp Modified: cfe/trunk/lib/Basic/Diagnostic.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=302151&r1=302150&r2=302151&view=diff ============================================================================== --- cfe/trunk/lib/Basic/Diagnostic.cpp (original) +++ cfe/trunk/lib/Basic/Diagnostic.cpp Thu May 4 08:56:51 2017 @@ -146,10 +146,9 @@ void DiagnosticsEngine::SetDelayedDiagno } void DiagnosticsEngine::ReportDelayed() { - Report(DelayedDiagID) << DelayedDiagArg1 << DelayedDiagArg2; + unsigned ID = DelayedDiagID; DelayedDiagID = 0; - DelayedDiagArg1.clear(); - DelayedDiagArg2.clear(); + Report(ID) << DelayedDiagArg1 << DelayedDiagArg2; } void DiagnosticsEngine::DiagStateMap::appendFirst( @@ -420,11 +419,10 @@ bool DiagnosticsEngine::EmitCurrentDiagn } // Clear out the current diagnostic object. - unsigned DiagID = CurDiagID; Clear(); // If there was a delayed diagnostic, emit it now. - if (!Force && DelayedDiagID && DelayedDiagID != DiagID) + if (!Force && DelayedDiagID) ReportDelayed(); return Emitted; Modified: cfe/trunk/lib/Basic/DiagnosticIDs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/DiagnosticIDs.cpp?rev=302151&r1=302150&r2=302151&view=diff ============================================================================== --- cfe/trunk/lib/Basic/DiagnosticIDs.cpp (original) +++ cfe/trunk/lib/Basic/DiagnosticIDs.cpp Thu May 4 08:56:51 2017 @@ -666,6 +666,10 @@ bool DiagnosticIDs::ProcessDiag(Diagnost } } + // Make sure we set FatalErrorOccurred to ensure that the notes from the + // diagnostic that caused `fatal_too_many_errors` won't be emitted. + if (Diag.CurDiagID == diag::fatal_too_many_errors) + Diag.FatalErrorOccurred = true; // Finally, report it. EmitDiag(Diag, DiagLevel); return true; Added: cfe/trunk/test/Index/KeepGoingWithLotsOfErrors.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/KeepGoingWithLotsOfErrors.mm?rev=302151&view=auto ============================================================================== --- cfe/trunk/test/Index/KeepGoingWithLotsOfErrors.mm (added) +++ cfe/trunk/test/Index/KeepGoingWithLotsOfErrors.mm Thu May 4 08:56:51 2017 @@ -0,0 +1,29 @@ +// RUN: env CINDEXTEST_KEEP_GOING=1 c-index-test -code-completion-at=%s:25:1 %s +// Shouldn't crash! +// This is the minimized test that triggered an infinite recursion: + ++(BOOL) onEntity { +} + +-(const Object &) a_200 { +} + +-(int) struct { +} + +-(int) bar { +} + +-(int) part { +} + ++(some_type_t) piece { +} + ++(void) z_Z_42 { + ([self onEntity: [] { 42]; + } class: ^ { } +]; + [super]; + BOOL struct; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits