[flang-commits] [flang] b3c72a9 - [flang][driver] -Werror promotes warnings to error and interopts with -Wfatal-errors (#148748)
via flang-commits
flang-commits at lists.llvm.org
Wed Jul 16 12:26:41 PDT 2025
Author: Andre Kuhlenschmidt
Date: 2025-07-16T12:26:38-07:00
New Revision: b3c72a97c5ac352b89c12f3cf7c3f223219f91ed
URL: https://github.com/llvm/llvm-project/commit/b3c72a97c5ac352b89c12f3cf7c3f223219f91ed
DIFF: https://github.com/llvm/llvm-project/commit/b3c72a97c5ac352b89c12f3cf7c3f223219f91ed.diff
LOG: [flang][driver] -Werror promotes warnings to error and interopts with -Wfatal-errors (#148748)
This PR changes how `-Werror` promotes warnings to errors so that it
interoperates with `-Wfatal-error`. It maintains the property that
warnings and other messages promoted to errors are displayed as there
original message.
Added:
flang/test/Driver/fatal-errors-warnings.f90
Modified:
flang/include/flang/Parser/message.h
flang/lib/Frontend/FrontendAction.cpp
flang/lib/Parser/message.cpp
flang/lib/Semantics/semantics.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Parser/message.h b/flang/include/flang/Parser/message.h
index db1a0a65157e3..9192d23529913 100644
--- a/flang/include/flang/Parser/message.h
+++ b/flang/include/flang/Parser/message.h
@@ -355,9 +355,9 @@ class Messages {
void Emit(llvm::raw_ostream &, const AllCookedSources &,
bool echoSourceLines = true,
const common::LanguageFeatureControl *hintFlags = nullptr,
- std::size_t maxErrorsToEmit = 0) const;
+ std::size_t maxErrorsToEmit = 0, bool warningsAreErrors = false) const;
void AttachTo(Message &, std::optional<Severity> = std::nullopt);
- bool AnyFatalError() const;
+ bool AnyFatalError(bool warningsAreErrors = false) const;
private:
std::list<Message> messages_;
diff --git a/flang/lib/Frontend/FrontendAction.cpp b/flang/lib/Frontend/FrontendAction.cpp
index 2429e07e5b8c4..58901c6000380 100644
--- a/flang/lib/Frontend/FrontendAction.cpp
+++ b/flang/lib/Frontend/FrontendAction.cpp
@@ -230,15 +230,14 @@ bool FrontendAction::reportFatalErrors(const char (&message)[N]) {
const common::LanguageFeatureControl &features{
instance->getInvocation().getFortranOpts().features};
const size_t maxErrors{instance->getInvocation().getMaxErrors()};
- if (!instance->getParsing().messages().empty() &&
- (instance->getInvocation().getWarnAsErr() ||
- instance->getParsing().messages().AnyFatalError())) {
+ const bool warningsAreErrors{instance->getInvocation().getWarnAsErr()};
+ if (instance->getParsing().messages().AnyFatalError(warningsAreErrors)) {
const unsigned diagID = instance->getDiagnostics().getCustomDiagID(
clang::DiagnosticsEngine::Error, message);
instance->getDiagnostics().Report(diagID) << getCurrentFileOrBufferName();
instance->getParsing().messages().Emit(
llvm::errs(), instance->getAllCookedSources(),
- /*echoSourceLines=*/true, &features, maxErrors);
+ /*echoSourceLines=*/true, &features, maxErrors, warningsAreErrors);
return true;
}
if (instance->getParsing().parseTree().has_value() &&
@@ -249,7 +248,7 @@ bool FrontendAction::reportFatalErrors(const char (&message)[N]) {
instance->getDiagnostics().Report(diagID) << getCurrentFileOrBufferName();
instance->getParsing().messages().Emit(
llvm::errs(), instance->getAllCookedSources(),
- /*echoSourceLine=*/true, &features, maxErrors);
+ /*echoSourceLine=*/true, &features, maxErrors, warningsAreErrors);
instance->getParsing().EmitMessage(
llvm::errs(), instance->getParsing().finalRestingPlace(),
"parser FAIL (final position)", "error: ", llvm::raw_ostream::RED);
diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp
index 909fba948a45a..2a8101dd0b810 100644
--- a/flang/lib/Parser/message.cpp
+++ b/flang/lib/Parser/message.cpp
@@ -453,7 +453,7 @@ void Messages::ResolveProvenances(const AllCookedSources &allCooked) {
void Messages::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
bool echoSourceLines, const common::LanguageFeatureControl *hintFlagPtr,
- std::size_t maxErrorsToEmit) const {
+ std::size_t maxErrorsToEmit, bool warningsAreErrors) const {
std::vector<const Message *> sorted;
for (const auto &msg : messages_) {
sorted.push_back(&msg);
@@ -469,7 +469,7 @@ void Messages::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
}
msg->Emit(o, allCooked, echoSourceLines, hintFlagPtr);
lastMsg = msg;
- if (msg->IsFatal()) {
+ if (warningsAreErrors || msg->IsFatal()) {
++errorsEmitted;
}
// If maxErrorsToEmit is 0, emit all errors, otherwise break after
@@ -491,7 +491,18 @@ void Messages::AttachTo(Message &msg, std::optional<Severity> severity) {
messages_.clear();
}
-bool Messages::AnyFatalError() const {
+bool Messages::AnyFatalError(bool warningsAreErrors) const {
+ // Short-circuit in the most common case.
+ if (messages_.empty()) {
+ return false;
+ }
+ // If warnings are errors and there are warnings or errors, this is fatal.
+ // This preserves the compiler's current behavior of treating any non-fatal
+ // message as a warning. We may want to refine this in the future.
+ if (warningsAreErrors) {
+ return true;
+ }
+ // Otherwise, check the message buffer for fatal errors.
for (const auto &msg : messages_) {
if (msg.IsFatal()) {
return true;
diff --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp
index ab78605d01f4c..b15ed057b52f2 100644
--- a/flang/lib/Semantics/semantics.cpp
+++ b/flang/lib/Semantics/semantics.cpp
@@ -376,8 +376,7 @@ const DeclTypeSpec &SemanticsContext::MakeLogicalType(int kind) {
}
bool SemanticsContext::AnyFatalError() const {
- return !messages_.empty() &&
- (warningsAreErrors_ || messages_.AnyFatalError());
+ return messages_.AnyFatalError(warningsAreErrors_);
}
bool SemanticsContext::HasError(const Symbol &symbol) {
return errorSymbols_.count(symbol) > 0;
@@ -658,7 +657,7 @@ void Semantics::EmitMessages(llvm::raw_ostream &os) {
context_.messages().ResolveProvenances(context_.allCookedSources());
context_.messages().Emit(os, context_.allCookedSources(),
/*echoSourceLine=*/true, &context_.languageFeatures(),
- /*maxErrorsToEmit=*/context_.maxErrors());
+ context_.maxErrors(), context_.warningsAreErrors());
}
void SemanticsContext::DumpSymbols(llvm::raw_ostream &os) {
diff --git a/flang/test/Driver/fatal-errors-warnings.f90 b/flang/test/Driver/fatal-errors-warnings.f90
new file mode 100644
index 0000000000000..2de09c3ed0778
--- /dev/null
+++ b/flang/test/Driver/fatal-errors-warnings.f90
@@ -0,0 +1,31 @@
+! RUN: %flang_fc1 -Wfatal-errors -pedantic %s 2>&1 | FileCheck %s --check-prefix=CHECK1
+! RUN: not %flang_fc1 -pedantic -Werror %s 2>&1 | FileCheck %s --check-prefix=CHECK2
+! RUN: not %flang_fc1 -Wfatal-errors -pedantic -Werror %s 2>&1 | FileCheck %s --check-prefix=CHECK3
+
+module m
+ contains
+ subroutine foo(a)
+ real, intent(in), target :: a(:)
+ end subroutine
+end module
+
+program test
+ use m
+ real, target :: a(1)
+ real :: b(1)
+ call foo(a) ! ok
+ !CHECK1: fatal-errors-warnings.f90:{{.*}} warning:
+ !CHECK2: fatal-errors-warnings.f90:{{.*}} warning:
+ !CHECK3: fatal-errors-warnings.f90:{{.*}} warning:
+ call foo(b)
+ !CHECK1: fatal-errors-warnings.f90:{{.*}} warning:
+ !CHECK2: fatal-errors-warnings.f90:{{.*}} warning:
+ !CHECK3-NOT: error:
+ !CHECK3-NOT: warning:
+ call foo((a))
+ !CHECK1: fatal-errors-warnings.f90:{{.*}} warning:
+ !CHECK2: fatal-errors-warnings.f90:{{.*}} warning:
+ call foo(a([1]))
+ !! Hard error instead of warning if uncommented.
+ !call foo(a(1))
+end
\ No newline at end of file
More information about the flang-commits
mailing list