Skip to content

Commit

Permalink
[flang] Add nonfatal message classes
Browse files Browse the repository at this point in the history
F18 presently has fatal and non-fatal diagnostic messages.  We'd like
to make non-fatal warnings stand out better in the output of the compiler.

This will turn out to be a large change that affects many files.
This patch is just the first part.  It converts a Boolean isFatal_ data
member of the message classes into a severity code, and defines four
of these codes (Error, Warning, Portability, and a catch-all Other).

Later patches will result from sweeping over the parser and semantics,
changing most non-fatal diagnostic messages into warnings and portability
notes.

Differential Revision: https://reviews.llvm.org/D121228
  • Loading branch information
klausler committed Mar 8, 2022
1 parent 1712254 commit 2895771
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 35 deletions.
18 changes: 14 additions & 4 deletions flang/docs/Parsing.md
Expand Up @@ -133,10 +133,20 @@ indicators within the parser and in the parse tree.

Message texts, and snprintf-like formatting strings for constructing
messages, are instantiated in the various components of the parser with
C++ user defined character literals tagged with `_err_en_US` and `_en_US`
(signifying fatality and language, with the default being the dialect of
English used in the United States) so that they may be easily identified
for localization. As described above, messages are associated with
C++ user defined character literals tagged with `_err_en_US`, `_warn_en_US`,
`port_en_US`, and `_en_US` to signify severity and language; the default
language is the dialect of English used in the United States.

All "fatal" errors that do not immediately abort compilation but do
prevent the generation of binary and module files are `_err_en_US`.
Warnings about detected flaws in the program that probably indicate
problems worth attention are `_warn_en_US`.
Non-conforming extensions, legacy features, and obsolescent or deleted
features will raise `_port_en_US` messages when those are enabled.
Other messages have a simple `_en_US` suffix, including all messages
that are explanatory attachments.

As described above, messages are associated with
source code positions by means of provenance values.

## The Parse Tree
Expand Down
41 changes: 27 additions & 14 deletions flang/include/flang/Parser/message.h
Expand Up @@ -29,34 +29,45 @@

namespace Fortran::parser {

// Use "..."_err_en_US and "..."_en_US literals to define the static
// text and fatality of a message.
// Use "..."_err_en_US, "..."_warn_en_US, and "..."_en_US literals to define
// the static text and fatality of a message.
enum class Severity { Error, Warning, Portability, None };

class MessageFixedText {
public:
constexpr MessageFixedText() {}
constexpr MessageFixedText(
const char str[], std::size_t n, bool isFatal = false)
: text_{str, n}, isFatal_{isFatal} {}
const char str[], std::size_t n, Severity severity = Severity::None)
: text_{str, n}, severity_{severity} {}
constexpr MessageFixedText(const MessageFixedText &) = default;
constexpr MessageFixedText(MessageFixedText &&) = default;
constexpr MessageFixedText &operator=(const MessageFixedText &) = default;
constexpr MessageFixedText &operator=(MessageFixedText &&) = default;

CharBlock text() const { return text_; }
bool isFatal() const { return isFatal_; }
Severity severity() const { return severity_; }
bool isFatal() const { return severity_ == Severity::Error; }

private:
CharBlock text_;
bool isFatal_{false};
Severity severity_{Severity::None};
};

inline namespace literals {
constexpr MessageFixedText operator""_en_US(const char str[], std::size_t n) {
return MessageFixedText{str, n, false /* not fatal */};
}

constexpr MessageFixedText operator""_err_en_US(
const char str[], std::size_t n) {
return MessageFixedText{str, n, true /* fatal */};
return MessageFixedText{str, n, Severity::Error};
}
constexpr MessageFixedText operator""_warn_en_US(
const char str[], std::size_t n) {
return MessageFixedText{str, n, Severity::Warning};
}
constexpr MessageFixedText operator""_port_en_US(
const char str[], std::size_t n) {
return MessageFixedText{str, n, Severity::Portability};
}
constexpr MessageFixedText operator""_en_US(const char str[], std::size_t n) {
return MessageFixedText{str, n, Severity::None};
}
} // namespace literals

