Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions flang/include/flang/Parser/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
Expand Down
9 changes: 4 additions & 5 deletions flang/lib/Frontend/FrontendAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() &&
Expand All @@ -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);
Expand Down
12 changes: 9 additions & 3 deletions flang/lib/Parser/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand All @@ -491,7 +491,13 @@ void Messages::AttachTo(Message &msg, std::optional<Severity> severity) {
messages_.clear();
}

bool Messages::AnyFatalError() const {
bool Messages::AnyFatalError(bool warningsAreErrors) const {
if (messages_.empty()) {
return false;
}
if (warningsAreErrors) {
return true;
}
for (const auto &msg : messages_) {
if (msg.IsFatal()) {
return true;
Expand Down
5 changes: 2 additions & 3 deletions flang/lib/Semantics/semantics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
31 changes: 31 additions & 0 deletions flang/test/Driver/fatal-errors-warnings.f90
Original file line number Diff line number Diff line change
@@ -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