[flang-commits] [flang] [flang] Tag warnings with LanguageFeature or UsageWarning (PR #110304)

via flang-commits flang-commits at lists.llvm.org
Fri Sep 27 10:37:05 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-openmp

@llvm/pr-subscribers-flang-semantics

Author: Peter Klausler (klausler)

<details>
<summary>Changes</summary>

Allow a parser::Message for a warning to be marked with the common::LanguageFeature or common::UsageWarning that controls it.  This will allow a later patch to add hooks whereby a driver will be able to decorate warning messages with the names of its options that enable each particular warning, and to add hooks whereby a driver can map those enumerators by name to command-line options that enable/disable the language feature and enable/disable the messages.

Hooks for a driver to use to map the name of a feature or warning to its enumerator were also added.

To simplify the tagging of warnings with their corresponding language feature or usage warning, to ensure that they are properly controlled by ShouldWarn(), and to ensure that warnings never issue at code sites in module files, two new Warn() member function templates were added to SemanticsContext and other contextual frameworks. Warn() can't be used before source locations can be mapped to scopes, but the bulk of existing code blocks testing ShouldWarn() and FindModuleFile() before calling Say() were convertible into calls to Warn().  The ones that were not convertible were extended with explicit calls to Message::set_languageFeature() and set_usageWarning().

---

Patch is 206.89 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/110304.diff


44 Files Affected:

- (modified) flang/include/flang/Common/Fortran-features.h (+6-73) 
- (modified) flang/include/flang/Parser/message.h (+88-2) 
- (modified) flang/include/flang/Semantics/expression.h (+10) 
- (modified) flang/include/flang/Semantics/semantics.h (+19-1) 
- (modified) flang/lib/Common/Fortran-features.cpp (+94) 
- (modified) flang/lib/Evaluate/check-expression.cpp (+36-30) 
- (modified) flang/lib/Evaluate/common.cpp (+9-7) 
- (modified) flang/lib/Evaluate/fold-character.cpp (+2-2) 
- (modified) flang/lib/Evaluate/fold-complex.cpp (+1-1) 
- (modified) flang/lib/Evaluate/fold-implementation.h (+13-13) 
- (modified) flang/lib/Evaluate/fold-integer.cpp (+22-12) 
- (modified) flang/lib/Evaluate/fold-logical.cpp (+2-1) 
- (modified) flang/lib/Evaluate/fold-matmul.h (+1-1) 
- (modified) flang/lib/Evaluate/fold-real.cpp (+23-13) 
- (modified) flang/lib/Evaluate/fold-reduction.h (+3-3) 
- (modified) flang/lib/Evaluate/host.cpp (+1-1) 
- (modified) flang/lib/Evaluate/intrinsics.cpp (+9-6) 
- (modified) flang/lib/Evaluate/variable.cpp (+2-2) 
- (modified) flang/lib/Parser/message.cpp (+18) 
- (modified) flang/lib/Parser/preprocessor.cpp (+12-6) 
- (modified) flang/lib/Parser/prescan.cpp (+17-11) 
- (modified) flang/lib/Semantics/check-acc-structure.cpp (+10-18) 
- (modified) flang/lib/Semantics/check-allocate.cpp (+2-4) 
- (modified) flang/lib/Semantics/check-call.cpp (+107-92) 
- (modified) flang/lib/Semantics/check-case.cpp (+5-9) 
- (modified) flang/lib/Semantics/check-cuda.cpp (+2-4) 
- (modified) flang/lib/Semantics/check-data.cpp (+4-6) 
- (modified) flang/lib/Semantics/check-declarations.cpp (+155-204) 
- (modified) flang/lib/Semantics/check-directive-structure.h (+10-13) 
- (modified) flang/lib/Semantics/check-do-forall.cpp (+11-15) 
- (modified) flang/lib/Semantics/check-io.cpp (+7-12) 
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+25-34) 
- (modified) flang/lib/Semantics/check-return.cpp (+3-3) 
- (modified) flang/lib/Semantics/compute-offsets.cpp (+3-5) 
- (modified) flang/lib/Semantics/data-to-inits.cpp (+12-22) 
- (modified) flang/lib/Semantics/definable.cpp (+2-1) 
- (modified) flang/lib/Semantics/expression.cpp (+59-88) 
- (modified) flang/lib/Semantics/mod-file.cpp (+4-2) 
- (modified) flang/lib/Semantics/pointer-assignment.cpp (+40-23) 
- (modified) flang/lib/Semantics/resolve-directives.cpp (+2-3) 
- (modified) flang/lib/Semantics/resolve-labels.cpp (+19-9) 
- (modified) flang/lib/Semantics/resolve-names-utils.cpp (+13-15) 
- (modified) flang/lib/Semantics/resolve-names.cpp (+154-151) 
- (modified) flang/lib/Semantics/semantics.cpp (+22-19) 


