mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Emit error diagnostic for a primary if all errors suppressed
This commit is contained in:
@@ -101,6 +101,8 @@ public:
|
||||
|
||||
/// \returns true if an error occurred while finishing-up.
|
||||
virtual bool finishProcessing() { return false; }
|
||||
|
||||
virtual bool hadOnlySuppressedFatalErrors() const { return false; }
|
||||
};
|
||||
|
||||
/// \brief DiagnosticConsumer that discards all diagnostics.
|
||||
@@ -165,6 +167,9 @@ private:
|
||||
/// If null, diagnostics are suppressed.
|
||||
Optional<DiagnosticConsumer *> ConsumerForSubsequentNotes = None;
|
||||
|
||||
bool WasAFatalDiagnosticSuppressed = false;
|
||||
bool WasAFatalDiagnosticEmitted = false;
|
||||
|
||||
public:
|
||||
/// Takes ownership of the DiagnosticConsumers specified in \p consumers.
|
||||
///
|
||||
@@ -181,6 +186,8 @@ public:
|
||||
|
||||
bool finishProcessing() override;
|
||||
|
||||
bool hadOnlySuppressedFatalErrors() const override;
|
||||
|
||||
private:
|
||||
void computeConsumersOrderedByRange(SourceManager &SM);
|
||||
|
||||
|
||||
@@ -768,6 +768,8 @@ namespace swift {
|
||||
ArrayRef<DiagnosticArgument> FormatArgs,
|
||||
DiagnosticFormatOptions FormatOpts = DiagnosticFormatOptions());
|
||||
|
||||
bool hadOnlySuppressedFatalErrors() const;
|
||||
|
||||
private:
|
||||
/// \brief Flush the active diagnostic.
|
||||
void flushActiveDiagnostic();
|
||||
|
||||
@@ -235,6 +235,8 @@ WARNING(cannot_assign_value_to_conditional_compilation_flag,none,
|
||||
ERROR(error_optimization_remark_pattern, none, "%0 in '%1'",
|
||||
(StringRef, StringRef))
|
||||
|
||||
ERROR(error_compilation_failed,none, "compilation failed", ())
|
||||
|
||||
#ifndef DIAG_NO_UNDEF
|
||||
# if defined(DIAG)
|
||||
# undef DIAG
|
||||
|
||||
@@ -176,17 +176,25 @@ void FileSpecificDiagnosticConsumer::handleDiagnostic(
|
||||
break;
|
||||
}
|
||||
|
||||
const bool isErrorFatal = Kind == DiagnosticKind::Error;
|
||||
if (!specificConsumer.hasValue()) {
|
||||
for (auto &subConsumer : SubConsumers) {
|
||||
if (subConsumer.second) {
|
||||
subConsumer.second->handleDiagnostic(SM, Loc, Kind, FormatString,
|
||||
FormatArgs, Info);
|
||||
WasAFatalDiagnosticEmitted |= isErrorFatal;
|
||||
}
|
||||
}
|
||||
} else if (DiagnosticConsumer *c = specificConsumer.getValue())
|
||||
} else if (DiagnosticConsumer *c = specificConsumer.getValue()) {
|
||||
c->handleDiagnostic(SM, Loc, Kind, FormatString, FormatArgs, Info);
|
||||
else
|
||||
; // Suppress non-primary diagnostic in batch mode.
|
||||
WasAFatalDiagnosticEmitted |= isErrorFatal;
|
||||
} else { // Suppress non-primary diagnostic in batch mode.
|
||||
WasAFatalDiagnosticSuppressed |= isErrorFatal;
|
||||
}
|
||||
}
|
||||
|
||||
bool FileSpecificDiagnosticConsumer::hadOnlySuppressedFatalErrors() const {
|
||||
return WasAFatalDiagnosticSuppressed && !WasAFatalDiagnosticEmitted;
|
||||
}
|
||||
|
||||
bool FileSpecificDiagnosticConsumer::finishProcessing() {
|
||||
|
||||
@@ -259,6 +259,14 @@ bool DiagnosticEngine::finishProcessing() {
|
||||
return hadError;
|
||||
}
|
||||
|
||||
bool DiagnosticEngine::hadOnlySuppressedFatalErrors() const {
|
||||
for (auto &Consumer : Consumers) {
|
||||
if (Consumer->hadOnlySuppressedFatalErrors())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief Skip forward to one of the given delimiters.
|
||||
///
|
||||
/// \param Text The text to search through, which will be updated to point
|
||||
|
||||
@@ -1651,6 +1651,9 @@ int swift::performFrontend(ArrayRef<const char *> Args,
|
||||
|
||||
auto finishDiagProcessing = [&](int retValue) -> int {
|
||||
FinishDiagProcessingCheckRAII.CalledFinishDiagProcessing = true;
|
||||
if (Instance->getDiags().hadOnlySuppressedFatalErrors())
|
||||
Instance->getDiags().diagnose(SourceLoc(),
|
||||
diag::error_compilation_failed);
|
||||
bool err = Instance->getDiags().finishProcessing();
|
||||
return retValue ? retValue : err;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// To avoid redundant diagnostics showing up in Xcode, batch-mode must suppress diagnostics in
|
||||
// non-primary files.
|
||||
// But if the only fatal errors are suppressed ones, a "compilation failed" error must be emitted
|
||||
// for the primary files so Xcode knows something happened.
|
||||
//
|
||||
// RUN: rm -f %t.*
|
||||
|
||||
// RUN: not %target-swift-frontend -typecheck -primary-file %s -serialize-diagnostics-path %t.main.dia -primary-file %S/../Inputs/empty.swift -serialize-diagnostics-path %t.empty.dia %S/Inputs/serialized-diagnostics-batch-mode-suppression-helper.swift 2> %t.stderr.txt
|
||||
// RUN: c-index-test -read-diagnostics %t.main.dia 2> %t.main.txt
|
||||
// RUN: c-index-test -read-diagnostics %t.empty.dia 2> %t.empty.txt
|
||||
|
||||
// Ensure there was an error:
|
||||
|
||||
// RUN: %FileCheck -check-prefix=ERROR %s <%t.stderr.txt
|
||||
// ERROR: error:
|
||||
|
||||
// Ensure the error is in the serialized diagnostics:
|
||||
|
||||
// RUN: %FileCheck -check-prefix=COMPILATION-FAILED %s <%t.main.txt
|
||||
// RUN: %FileCheck -check-prefix=COMPILATION-FAILED %s <%t.empty.txt
|
||||
// COMPILATION-FAILED: compilation failed
|
||||
|
||||
func test(x: SomeType) {
|
||||
}
|
||||
@@ -7,20 +7,11 @@
|
||||
// RUN: c-index-test -read-diagnostics %t.main.dia 2> %t.main.txt
|
||||
// RUN: c-index-test -read-diagnostics %t.empty.dia 2> %t.empty.txt
|
||||
|
||||
// Ensure there was an error:
|
||||
// RUN: %FileCheck -check-prefix=NO-COMPILATION-FAILED %s <%t.main.txt
|
||||
// RUN: %FileCheck -check-prefix=NO-COMPILATION-FAILED %s <%t.empty.txt
|
||||
// NO-COMPILATION-FAILED-NOT: compilation failed
|
||||
|
||||
// RUN: %FileCheck -check-prefix=ERROR %s <%t.stderr.txt
|
||||
// ERROR: error:
|
||||
|
||||
// Ensure the error is not in the serialized diagnostics:
|
||||
|
||||
// RUN: %FileCheck -check-prefix=NO-DIAGNOSTICS %s <%t.main.txt
|
||||
// RUN: %FileCheck -check-prefix=NO-DIAGNOSTICS %s <%t.empty.txt
|
||||
// NO-DIAGNOSTICS: Number of diagnostics: 0
|
||||
|
||||
// RUN: %FileCheck -check-prefix=NO-ERROR %s <%t.main.txt
|
||||
// RUN: %FileCheck -check-prefix=NO-ERROR %s <%t.empty.txt
|
||||
// NO-ERROR-NOT: error:
|
||||
|
||||
func test(x: SomeType) {
|
||||
nonexistant(); // create a fatal error here
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user