Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
35 changes: 27 additions & 8 deletions flang/include/flang/Parser/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,18 @@ class MessageFixedText {
severity_ = severity;
return *this;
}
bool IsFatal() const {
return severity_ == Severity::Error || severity_ == Severity::Todo;
// This is currently emulating how the frontend is currently handling other
// diagnostic messages. We may want to be more nuanced in the future.
Severity EffectiveSeverity(bool warningsAreErrors) const {
if (warningsAreErrors) {
return Severity::Error;
} else {
return severity_;
}
}
bool IsFatal(bool warningsAreErrors = false) const {
Severity sev{EffectiveSeverity(warningsAreErrors)};
return sev == Severity::Error || sev == Severity::Todo;
}

private:
Expand Down Expand Up @@ -113,14 +123,22 @@ class MessageFormattedText {
MessageFormattedText &operator=(const MessageFormattedText &) = default;
MessageFormattedText &operator=(MessageFormattedText &&) = default;
const std::string &string() const { return string_; }
bool IsFatal() const {
return severity_ == Severity::Error || severity_ == Severity::Todo;
}
Severity severity() const { return severity_; }
MessageFormattedText &set_severity(Severity severity) {
severity_ = severity;
return *this;
}
Severity EffectiveSeverity(bool warningsAreErrors) const {
if (warningsAreErrors) {
return Severity::Error;
} else {
return severity_;
}
}
bool IsFatal(bool warningsAreErrors = false) const {
Severity sev{EffectiveSeverity(warningsAreErrors)};
return sev == Severity::Error || sev == Severity::Todo;
}
std::string MoveString() { return std::move(string_); }
bool operator==(const MessageFormattedText &that) const {
return severity_ == that.severity_ && string_ == that.string_;
Expand Down Expand Up @@ -281,7 +299,8 @@ class Message : public common::ReferenceCounted<Message> {
}

bool SortBefore(const Message &that) const;
bool IsFatal() const;
bool IsFatal(bool warningsAreErrors = false) const;
Severity EffectiveSeverity(bool warningsAreErrors) const;
Severity severity() const;
Message &set_severity(Severity);
std::optional<common::LanguageFeature> languageFeature() const;
Expand Down Expand Up @@ -355,9 +374,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
32 changes: 26 additions & 6 deletions flang/lib/Parser/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,23 @@ bool Message::SortBefore(const Message &that) const {
location_, that.location_);
}

bool Message::IsFatal() const {
return severity() == Severity::Error || severity() == Severity::Todo;
Severity Message::EffectiveSeverity(bool warningsAreErrors) const {
return common::visit(
common::visitors{
[](const MessageExpectedText &) { return Severity::Error; },
[=](const MessageFixedText &x) {
return x.EffectiveSeverity(warningsAreErrors);
},
[=](const MessageFormattedText &x) {
return x.EffectiveSeverity(warningsAreErrors);
},
},
text_);
}

bool Message::IsFatal(bool warningsAreErrors) const {
Severity sev{EffectiveSeverity(warningsAreErrors)};
return sev == Severity::Error || sev == Severity::Todo;
}

Severity Message::severity() const {
Expand Down Expand Up @@ -294,6 +309,8 @@ static std::string HintLanguageControlFlag(
static constexpr int MAX_CONTEXTS_EMITTED{2};
static constexpr bool OMIT_SHARED_CONTEXTS{true};

// We think it is confusing to users to display warnings and other
// diagnostics as errors. Don't use EffectiveSeverity() here.
void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
bool echoSourceLine,
const common::LanguageFeatureControl *hintFlagPtr) const {
Expand Down Expand Up @@ -453,7 +470,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 +486,7 @@ void Messages::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
}
msg->Emit(o, allCooked, echoSourceLines, hintFlagPtr);
lastMsg = msg;
if (msg->IsFatal()) {
if (msg->IsFatal(warningsAreErrors)) {
++errorsEmitted;
}
// If maxErrorsToEmit is 0, emit all errors, otherwise break after
Expand All @@ -491,9 +508,12 @@ 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;
}
for (const auto &msg : messages_) {
if (msg.IsFatal()) {
if (msg.IsFatal(warningsAreErrors)) {
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
Loading