``````````diff
diff --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h
index 86c6e02b0f2ffd..f813cbae40a57e 100644
--- a/flang/include/flang/Common/Fortran-features.h
+++ b/flang/include/flang/Common/Fortran-features.h
@@ -12,6 +12,7 @@
 #include "flang/Common/Fortran.h"
 #include "flang/Common/enum-set.h"
 #include "flang/Common/idioms.h"
+#include <optional>
 #include <vector>
 
 namespace Fortran::common {
@@ -48,7 +49,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
     ImpliedDoIndexScope, DistinctCommonSizes, OddIndexVariableRestrictions,
     IndistinguishableSpecifics, SubroutineAndFunctionSpecifics,
     EmptySequenceType, NonSequenceCrayPointee, BranchIntoConstruct,
-    BadBranchTarget, ConvertedArgument, HollerithPolymorphic, ListDirectedSize,
+    BadBranchTarget, HollerithPolymorphic, ListDirectedSize,
     NonBindCInteroperability, CudaManaged, CudaUnified,
     PolymorphicActualAllocatableOrPointerToMonomorphicDummy, RelaxedPureDummy,
     UndefinableAsynchronousOrVolatileActual, AutomaticInMainProgram, PrintCptr,
@@ -76,80 +77,12 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
 using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
 using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;
 
+std::optional<LanguageFeature> FindLanguageFeature(const char *);
+std::optional<UsageWarning> FindUsageWarning(const char *);
+
 class LanguageFeatureControl {
 public:
-  LanguageFeatureControl() {
-    // These features must be explicitly enabled by command line options.
-    disable_.set(LanguageFeature::OldDebugLines);
-    disable_.set(LanguageFeature::OpenACC);
-    disable_.set(LanguageFeature::OpenMP);
-    disable_.set(LanguageFeature::CUDA); // !@cuf
-    disable_.set(LanguageFeature::CudaManaged);
-    disable_.set(LanguageFeature::CudaUnified);
-    disable_.set(LanguageFeature::ImplicitNoneTypeNever);
-    disable_.set(LanguageFeature::ImplicitNoneTypeAlways);
-    disable_.set(LanguageFeature::DefaultSave);
-    disable_.set(LanguageFeature::SaveMainProgram);
-    // These features, if enabled, conflict with valid standard usage,
-    // so there are disabled here by default.
-    disable_.set(LanguageFeature::BackslashEscapes);
-    disable_.set(LanguageFeature::LogicalAbbreviations);
-    disable_.set(LanguageFeature::XOROperator);
-    disable_.set(LanguageFeature::OldStyleParameter);
-    // These warnings are enabled by default, but only because they used
-    // to be unconditional.  TODO: prune this list
-    warnLanguage_.set(LanguageFeature::ExponentMatchingKindParam);
-    warnLanguage_.set(LanguageFeature::RedundantAttribute);
-    warnLanguage_.set(LanguageFeature::SubroutineAndFunctionSpecifics);
-    warnLanguage_.set(LanguageFeature::EmptySequenceType);
-    warnLanguage_.set(LanguageFeature::NonSequenceCrayPointee);
-    warnLanguage_.set(LanguageFeature::BranchIntoConstruct);
-    warnLanguage_.set(LanguageFeature::BadBranchTarget);
-    warnLanguage_.set(LanguageFeature::ConvertedArgument);
-    warnLanguage_.set(LanguageFeature::HollerithPolymorphic);
-    warnLanguage_.set(LanguageFeature::ListDirectedSize);
-    warnUsage_.set(UsageWarning::ShortArrayActual);
-    warnUsage_.set(UsageWarning::FoldingException);
-    warnUsage_.set(UsageWarning::FoldingAvoidsRuntimeCrash);
-    warnUsage_.set(UsageWarning::FoldingValueChecks);
-    warnUsage_.set(UsageWarning::FoldingFailure);
-    warnUsage_.set(UsageWarning::FoldingLimit);
-    warnUsage_.set(UsageWarning::Interoperability);
-    warnUsage_.set(UsageWarning::Bounds);
-    warnUsage_.set(UsageWarning::Preprocessing);
-    warnUsage_.set(UsageWarning::Scanning);
-    warnUsage_.set(UsageWarning::OpenAccUsage);
-    warnUsage_.set(UsageWarning::ProcPointerCompatibility);
-    warnUsage_.set(UsageWarning::VoidMold);
-    warnUsage_.set(UsageWarning::KnownBadImplicitInterface);
-    warnUsage_.set(UsageWarning::EmptyCase);
-    warnUsage_.set(UsageWarning::CaseOverflow);
-    warnUsage_.set(UsageWarning::CUDAUsage);
-    warnUsage_.set(UsageWarning::IgnoreTKRUsage);
-    warnUsage_.set(UsageWarning::ExternalInterfaceMismatch);
-    warnUsage_.set(UsageWarning::DefinedOperatorArgs);
-    warnUsage_.set(UsageWarning::Final);
-    warnUsage_.set(UsageWarning::ZeroDoStep);
-    warnUsage_.set(UsageWarning::UnusedForallIndex);
-    warnUsage_.set(UsageWarning::OpenMPUsage);
-    warnUsage_.set(UsageWarning::ModuleFile);
-    warnUsage_.set(UsageWarning::DataLength);
-    warnUsage_.set(UsageWarning::IgnoredDirective);
-    warnUsage_.set(UsageWarning::HomonymousSpecific);
-    warnUsage_.set(UsageWarning::HomonymousResult);
-    warnUsage_.set(UsageWarning::IgnoredIntrinsicFunctionType);
-    warnUsage_.set(UsageWarning::PreviousScalarUse);
-    warnUsage_.set(UsageWarning::RedeclaredInaccessibleComponent);
-    warnUsage_.set(UsageWarning::ImplicitShared);
-    warnUsage_.set(UsageWarning::IndexVarRedefinition);
-    warnUsage_.set(UsageWarning::IncompatibleImplicitInterfaces);
-    warnUsage_.set(UsageWarning::BadTypeForTarget);
-    warnUsage_.set(UsageWarning::VectorSubscriptFinalization);
-    warnUsage_.set(UsageWarning::UndefinedFunctionResult);
-    warnUsage_.set(UsageWarning::UselessIomsg);
-    // New warnings, on by default
-    warnLanguage_.set(LanguageFeature::SavedLocalInSpecExpr);
-  }
+  LanguageFeatureControl();
   LanguageFeatureControl(const LanguageFeatureControl &) = default;
 
   void Enable(LanguageFeature f, bool yes = true) { disable_.set(f, !yes); }
diff --git a/flang/include/flang/Parser/message.h b/flang/include/flang/Parser/message.h
index 668559aeec9478..bc38f571ca3df4 100644
--- a/flang/include/flang/Parser/message.h
+++ b/flang/include/flang/Parser/message.h
@@ -15,6 +15,7 @@
 #include "char-block.h"
 #include "char-set.h"
 #include "provenance.h"
+#include "flang/Common/Fortran-features.h"
 #include "flang/Common/idioms.h"
 #include "flang/Common/reference-counted.h"
 #include "flang/Common/restorer.h"
@@ -202,6 +203,26 @@ class Message : public common::ReferenceCounted<Message> {
   Message(ProvenanceRange pr, const MessageExpectedText &t)
       : location_{pr}, text_{t} {}
 
+  Message(common::LanguageFeature feature, ProvenanceRange pr,
+      const MessageFixedText &t)
+      : location_{pr}, text_{t}, languageFeature_{feature} {}
+  Message(common::LanguageFeature feature, ProvenanceRange pr,
+      const MessageFormattedText &s)
+      : location_{pr}, text_{s}, languageFeature_{feature} {}
+  Message(common::LanguageFeature feature, ProvenanceRange pr,
+      MessageFormattedText &&s)
+      : location_{pr}, text_{std::move(s)}, languageFeature_{feature} {}
+
+  Message(common::UsageWarning warning, ProvenanceRange pr,
+      const MessageFixedText &t)
+      : location_{pr}, text_{t}, usageWarning_{warning} {}
+  Message(common::UsageWarning warning, ProvenanceRange pr,
+      const MessageFormattedText &s)
+      : location_{pr}, text_{s}, usageWarning_{warning} {}
+  Message(common::UsageWarning warning, ProvenanceRange pr,
+      MessageFormattedText &&s)
+      : location_{pr}, text_{std::move(s)}, usageWarning_{warning} {}
+
   Message(CharBlock csr, const MessageFixedText &t)
       : location_{csr}, text_{t} {}
   Message(CharBlock csr, const MessageFormattedText &s)
@@ -211,10 +232,41 @@ class Message : public common::ReferenceCounted<Message> {
   Message(CharBlock csr, const MessageExpectedText &t)
       : location_{csr}, text_{t} {}
 
+  Message(
+      common::LanguageFeature feature, CharBlock csr, const MessageFixedText &t)
+      : location_{csr}, text_{t}, languageFeature_{feature} {}
+  Message(common::LanguageFeature feature, CharBlock csr,
+      const MessageFormattedText &s)
+      : location_{csr}, text_{s}, languageFeature_{feature} {}
+  Message(
+      common::LanguageFeature feature, CharBlock csr, MessageFormattedText &&s)
+      : location_{csr}, text_{std::move(s)}, languageFeature_{feature} {}
+
+  Message(
+      common::UsageWarning warning, CharBlock csr, const MessageFixedText &t)
+      : location_{csr}, text_{t}, usageWarning_{warning} {}
+  Message(common::UsageWarning warning, CharBlock csr,
+      const MessageFormattedText &s)
+      : location_{csr}, text_{s}, usageWarning_{warning} {}
+  Message(common::UsageWarning warning, CharBlock csr, MessageFormattedText &&s)
+      : location_{csr}, text_{std::move(s)}, usageWarning_{warning} {}
+
   template <typename RANGE, typename A, typename... As>
   Message(RANGE r, const MessageFixedText &t, A &&x, As &&...xs)
       : location_{r}, text_{MessageFormattedText{
                           t, std::forward<A>(x), std::forward<As>(xs)...}} {}
+  template <typename RANGE, typename A, typename... As>
+  Message(common::LanguageFeature feature, RANGE r, const MessageFixedText &t,
+      A &&x, As &&...xs)
+      : location_{r}, text_{MessageFormattedText{
+                          t, std::forward<A>(x), std::forward<As>(xs)...}},
+        languageFeature_{feature} {}
+  template <typename RANGE, typename A, typename... As>
+  Message(common::UsageWarning warning, RANGE r, const MessageFixedText &t,
+      A &&x, As &&...xs)
+      : location_{r}, text_{MessageFormattedText{
+                          t, std::forward<A>(x), std::forward<As>(xs)...}},
+        usageWarning_{warning} {}
 
   Reference attachment() const { return attachment_; }
 
@@ -232,6 +284,10 @@ class Message : public common::ReferenceCounted<Message> {
   bool IsFatal() const;
   Severity severity() const;
   Message &set_severity(Severity);
+  std::optional<common::LanguageFeature> languageFeature() const;
+  Message &set_languageFeature(common::LanguageFeature);
+  std::optional<common::UsageWarning> usageWarning() const;
+  Message &set_usageWarning(common::UsageWarning);
   std::string ToString() const;
   std::optional<ProvenanceRange> GetProvenanceRange(
       const AllCookedSources &) const;
@@ -256,6 +312,8 @@ class Message : public common::ReferenceCounted<Message> {
       text_;
   bool attachmentIsContext_{false};
   Reference attachment_;
+  std::optional<common::LanguageFeature> languageFeature_;
+  std::optional<common::UsageWarning> usageWarning_;
 };
 
 class Messages {
@@ -275,6 +333,16 @@ class Messages {
     return messages_.emplace_back(std::forward<A>(args)...);
   }
 
+  template <typename... A>
+  Message &Say(common::LanguageFeature feature, A &&...args) {
+    return Say(std::forward<A>(args)...).set_languageFeature(feature);
+  }
+
+  template <typename... A>
+  Message &Say(common::UsageWarning warning, A &&...args) {
+    return Say(std::forward<A>(args)...).set_usageWarning(warning);
+  }
+
   void Annex(Messages &&that) {
     messages_.splice(messages_.end(), that.messages_);
   }
@@ -330,6 +398,10 @@ class ContextualMessages {
     return common::ScopedSet(messages_, nullptr);
   }
 
+  template <typename... A> Message *Say(A &&...args) {
+    return Say(at_, std::forward<A>(args)...);
+  }
+
   template <typename... A> Message *Say(CharBlock at, A &&...args) {
     if (messages_ != nullptr) {
       auto &msg{messages_->Say(at, std::forward<A>(args)...)};
@@ -347,8 +419,22 @@ class ContextualMessages {
     return Say(at.value_or(at_), std::forward<A>(args)...);
   }
 
-  template <typename... A> Message *Say(A &&...args) {
-    return Say(at_, std::forward<A>(args)...);
+  template <typename... A>
+  Message *Say(common::LanguageFeature feature, A &&...args) {
+    Message *msg{Say(std::forward<A>(args)...)};
+    if (msg) {
+      msg->set_languageFeature(feature);
+    }
+    return msg;
+  }
+
+  template <typename... A>
+  Message *Say(common::UsageWarning warning, A &&...args) {
+    Message *msg{Say(std::forward<A>(args)...)};
+    if (msg) {
+      msg->set_usageWarning(warning);
+    }
+    return msg;
   }
 
   Message *Say(Message &&msg) {
diff --git a/flang/include/flang/Semantics/expression.h b/flang/include/flang/Semantics/expression.h
index c90c8c4b3cc70f..a90801db7338cc 100644
--- a/flang/include/flang/Semantics/expression.h
+++ b/flang/include/flang/Semantics/expression.h
@@ -123,6 +123,16 @@ class ExpressionAnalyzer {
   template <typename... A> parser::Message *Say(A &&...args) {
     return GetContextualMessages().Say(std::forward<A>(args)...);
   }
+  template <typename FeatureOrUsageWarning, typename... A>
+  parser::Message *Warn(
+      FeatureOrUsageWarning warning, parser::CharBlock at, A &&...args) {
+    return context_.Warn(warning, at, std::forward<A>(args)...);
+  }
+  template <typename FeatureOrUsageWarning, typename... A>
+  parser::Message *Warn(FeatureOrUsageWarning warning, A &&...args) {
+    return Warn(
+        warning, GetContextualMessages().at(), std::forward<A>(args)...);
+  }
 
   template <typename T, typename... A>
   parser::Message *SayAt(const T &parsed, A &&...args) {
diff --git a/flang/include/flang/Semantics/semantics.h b/flang/include/flang/Semantics/semantics.h
index e73f9d2e85d589..a9b9e9f3031b57 100644
--- a/flang/include/flang/Semantics/semantics.h
+++ b/flang/include/flang/Semantics/semantics.h
@@ -185,6 +185,24 @@ class SemanticsContext {
     return message;
   }
 
+  template <typename FeatureOrUsageWarning, typename... A>
+  parser::Message *Warn(
+      FeatureOrUsageWarning warning, parser::CharBlock at, A &&...args) {
+    if (languageFeatures_.ShouldWarn(warning) && !IsInModuleFile(at)) {
+      parser::Message &msg{
+          messages_.Say(warning, at, std::forward<A>(args)...)};
+      return &msg;
+    } else {
+      return nullptr;
+    }
+  }
+
+  template <typename FeatureOrUsageWarning, typename... A>
+  parser::Message *Warn(FeatureOrUsageWarning warning, A &&...args) {
+    CHECK(location_);
+    return Warn(warning, *location_, std::forward<A>(args)...);
+  }
+
   const Scope &FindScope(parser::CharBlock) const;
   Scope &FindScope(parser::CharBlock);
   void UpdateScopeIndex(Scope &, parser::CharBlock);
@@ -267,7 +285,7 @@ class SemanticsContext {
       std::multimap<parser::CharBlock, Scope &, ScopeIndexComparator>;
   ScopeIndex::iterator SearchScopeIndex(parser::CharBlock);
 
-  void CheckIndexVarRedefine(
+  parser::Message *CheckIndexVarRedefine(
       const parser::CharBlock &, const Symbol &, parser::MessageFixedText &&);
   void CheckError(const Symbol &);
 
diff --git a/flang/lib/Common/Fortran-features.cpp b/flang/lib/Common/Fortran-features.cpp
index 25a948818e6560..8f2a96095ab853 100644
--- a/flang/lib/Common/Fortran-features.cpp
+++ b/flang/lib/Common/Fortran-features.cpp
@@ -9,9 +9,103 @@
 #include "flang/Common/Fortran-features.h"
 #include "flang/Common/Fortran.h"
 #include "flang/Common/idioms.h"
+#include <strings.h>
 
 namespace Fortran::common {
 
+LanguageFeatureControl::LanguageFeatureControl() {
+  // These features must be explicitly enabled by command line options.
+  disable_.set(LanguageFeature::OldDebugLines);
+  disable_.set(LanguageFeature::OpenACC);
+  disable_.set(LanguageFeature::OpenMP);
+  disable_.set(LanguageFeature::CUDA); // !@cuf
+  disable_.set(LanguageFeature::CudaManaged);
+  disable_.set(LanguageFeature::CudaUnified);
+  disable_.set(LanguageFeature::ImplicitNoneTypeNever);
+  disable_.set(LanguageFeature::ImplicitNoneTypeAlways);
+  disable_.set(LanguageFeature::DefaultSave);
+  disable_.set(LanguageFeature::SaveMainProgram);
+  // These features, if enabled, conflict with valid standard usage,
+  // so there are disabled here by default.
+  disable_.set(LanguageFeature::BackslashEscapes);
+  disable_.set(LanguageFeature::LogicalAbbreviations);
+  disable_.set(LanguageFeature::XOROperator);
+  disable_.set(LanguageFeature::OldStyleParameter);
+  // These warnings are enabled by default, but only because they used
+  // to be unconditional.  TODO: prune this list
+  warnLanguage_.set(LanguageFeature::ExponentMatchingKindParam);
+  warnLanguage_.set(LanguageFeature::RedundantAttribute);
+  warnLanguage_.set(LanguageFeature::SubroutineAndFunctionSpecifics);
+  warnLanguage_.set(LanguageFeature::EmptySequenceType);
+  warnLanguage_.set(LanguageFeature::NonSequenceCrayPointee);
+  warnLanguage_.set(LanguageFeature::BranchIntoConstruct);
+  warnLanguage_.set(LanguageFeature::BadBranchTarget);
+  warnLanguage_.set(LanguageFeature::HollerithPolymorphic);
+  warnLanguage_.set(LanguageFeature::ListDirectedSize);
+  warnUsage_.set(UsageWarning::ShortArrayActual);
+  warnUsage_.set(UsageWarning::FoldingException);
+  warnUsage_.set(UsageWarning::FoldingAvoidsRuntimeCrash);
+  warnUsage_.set(UsageWarning::FoldingValueChecks);
+  warnUsage_.set(UsageWarning::FoldingFailure);
+  warnUsage_.set(UsageWarning::FoldingLimit);
+  warnUsage_.set(UsageWarning::Interoperability);
+  warnUsage_.set(UsageWarning::Bounds);
+  warnUsage_.set(UsageWarning::Preprocessing);
+  warnUsage_.set(UsageWarning::Scanning);
+  warnUsage_.set(UsageWarning::OpenAccUsage);
+  warnUsage_.set(UsageWarning::ProcPointerCompatibility);
+  warnUsage_.set(UsageWarning::VoidMold);
+  warnUsage_.set(UsageWarning::KnownBadImplicitInterface);
+  warnUsage_.set(UsageWarning::EmptyCase);
+  warnUsage_.set(UsageWarning::CaseOverflow);
+  warnUsage_.set(UsageWarning::CUDAUsage);
+  warnUsage_.set(UsageWarning::IgnoreTKRUsage);
+  warnUsage_.set(UsageWarning::ExternalInterfaceMismatch);
+  warnUsage_.set(UsageWarning::DefinedOperatorArgs);
+  warnUsage_.set(UsageWarning::Final);
+  warnUsage_.set(UsageWarning::ZeroDoStep);
+  warnUsage_.set(UsageWarning::UnusedForallIndex);
+  warnUsage_.set(UsageWarning::OpenMPUsage);
+  warnUsage_.set(UsageWarning::ModuleFile);
+  warnUsage_.set(UsageWarning::DataLength);
+  warnUsage_.set(UsageWarning::IgnoredDirective);
+  warnUsage_.set(UsageWarning::HomonymousSpecific);
+  warnUsage_.set(UsageWarning::HomonymousResult);
+  warnUsage_.set(UsageWarning::IgnoredIntrinsicFunctionType);
+  warnUsage_.set(UsageWarning::PreviousScalarUse);
+  warnUsage_.set(UsageWarning::RedeclaredInaccessibleComponent);
+  warnUsage_.set(UsageWarning::ImplicitShared);
+  warnUsage_.set(UsageWarning::IndexVarRedefinition);
+  warnUsage_.set(UsageWarning::IncompatibleImplicitInterfaces);
+  warnUsage_.set(UsageWarning::BadTypeForTarget);
+  warnUsage_.set(UsageWarning::VectorSubscriptFinalization);
+  warnUsage_.set(UsageWarning::UndefinedFunctionResult);
+  warnUsage_.set(UsageWarning::UselessIomsg);
+  // New warnings, on by default
+  warnLanguage_.set(LanguageFeature::SavedLocalInSpecExpr);
+}
+
+template <typename ENUM, std::size_t N>
+std::optional<ENUM> ScanEnum(const char *name) {
+  if (name) {
+    for (std::size_t j{0}; j < N; ++j) {
+      auto feature{static_cast<ENUM>(j)};
+      if (::strcasecmp(name, EnumToString(feature).data()) == 0) {
+        return feature;
+      }
+    }
+  }
+  return std::nullopt;
+}
+
+std::optional<LanguageFeature> FindLanguageFeature(const char *name) {
+  return ScanEnum<LanguageFeature, LanguageFeature_enumSize>(name);
+}
+
+std::optional<UsageWarning> FindUsageWarning(const char *name) {
+  return ScanEnum<UsageWarning, UsageWarning_enumSize>(name);
+}
+
 std::vector<const char *> LanguageFeatureControl::GetNames(
     LogicalOperator opr) const {
   std::vector<const char *> result;
diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index a1ede7d7553bf6..38794a2d8aacc7 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -412,6 +412,7 @@ std::optional<Expr<SomeType>> NonPointerInitializationExpr(const Symbol &symbol,
           symbol.owner().context().ShouldWarn(
               common::LanguageFeature::LogicalIntegerAssignment)) {
         context.messages().Say(
+            common::LanguageFeature::LogicalIntegerAssignment,
             "nonstandard usage: initialization of %s with %s"_port_en_US,
             symTS->type().AsFortran(), x.GetType().value().AsFortran());
       }
@@ -565,7 +566,7 @@ class CheckSpecificationExprHelper
       if (!scope_.IsModuleFile() &&
           context_.languageFeatures().ShouldWarn(
               common::LanguageFeature::SavedLocalInSpecExpr)) {
-        context_.messages().Say(
+        context_.messages().Say(common::LanguageFeature::SavedLocalInSpecExpr,
             "specification expression refers to local object '%s' (initialized and saved)"_port_en_US,
             ultimate.name().ToString());
       }
@@ -1102,44 +1103,53 @@ class StmtFunctionChecker
 public:
   using Result = std::optional<parser::Me...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/110304


More information about the flang-commits mailing list