Skip to content

Commit e83f58f

Browse files
authored
Merge pull request #30028 from martinboehme/verify-fix
If `-verify` mode saw unexpected diagnostics, print diagnostics from all files.
2 parents ae2bef9 + f81ef9c commit e83f58f

File tree

5 files changed

+78
-13
lines changed

5 files changed

+78
-13
lines changed

lib/Frontend/DiagnosticVerifier.cpp

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,26 @@ namespace {
9292
CapturedDiagnostics.push_back(Diag);
9393
}
9494

95+
/// Result of verifying a file.
96+
struct Result {
97+
/// Were there any errors? All of the following are considered errors:
98+
/// - Expected diagnostics that were not present
99+
/// - Unexpected diagnostics that were present
100+
/// - Errors in the definition of expected diagnostics
101+
bool HadError;
102+
bool HadUnexpectedDiag;
103+
};
104+
95105
/// verifyFile - After the file has been processed, check to see if we
96106
/// got all of the expected diagnostics and check to see if there were any
97107
/// unexpected ones.
98-
bool verifyFile(unsigned BufferID, bool autoApplyFixes);
108+
Result verifyFile(unsigned BufferID, bool autoApplyFixes);
99109

100110
/// diagnostics for '<unknown>:0' should be considered as unexpected.
101111
bool verifyUnknown();
102112

113+
void printRemainingDiagnostics() const;
114+
103115
/// If there are any -verify errors (e.g. differences between expectations
104116
/// and actual diagnostics produced), apply fixits to the original source
105117
/// file and drop it back in place.
@@ -210,8 +222,8 @@ static std::string renderFixits(ArrayRef<llvm::SMFixIt> fixits,
210222
/// After the file has been processed, check to see if we got all of
211223
/// the expected diagnostics and check to see if there were any unexpected
212224
/// ones.
213-
bool DiagnosticVerifier::verifyFile(unsigned BufferID,
214-
bool shouldAutoApplyFixes) {
225+
DiagnosticVerifier::Result
226+
DiagnosticVerifier::verifyFile(unsigned BufferID, bool shouldAutoApplyFixes) {
215227
using llvm::SMLoc;
216228

217229
const SourceLoc BufferStartLoc = SM.getLocForBufferStart(BufferID);
@@ -632,15 +644,20 @@ bool DiagnosticVerifier::verifyFile(unsigned BufferID,
632644
}
633645

634646
// Verify that there are no diagnostics (in MemoryBuffer) left in the list.
635-
for (unsigned i = 0, e = CapturedDiagnostics.size(); i != e; ++i) {
636-
if (CapturedDiagnostics[i].getFilename() != BufferName)
647+
bool HadUnexpectedDiag = false;
648+
for (unsigned i = CapturedDiagnostics.size(); i != 0; ) {
649+
--i;
650+
if (CapturedDiagnostics[i].getFilename() != BufferName) {
637651
continue;
652+
}
638653

654+
HadUnexpectedDiag = true;
639655
std::string Message =
640656
"unexpected "+getDiagKindString(CapturedDiagnostics[i].getKind())+
641657
" produced: "+CapturedDiagnostics[i].getMessage().str();
642658
addError(CapturedDiagnostics[i].getLoc().getPointer(),
643659
Message);
660+
CapturedDiagnostics.erase(CapturedDiagnostics.begin() + i);
644661
}
645662

646663
// Sort the diagnostics by their address in the memory buffer as the primary
@@ -659,8 +676,8 @@ bool DiagnosticVerifier::verifyFile(unsigned BufferID,
659676
// If auto-apply fixits is on, rewrite the original source file.
660677
if (shouldAutoApplyFixes)
661678
autoApplyFixes(BufferID, Errors);
662-
663-
return !Errors.empty();
679+
680+
return Result{!Errors.empty(), HadUnexpectedDiag};
664681
}
665682

666683
bool DiagnosticVerifier::verifyUnknown() {
@@ -681,6 +698,15 @@ bool DiagnosticVerifier::verifyUnknown() {
681698
return HadError;
682699
}
683700

701+
void DiagnosticVerifier::printRemainingDiagnostics() const {
702+
for (const auto &diag : CapturedDiagnostics) {
703+
SM.getLLVMSourceMgr().PrintMessage(
704+
llvm::errs(), diag.getLoc(), diag.getKind(),
705+
"diagnostic produced by Clang: " + diag.getMessage(),
706+
/*Ranges=*/ {}, diag.getFixIts());
707+
}
708+
}
709+
684710
/// If there are any -verify errors (e.g. differences between expectations
685711
/// and actual diagnostics produced), apply fixits to the original source
686712
/// file and drop it back in place.
@@ -776,15 +802,26 @@ bool swift::verifyDiagnostics(SourceManager &SM, ArrayRef<unsigned> BufferIDs,
776802
auto *Verifier = (DiagnosticVerifier*)SM.getLLVMSourceMgr().getDiagContext();
777803
SM.getLLVMSourceMgr().setDiagHandler(nullptr, nullptr);
778804

779-
bool HadError = false;
805+
DiagnosticVerifier::Result Result = {false, false};
780806

781-
for (auto &BufferID : BufferIDs)
782-
HadError |= Verifier->verifyFile(BufferID, autoApplyFixes);
783-
if (!ignoreUnknown)
784-
HadError |= Verifier->verifyUnknown();
807+
for (auto &BufferID : BufferIDs) {
808+
DiagnosticVerifier::Result FileResult =
809+
Verifier->verifyFile(BufferID, autoApplyFixes);
810+
Result.HadError |= FileResult.HadError;
811+
Result.HadUnexpectedDiag |= FileResult.HadUnexpectedDiag;
812+
}
813+
if (!ignoreUnknown) {
814+
bool HadError = Verifier->verifyUnknown();
815+
Result.HadError |= HadError;
816+
// For <unknown>, all errors are unexpected.
817+
Result.HadUnexpectedDiag |= HadError;
818+
}
819+
820+
if (Result.HadUnexpectedDiag)
821+
Verifier->printRemainingDiagnostics();
785822

786823
delete Verifier;
787824

788-
return HadError;
825+
return Result.HadError;
789826
}
790827

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// This C code intentionally doesn't compile (note missing semicolon).
2+
void foo()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module BrokenCModule {
2+
header "broken_c.h"
3+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Tests that `-verify` mode outputs diagnostics from a failing C module
2+
// compilation.
3+
// This needs to be a separate test from verify.swift because compilation will
4+
// terminate after the failing import statement.
5+
6+
// RUN: not %target-typecheck-verify-swift -I %S/Inputs/broken-c-module 2>&1 | %FileCheck %s
7+
8+
// CHECK: [[@LINE+3]]:8: error: unexpected error produced: could not build
9+
// CHECK: note: diagnostic produced by Clang: in file included from <module-includes>
10+
// CHECK: broken_c.h:2:11: error: diagnostic produced by Clang: expected function body after function declarator
11+
import BrokenCModule

test/Frontend/verify.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Tests for the Swift frontends `-verify` mode.
2+
3+
// RUN: not %target-typecheck-verify-swift 2>&1 | %FileCheck %s
4+
5+
// CHECK: [[@LINE+1]]:1: error: unexpected error produced: use of unresolved
6+
undefinedFunc()
7+
8+
// CHECK: [[@LINE+1]]:4: error: expected error not produced
9+
// expected-error{{This error message never gets output}}
10+
11+
// CHECK: [[@LINE+1]]:20: error: expected {{{{}} in {{expected}}-{{warning}}
12+
// expected-warning

0 commit comments

Comments
 (0)