[flang-commits] [flang] 2895771 - [flang] Add nonfatal message classes

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Tue Mar 8 11:40:53 PST 2022


Author: Peter Klausler
Date: 2022-03-08T11:40:45-08:00
New Revision: 2895771faf4f8e63fabeb6f35fd5b70b925b0234

URL: https://github.com/llvm/llvm-project/commit/2895771faf4f8e63fabeb6f35fd5b70b925b0234
DIFF: https://github.com/llvm/llvm-project/commit/2895771faf4f8e63fabeb6f35fd5b70b925b0234.diff

LOG: [flang] Add nonfatal message classes

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

Added: 
    

Modified: 
    flang/docs/Parsing.md
    flang/include/flang/Parser/message.h
    flang/lib/Parser/message.cpp
    flang/lib/Semantics/check-io.cpp
    flang/lib/Semantics/mod-file.cpp
    flang/lib/Semantics/resolve-names-utils.cpp
    flang/lib/Semantics/resolve-names-utils.h
    flang/lib/Semantics/resolve-names.cpp

Removed: 
    


################################################################################
diff  --git a/flang/docs/Parsing.md b/flang/docs/Parsing.md
index dec63e6fbdab4..172a13946601e 100644
--- a/flang/docs/Parsing.md
+++ b/flang/docs/Parsing.md
@@ -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

diff  --git a/flang/include/flang/Parser/message.h b/flang/include/flang/Parser/message.h
index 50ab3118543f5..432ee36862d4c 100644
--- a/flang/include/flang/Parser/message.h
+++ b/flang/include/flang/Parser/message.h
@@ -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
 
@@ -69,7 +80,7 @@ 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;
@@ -77,7 +88,8 @@ class MessageFormattedText {
   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:
@@ -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
 };
@@ -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;

diff  --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp
index fd4a52c895bf9..63515fd2e0fa5 100644
--- a/flang/lib/Parser/message.cpp
+++ b/flang/lib/Parser/message.cpp
@@ -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_);
 }
@@ -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()};

diff  --git a/flang/lib/Semantics/check-io.cpp b/flang/lib/Semantics/check-io.cpp
index 15e8b79052242..da266c15f8e4c 100644
--- a/flang/lib/Semantics/check-io.cpp
+++ b/flang/lib/Semantics/check-io.cpp
@@ -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

diff  --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 95118202e9fe3..ce1c37ef59a40 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -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;

diff  --git a/flang/lib/Semantics/resolve-names-utils.cpp b/flang/lib/Semantics/resolve-names-utils.cpp
index da33359e29614..4c3c32e1a0af6 100644
--- a/flang/lib/Semantics/resolve-names-utils.cpp
+++ b/flang/lib/Semantics/resolve-names-utils.cpp
@@ -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(
@@ -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'"

diff  --git a/flang/lib/Semantics/resolve-names-utils.h b/flang/lib/Semantics/resolve-names-utils.h
index 032aa1943cb61..d0986fdfc139e 100644
--- a/flang/lib/Semantics/resolve-names-utils.h
+++ b/flang/lib/Semantics/resolve-names-utils.h
@@ -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 &);

diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 4da150599c88a..07135b5796d46 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -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);


        


More information about the flang-commits mailing list