Expand All @@ -69,15 +80,16 @@ class MessageFormattedText {
public:
template <typename... A>
MessageFormattedText(const MessageFixedText &text, A &&...x)
: isFatal_{text.isFatal()} {
: severity_{text.severity()} {
Format(&text, Convert(std::forward<A>(x))...);
}
MessageFormattedText(const MessageFormattedText &) = default;
MessageFormattedText(MessageFormattedText &&) = default;
MessageFormattedText &operator=(const MessageFormattedText &) = default;
MessageFormattedText &operator=(MessageFormattedText &&) = default;
const std::string &string() const { return string_; }
bool isFatal() const { return isFatal_; }
bool isFatal() const { return severity_ == Severity::Error; }
Severity severity() const { return severity_; }
std::string MoveString() { return std::move(string_); }

private:
Expand All @@ -104,7 +116,7 @@ class MessageFormattedText {
std::intmax_t Convert(std::int64_t x) { return x; }
std::uintmax_t Convert(std::uint64_t x) { return x; }

bool isFatal_{false};
Severity severity_;
std::string string_;
std::forward_list<std::string> conversions_; // preserves created strings
};
Expand Down Expand Up @@ -186,6 +198,7 @@ class Message : public common::ReferenceCounted<Message> {

bool SortBefore(const Message &that) const;
bool IsFatal() const;
Severity severity() const;
std::string ToString() const;
std::optional<ProvenanceRange> GetProvenanceRange(
const AllCookedSources &) const;
Expand Down
24 changes: 18 additions & 6 deletions flang/lib/Parser/message.cpp
Expand Up @@ -155,12 +155,14 @@ bool Message::SortBefore(const Message &that) const {
location_, that.location_);
}

bool Message::IsFatal() const {
bool Message::IsFatal() const { return severity() == Severity::Error; }

Severity Message::severity() const {
return std::visit(
common::visitors{
[](const MessageExpectedText &) { return true; },
[](const MessageFixedText &x) { return x.isFatal(); },
[](const MessageFormattedText &x) { return x.isFatal(); },
[](const MessageExpectedText &) { return Severity::Error; },
[](const MessageFixedText &x) { return x.severity(); },
[](const MessageFormattedText &x) { return x.severity(); },
},
text_);
}
Expand Down Expand Up @@ -203,8 +205,18 @@ void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
bool echoSourceLine) const {
std::optional<ProvenanceRange> provenanceRange{GetProvenanceRange(allCooked)};
std::string text;
if (IsFatal()) {
text += "error: ";
switch (severity()) {
case Severity::Error:
text = "error: ";
break;
case Severity::Warning:
text = "warning: ";
break;
case Severity::Portability:
text = "portability: ";
break;
case Severity::None:
break;
}
text += ToString();
const AllSources &sources{allCooked.allSources()};
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Semantics/check-io.cpp
Expand Up @@ -38,7 +38,8 @@ bool FormatErrorReporter::Say(const common::FormatMessage &msg) {
return false;
}
parser::MessageFormattedText text{
parser::MessageFixedText(msg.text, strlen(msg.text), msg.isError),
parser::MessageFixedText{msg.text, strlen(msg.text),
msg.isError ? parser::Severity::Error : parser::Severity::Warning},
msg.arg};
if (formatCharBlock_.size()) {
// The input format is a folded expression. Error markers span the full
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Semantics/mod-file.cpp
Expand Up @@ -946,7 +946,8 @@ Scope *ModFileReader::Read(const SourceName &name,
for (auto &msg : parsing.messages().messages()) {
std::string str{msg.ToString()};
Say(name, ancestorName,
parser::MessageFixedText{str.c_str(), str.size()}, path);
parser::MessageFixedText{str.c_str(), str.size(), msg.severity()},
path);
}
}
return nullptr;
Expand Down
8 changes: 4 additions & 4 deletions flang/lib/Semantics/resolve-names-utils.cpp
Expand Up @@ -44,10 +44,10 @@ Symbol &Resolve(const parser::Name &name, Symbol &symbol) {
return *Resolve(name, &symbol);
}

parser::MessageFixedText WithIsFatal(
const parser::MessageFixedText &msg, bool isFatal) {
parser::MessageFixedText WithSeverity(
const parser::MessageFixedText &msg, parser::Severity severity) {
return parser::MessageFixedText{
msg.text().begin(), msg.text().size(), isFatal};
msg.text().begin(), msg.text().size(), severity};
}

bool IsIntrinsicOperator(
Expand Down Expand Up @@ -576,7 +576,7 @@ bool EquivalenceSets::CheckObject(const parser::Name &name) {
return false; // an error has already occurred
}
currObject_.symbol = name.symbol;
parser::MessageFixedText msg{"", 0};
parser::MessageFixedText msg;
const Symbol &symbol{*name.symbol};
if (symbol.owner().IsDerivedType()) { // C8107
msg = "Derived type component '%s'"
Expand Down
6 changes: 3 additions & 3 deletions flang/lib/Semantics/resolve-names-utils.h
Expand Up @@ -44,9 +44,9 @@ class SemanticsContext;
Symbol &Resolve(const parser::Name &, Symbol &);
Symbol *Resolve(const parser::Name &, Symbol *);

// Create a copy of msg with a new isFatal value.
parser::MessageFixedText WithIsFatal(
const parser::MessageFixedText &msg, bool isFatal);
// Create a copy of msg with a new severity.
parser::MessageFixedText WithSeverity(
const parser::MessageFixedText &msg, parser::Severity);

bool IsIntrinsicOperator(const SemanticsContext &, const SourceName &);
bool IsLogicalConstant(const SemanticsContext &, const SourceName &);
Expand Down
4 changes: 2 additions & 2 deletions flang/lib/Semantics/resolve-names.cpp
Expand Up @@ -6654,9 +6654,9 @@ Symbol &ModuleVisitor::SetAccess(
// PUBLIC/PRIVATE already set: make it a fatal error if it changed
Attr prev = attrs.test(Attr::PUBLIC) ? Attr::PUBLIC : Attr::PRIVATE;
Say(name,
WithIsFatal(
WithSeverity(
"The accessibility of '%s' has already been specified as %s"_en_US,
attr != prev),
attr != prev ? parser::Severity::Error : parser::Severity::Warning),
MakeOpName(name), EnumToString(prev));
} else {
attrs.set(attr);
Expand Down

0 comments on commit 2895771

Please sign in to comment.