[flang-commits] [flang] [flang] Ensure all warning/portability messages are guarded by Should… (PR #90518)

via flang-commits flang-commits at lists.llvm.org
Mon Apr 29 13:04:12 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-openmp

Author: Peter Klausler (klausler)

<details>
<summary>Changes</summary>

…Warn()

Many warning messages were being emitted unconditionally.  Ensure that all warnings are conditional on a true result from a call to common::LanguageFeatureControl::ShouldWarn() so that it is easy for a driver to disable them all, or, in the future, to provide per-warning control over them.

---

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


111 Files Affected:

- (modified) flang/include/flang/Common/Fortran-features.h (+36-11) 
- (modified) flang/include/flang/Semantics/tools.h (+1-1) 
- (modified) flang/lib/Evaluate/common.cpp (+17-14) 
- (modified) flang/lib/Evaluate/fold-character.cpp (+13-7) 
- (modified) flang/lib/Evaluate/fold-complex.cpp (+2-1) 
- (modified) flang/lib/Evaluate/fold-implementation.h (+52-28) 
- (modified) flang/lib/Evaluate/fold-integer.cpp (+31-12) 
- (modified) flang/lib/Evaluate/fold-logical.cpp (+3-1) 
- (modified) flang/lib/Evaluate/fold-matmul.h (+3-1) 
- (modified) flang/lib/Evaluate/fold-real.cpp (+61-28) 
- (modified) flang/lib/Evaluate/fold-reduction.h (+9-3) 
- (modified) flang/lib/Evaluate/host.cpp (+7-3) 
- (modified) flang/lib/Evaluate/intrinsics.cpp (+17-10) 
- (modified) flang/lib/Evaluate/variable.cpp (+11-7) 
- (modified) flang/lib/Parser/preprocessor.cpp (+27-12) 
- (modified) flang/lib/Parser/prescan.cpp (+18-10) 
- (modified) flang/lib/Parser/prescan.h (+1) 
- (modified) flang/lib/Semantics/check-acc-structure.cpp (+14-7) 
- (modified) flang/lib/Semantics/check-call.cpp (+40-15) 
- (modified) flang/lib/Semantics/check-case.cpp (+9-5) 
- (modified) flang/lib/Semantics/check-cuda.cpp (+4-2) 
- (modified) flang/lib/Semantics/check-declarations.cpp (+70-38) 
- (modified) flang/lib/Semantics/check-do-forall.cpp (+4-2) 
- (modified) flang/lib/Semantics/check-io.cpp (+6-4) 
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+25-17) 
- (modified) flang/lib/Semantics/data-to-inits.cpp (+6-3) 
- (modified) flang/lib/Semantics/expression.cpp (+19-9) 
- (modified) flang/lib/Semantics/mod-file.cpp (+9-5) 
- (modified) flang/lib/Semantics/pointer-assignment.cpp (+5-2) 
- (modified) flang/lib/Semantics/program-tree.cpp (+3-1) 
- (modified) flang/lib/Semantics/resolve-labels.cpp (+25-16) 
- (modified) flang/lib/Semantics/resolve-names.cpp (+101-57) 
- (modified) flang/lib/Semantics/semantics.cpp (+4-2) 
- (modified) flang/lib/Semantics/tools.cpp (+12-12) 
- (modified) flang/test/Driver/color-diagnostics-scan.f (+4-4) 
- (modified) flang/test/Driver/fixed-free-flag.f90 (+2-2) 
- (modified) flang/test/Driver/prescanner-diag.f90 (+4-4) 
- (modified) flang/test/Driver/werror-all.f90 (+2-2) 
- (modified) flang/test/Driver/werror-scan.f (+8-8) 
- (modified) flang/test/Driver/werror-sema.f90 (+5-5) 
- (modified) flang/test/Evaluate/errors01.f90 (+1-1) 
- (modified) flang/test/Evaluate/fold-dim.f90 (+1-1) 
- (modified) flang/test/Evaluate/fold-nearest.f90 (+1-1) 
- (modified) flang/test/Evaluate/fold-out_of_range.f90 (+1-1) 
- (modified) flang/test/Evaluate/folding03.f90 (+1-1) 
- (modified) flang/test/Evaluate/folding05.f90 () 
- (modified) flang/test/Evaluate/folding14.f90 (+1-1) 
- (modified) flang/test/Evaluate/folding28.f90 (+1-1) 
- (modified) flang/test/Parser/at-process.f (+1-1) 
- (modified) flang/test/Parser/unrecognized-dir.f90 (+1-1) 
- (modified) flang/test/Preprocessing/include-comment.F90 (+1-1) 
- (modified) flang/test/Preprocessing/pp044.F (+1-1) 
- (modified) flang/test/Semantics/OpenACC/acc-declare-validity.f90 (+1-1) 
- (modified) flang/test/Semantics/OpenMP/declarative-directive.f90 (+1-1) 
- (modified) flang/test/Semantics/OpenMP/declare-target01.f90 (+1-1) 
- (modified) flang/test/Semantics/OpenMP/declare-target02.f90 (+1-1) 
- (modified) flang/test/Semantics/OpenMP/declare-target06.f90 (+1-1) 
- (modified) flang/test/Semantics/OpenMP/requires04.f90 (+1-1) 
- (modified) flang/test/Semantics/OpenMP/requires05.f90 (+1-1) 
- (modified) flang/test/Semantics/OpenMP/target01.f90 (+1-1) 
- (modified) flang/test/Semantics/OpenMP/use_device_ptr1.f90 (+1-1) 
- (modified) flang/test/Semantics/arg-convert.f90 (+1-1) 
- (modified) flang/test/Semantics/badly-typed-intrinsic.f90 (+1-2) 
- (modified) flang/test/Semantics/bind-c04.f90 (+1-1) 
- (modified) flang/test/Semantics/boz-literal-constants.f90 (+1-1) 
- (modified) flang/test/Semantics/call24.f90 (+1-1) 
- (modified) flang/test/Semantics/call35.f90 (+1-1) 
- (modified) flang/test/Semantics/call41.f90 (+6-2) 
- (modified) flang/test/Semantics/case01.f90 (+1-1) 
- (modified) flang/test/Semantics/cuf01.cuf (+1-1) 
- (modified) flang/test/Semantics/cuf03.cuf (+1-1) 
- (modified) flang/test/Semantics/cuf04.cuf (+1-1) 
- (modified) flang/test/Semantics/cuf09.cuf (+3-3) 
- (modified) flang/test/Semantics/data17.f90 (+1-1) 
- (modified) flang/test/Semantics/declarations05.f90 (+1-1) 
- (modified) flang/test/Semantics/declarations07.f90 (+1-1) 
- (modified) flang/test/Semantics/doconcurrent03.f90 (+1-1) 
- (modified) flang/test/Semantics/dosemantics02.f90 (+1-1) 
- (modified) flang/test/Semantics/final02.f90 (+1-1) 
- (modified) flang/test/Semantics/forall02.f90 (+1-1) 
- (modified) flang/test/Semantics/generic03.f90 (+1-1) 
- (modified) flang/test/Semantics/global01.f90 (+1-1) 
- (modified) flang/test/Semantics/intrinsics02.f90 (+1-1) 
- (modified) flang/test/Semantics/io03.f90 (+4-4) 
- (modified) flang/test/Semantics/kinds04_q10.f90 (+14-6) 
- (modified) flang/test/Semantics/label04.f90 (+1-2) 
- (modified) flang/test/Semantics/label05.f90 (+1-1) 
- (modified) flang/test/Semantics/label06.f90 (+1-1) 
- (modified) flang/test/Semantics/label07.f90 (+1-1) 
- (modified) flang/test/Semantics/label13.f90 (+1-1) 
- (modified) flang/test/Semantics/label18.f90 (+1-1) 
- (modified) flang/test/Semantics/null-init.f90 (+1-1) 
- (modified) flang/test/Semantics/numeric_storage_size.f90 (+4-4) 
- (modified) flang/test/Semantics/pdt02.f90 (+1-1) 
- (modified) flang/test/Semantics/reshape.f90 (+2-2) 
- (modified) flang/test/Semantics/resolve107.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve108.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve11.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve18.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve24.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve37.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve45.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve60.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve61.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve67.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve78.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve79.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve80.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve81.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve82.f90 (+1-1) 
- (modified) flang/test/Semantics/resolve83.f90 (+1-1) 


``````````diff
diff --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h
index 1e678c341d8132..0f0416d16e9ab5 100644
--- a/flang/include/flang/Common/Fortran-features.h
+++ b/flang/include/flang/Common/Fortran-features.h
@@ -41,20 +41,32 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
     ActualIntegerConvertedToSmallerKind, HollerithOrCharacterAsBOZ,
     BindingAsProcedure, StatementFunctionExtensions,
     UseGenericIntrinsicWhenSpecificDoesntMatch, DataStmtExtensions,
-    RedundantContiguous, InitBlankCommon, EmptyBindCDerivedType,
-    MiscSourceExtensions, AllocateToOtherLength, LongNames, IntrinsicAsSpecific,
-    BenignNameClash, BenignRedundancy, NullMoldAllocatableComponentValue,
-    NopassScalarBase, MiscUseExtensions, ImpliedDoIndexScope,
-    DistinctCommonSizes, OddIndexVariableRestrictions,
-    IndistinguishableSpecifics)
+    RedundantContiguous, RedundantAttribute, InitBlankCommon,
+    EmptyBindCDerivedType, MiscSourceExtensions, AllocateToOtherLength,
+    LongNames, IntrinsicAsSpecific, BenignNameClash, BenignRedundancy,
+    NullMoldAllocatableComponentValue, NopassScalarBase, MiscUseExtensions,
+    ImpliedDoIndexScope, DistinctCommonSizes, OddIndexVariableRestrictions,
+    IndistinguishableSpecifics, SubroutineAndFunctionSpecifics,
+    EmptySequenceType, NonSequenceCrayPointee, BranchIntoConstruct,
+    BadBranchTarget, ConvertedArgument, HollerithPolymorphic, ListDirectedSize)
 
-// Portability and suspicious usage warnings for conforming code
+// Portability and suspicious usage warnings
 ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
     NonTargetPassedToTarget, PointerToPossibleNoncontiguous,
-    ShortCharacterActual, ExprPassedToVolatile, ImplicitInterfaceActual,
-    PolymorphicTransferArg, PointerComponentTransferArg, TransferSizePresence,
-    F202XAllocatableBreakingChange, DimMustBePresent, CommonBlockPadding,
-    LogicalVsCBool, BindCCharLength, ProcDummyArgShapes, ExternalNameConflict)
+    ShortCharacterActual, ShortArrayActual, ExprPassedToVolatile,
+    ImplicitInterfaceActual, PolymorphicTransferArg,
+    PointerComponentTransferArg, TransferSizePresence,
+    F202XAllocatableBreakingChange, OptionalMustBePresent, CommonBlockPadding,
+    LogicalVsCBool, BindCCharLength, ProcDummyArgShapes, ExternalNameConflict,
+    FoldingException, FoldingValueChecks, FoldingFailure, Interoperability,
+    Bounds, Preprocessing, Scanning, OpenAccUsage, ProcPointerCompatibility,
+    VoidMold, KnownBadImplicitInterface, EmptyCase, CaseOverflow, CUDAUsage,
+    IgnoreTKRUsage, ExternalInterfaceMismatch, DefinedOperatorArgs, Final,
+    ZeroDoStep, UnusedForallIndex, OpenMPUsage, ModuleFile, DataLength,
+    IgnoredDirective, HomonymousSpecific, HomonymousResult,
+    IgnoredIntrinsicFunctionType, PreviousScalarUse,
+    RedeclaredInaccessibleComponent, ImplicitShared, IndexVarRedefinition,
+    IncompatibleImplicitInterfaces, BadTypeForTarget, FoldingLimit)
 
 using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
 using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;
@@ -77,8 +89,12 @@ class LanguageFeatureControl {
     disable_.set(LanguageFeature::LogicalAbbreviations);
     disable_.set(LanguageFeature::XOROperator);
     disable_.set(LanguageFeature::OldStyleParameter);
+    // These warnings are serious enough to be enabled by default.
+    warnUsage_.set(UsageWarning::ModuleFile);
+    warnUsage_.set(UsageWarning::BadTypeForTarget);
   }
   LanguageFeatureControl(const LanguageFeatureControl &) = default;
+
   void Enable(LanguageFeature f, bool yes = true) { disable_.set(f, !yes); }
   void EnableWarning(LanguageFeature f, bool yes = true) {
     warnLanguage_.set(f, yes);
@@ -88,6 +104,15 @@ class LanguageFeatureControl {
   }
   void WarnOnAllNonstandard(bool yes = true) { warnAllLanguage_ = yes; }
   void WarnOnAllUsage(bool yes = true) { warnAllUsage_ = yes; }
+  void DisableAllNonstandardWarnings() {
+    warnAllLanguage_ = false;
+    warnLanguage_.clear();
+  }
+  void DisableAllUsageWarnings() {
+    warnAllUsage_ = false;
+    warnUsage_.clear();
+  }
+
   bool IsEnabled(LanguageFeature f) const { return !disable_.test(f); }
   bool ShouldWarn(LanguageFeature f) const {
     return (warnAllLanguage_ && f != LanguageFeature::OpenMP &&
diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h
index da10969ebc7021..efb5c9ba1077d4 100644
--- a/flang/include/flang/Semantics/tools.h
+++ b/flang/include/flang/Semantics/tools.h
@@ -634,7 +634,7 @@ class LabelEnforce {
   void Post(const parser::ErrLabel &errLabel);
   void Post(const parser::EndLabel &endLabel);
   void Post(const parser::EorLabel &eorLabel);
-  void checkLabelUse(const parser::Label &labelUsed);
+  void CheckLabelUse(const parser::Label &labelUsed);
 
 private:
   SemanticsContext &context_;
diff --git a/flang/lib/Evaluate/common.cpp b/flang/lib/Evaluate/common.cpp
index c659a5002ba0fc..c633bff57b1ecd 100644
--- a/flang/lib/Evaluate/common.cpp
+++ b/flang/lib/Evaluate/common.cpp
@@ -15,21 +15,24 @@ namespace Fortran::evaluate {
 
 void RealFlagWarnings(
     FoldingContext &context, const RealFlags &flags, const char *operation) {
-  if (flags.test(RealFlag::Overflow)) {
-    context.messages().Say("overflow on %s"_warn_en_US, operation);
-  }
-  if (flags.test(RealFlag::DivideByZero)) {
-    if (std::strcmp(operation, "division") == 0) {
-      context.messages().Say("division by zero"_warn_en_US);
-    } else {
-      context.messages().Say("division by zero on %s"_warn_en_US, operation);
+  if (context.languageFeatures().ShouldWarn(
+          common::UsageWarning::FoldingException)) {
+    if (flags.test(RealFlag::Overflow)) {
+      context.messages().Say("overflow on %s"_warn_en_US, operation);
+    }
+    if (flags.test(RealFlag::DivideByZero)) {
+      if (std::strcmp(operation, "division") == 0) {
+        context.messages().Say("division by zero"_warn_en_US);
+      } else {
+        context.messages().Say("division by zero on %s"_warn_en_US, operation);
+      }
+    }
+    if (flags.test(RealFlag::InvalidArgument)) {
+      context.messages().Say("invalid argument on %s"_warn_en_US, operation);
+    }
+    if (flags.test(RealFlag::Underflow)) {
+      context.messages().Say("underflow on %s"_warn_en_US, operation);
     }
-  }
-  if (flags.test(RealFlag::InvalidArgument)) {
-    context.messages().Say("invalid argument on %s"_warn_en_US, operation);
-  }
-  if (flags.test(RealFlag::Underflow)) {
-    context.messages().Say("underflow on %s"_warn_en_US, operation);
   }
 }
 
diff --git a/flang/lib/Evaluate/fold-character.cpp b/flang/lib/Evaluate/fold-character.cpp
index 5d9cc11754a7dd..877bc2eac1fc27 100644
--- a/flang/lib/Evaluate/fold-character.cpp
+++ b/flang/lib/Evaluate/fold-character.cpp
@@ -58,10 +58,13 @@ Expr<Type<TypeCategory::Character, KIND>> FoldIntrinsicFunction(
     return FoldElementalIntrinsic<T, IntT>(context, std::move(funcRef),
         ScalarFunc<T, IntT>([&](const Scalar<IntT> &i) {
           if (i.IsNegative() || i.BGE(Scalar<IntT>{0}.IBSET(8 * KIND))) {
-            context.messages().Say(
-                "%s(I=%jd) is out of range for CHARACTER(KIND=%d)"_warn_en_US,
-                parser::ToUpperCaseLetters(name),
-                static_cast<std::intmax_t>(i.ToInt64()), KIND);
+            if (context.languageFeatures().ShouldWarn(
+                    common::UsageWarning::FoldingValueChecks)) {
+              context.messages().Say(
+                  "%s(I=%jd) is out of range for CHARACTER(KIND=%d)"_warn_en_US,
+                  parser::ToUpperCaseLetters(name),
+                  static_cast<std::intmax_t>(i.ToInt64()), KIND);
+            }
           }
           return CharacterUtils<KIND>::CHAR(i.ToUInt64());
         }));
@@ -103,9 +106,12 @@ Expr<Type<TypeCategory::Character, KIND>> FoldIntrinsicFunction(
             static_cast<std::intmax_t>(n));
       } else if (static_cast<double>(n) * str.size() >
           (1 << 20)) { // sanity limit of 1MiB
-        context.messages().Say(
-            "Result of REPEAT() is too large to compute at compilation time (%g characters)"_port_en_US,
-            static_cast<double>(n) * str.size());
+        if (context.languageFeatures().ShouldWarn(
+                common::UsageWarning::FoldingLimit)) {
+          context.messages().Say(
+              "Result of REPEAT() is too large to compute at compilation time (%g characters)"_port_en_US,
+              static_cast<double>(n) * str.size());
+        }
       } else {
         return Expr<T>{Constant<T>{CharacterUtils<KIND>::REPEAT(str, n)}};
       }
diff --git a/flang/lib/Evaluate/fold-complex.cpp b/flang/lib/Evaluate/fold-complex.cpp
index 3260f82ffe8d73..d44cc9c69dd68d 100644
--- a/flang/lib/Evaluate/fold-complex.cpp
+++ b/flang/lib/Evaluate/fold-complex.cpp
@@ -29,7 +29,8 @@ Expr<Type<TypeCategory::Complex, KIND>> FoldIntrinsicFunction(
     if (auto callable{GetHostRuntimeWrapper<T, T>(name)}) {
       return FoldElementalIntrinsic<T, T>(
           context, std::move(funcRef), *callable);
-    } else {
+    } else if (context.languageFeatures().ShouldWarn(
+                   common::UsageWarning::FoldingFailure)) {
       context.messages().Say(
           "%s(complex(kind=%d)) cannot be folded on host"_warn_en_US, name,
           KIND);
diff --git a/flang/lib/Evaluate/fold-implementation.h b/flang/lib/Evaluate/fold-implementation.h
index 093f26bea1a44f..b62b5965c877ed 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -1680,7 +1680,7 @@ Expr<TO> FoldOperation(
     Convert<TO, FROMCAT> &convert;
   } msvcWorkaround{context, convert};
   return common::visit(
-      [&msvcWorkaround](auto &kindExpr) -> Expr<TO> {
+      [&msvcWorkaround, &context](auto &kindExpr) -> Expr<TO> {
         using Operand = ResultType<decltype(kindExpr)>;
         // This variable is a workaround for msvc which emits an error when
         // using the FROMCAT template parameter below.
@@ -1692,7 +1692,9 @@ Expr<TO> FoldOperation(
           if constexpr (TO::category == TypeCategory::Integer) {
             if constexpr (FromCat == TypeCategory::Integer) {
               auto converted{Scalar<TO>::ConvertSigned(*value)};
-              if (converted.overflow) {
+              if (converted.overflow &&
+                  context.languageFeatures().ShouldWarn(
+                      common::UsageWarning::FoldingException)) {
                 ctx.messages().Say(
                     "INTEGER(%d) to INTEGER(%d) conversion overflowed"_warn_en_US,
                     Operand::kind, TO::kind);
@@ -1700,14 +1702,17 @@ Expr<TO> FoldOperation(
               return ScalarConstantToExpr(std::move(converted.value));
             } else if constexpr (FromCat == TypeCategory::Real) {
               auto converted{value->template ToInteger<Scalar<TO>>()};
-              if (converted.flags.test(RealFlag::InvalidArgument)) {
-                ctx.messages().Say(
-                    "REAL(%d) to INTEGER(%d) conversion: invalid argument"_warn_en_US,
-                    Operand::kind, TO::kind);
-              } else if (converted.flags.test(RealFlag::Overflow)) {
-                ctx.messages().Say(
-                    "REAL(%d) to INTEGER(%d) conversion overflowed"_warn_en_US,
-                    Operand::kind, TO::kind);
+              if (context.languageFeatures().ShouldWarn(
+                      common::UsageWarning::FoldingException)) {
+                if (converted.flags.test(RealFlag::InvalidArgument)) {
+                  ctx.messages().Say(
+                      "REAL(%d) to INTEGER(%d) conversion: invalid argument"_warn_en_US,
+                      Operand::kind, TO::kind);
+                } else if (converted.flags.test(RealFlag::Overflow)) {
+                  ctx.messages().Say(
+                      "REAL(%d) to INTEGER(%d) conversion overflowed"_warn_en_US,
+                      Operand::kind, TO::kind);
+                }
               }
               return ScalarConstantToExpr(std::move(converted.value));
             }
@@ -1816,7 +1821,9 @@ Expr<T> FoldOperation(FoldingContext &context, Negate<T> &&x) {
   } else if (auto value{GetScalarConstantValue<T>(operand)}) {
     if constexpr (T::category == TypeCategory::Integer) {
       auto negated{value->Negate()};
-      if (negated.overflow) {
+      if (negated.overflow &&
+          context.languageFeatures().ShouldWarn(
+              common::UsageWarning::FoldingException)) {
         context.messages().Say(
             "INTEGER(%d) negation overflowed"_warn_en_US, T::kind);
       }
@@ -1856,7 +1863,9 @@ Expr<T> FoldOperation(FoldingContext &context, Add<T> &&x) {
   if (auto folded{OperandsAreConstants(x)}) {
     if constexpr (T::category == TypeCategory::Integer) {
       auto sum{folded->first.AddSigned(folded->second)};
-      if (sum.overflow) {
+      if (sum.overflow &&
+          context.languageFeatures().ShouldWarn(
+              common::UsageWarning::FoldingException)) {
         context.messages().Say(
             "INTEGER(%d) addition overflowed"_warn_en_US, T::kind);
       }
@@ -1882,7 +1891,9 @@ Expr<T> FoldOperation(FoldingContext &context, Subtract<T> &&x) {
   if (auto folded{OperandsAreConstants(x)}) {
     if constexpr (T::category == TypeCategory::Integer) {
       auto difference{folded->first.SubtractSigned(folded->second)};
-      if (difference.overflow) {
+      if (difference.overflow &&
+          context.languageFeatures().ShouldWarn(
+              common::UsageWarning::FoldingException)) {
         context.messages().Say(
             "INTEGER(%d) subtraction overflowed"_warn_en_US, T::kind);
       }
@@ -1908,7 +1919,9 @@ Expr<T> FoldOperation(FoldingContext &context, Multiply<T> &&x) {
   if (auto folded{OperandsAreConstants(x)}) {
     if constexpr (T::category == TypeCategory::Integer) {
       auto product{folded->first.MultiplySigned(folded->second)};
-      if (product.SignedMultiplicationOverflowed()) {
+      if (product.SignedMultiplicationOverflowed() &&
+          context.languageFeatures().ShouldWarn(
+              common::UsageWarning::FoldingException)) {
         context.messages().Say(
             "INTEGER(%d) multiplication overflowed"_warn_en_US, T::kind);
       }
@@ -1953,11 +1966,16 @@ Expr<T> FoldOperation(FoldingContext &context, Divide<T> &&x) {
     if constexpr (T::category == TypeCategory::Integer) {
       auto quotAndRem{folded->first.DivideSigned(folded->second)};
       if (quotAndRem.divisionByZero) {
-        context.messages().Say(
-            "INTEGER(%d) division by zero"_warn_en_US, T::kind);
+        if (context.languageFeatures().ShouldWarn(
+                common::UsageWarning::FoldingException)) {
+          context.messages().Say(
+              "INTEGER(%d) division by zero"_warn_en_US, T::kind);
+        }
         return Expr<T>{std::move(x)};
       }
-      if (quotAndRem.overflow) {
+      if (quotAndRem.overflow &&
+          context.languageFeatures().ShouldWarn(
+              common::UsageWarning::FoldingException)) {
         context.messages().Say(
             "INTEGER(%d) division overflowed"_warn_en_US, T::kind);
       }
@@ -1998,22 +2016,26 @@ Expr<T> FoldOperation(FoldingContext &context, Power<T> &&x) {
   if (auto folded{OperandsAreConstants(x)}) {
     if constexpr (T::category == TypeCategory::Integer) {
       auto power{folded->first.Power(folded->second)};
-      if (power.divisionByZero) {
-        context.messages().Say(
-            "INTEGER(%d) zero to negative power"_warn_en_US, T::kind);
-      } else if (power.overflow) {
-        context.messages().Say(
-            "INTEGER(%d) power overflowed"_warn_en_US, T::kind);
-      } else if (power.zeroToZero) {
-        context.messages().Say(
-            "INTEGER(%d) 0**0 is not defined"_warn_en_US, T::kind);
+      if (context.languageFeatures().ShouldWarn(
+              common::UsageWarning::FoldingException)) {
+        if (power.divisionByZero) {
+          context.messages().Say(
+              "INTEGER(%d) zero to negative power"_warn_en_US, T::kind);
+        } else if (power.overflow) {
+          context.messages().Say(
+              "INTEGER(%d) power overflowed"_warn_en_US, T::kind);
+        } else if (power.zeroToZero) {
+          context.messages().Say(
+              "INTEGER(%d) 0**0 is not defined"_warn_en_US, T::kind);
+        }
       }
       return Expr<T>{Constant<T>{power.power}};
     } else {
       if (auto callable{GetHostRuntimeWrapper<T, T, T>("pow")}) {
         return Expr<T>{
             Constant<T>{(*callable)(context, folded->first, folded->second)}};
-      } else {
+      } else if (context.languageFeatures().ShouldWarn(
+                     common::UsageWarning::FoldingFailure)) {
         context.messages().Say(
             "Power for %s cannot be folded on host"_warn_en_US,
             T{}.AsFortran());
@@ -2097,7 +2119,9 @@ Expr<Type<TypeCategory::Real, KIND>> ToReal(
           CHECK(constant);
           Scalar<Result> real{constant->GetScalarValue().value()};
           From converted{From::ConvertUnsigned(real.RawBits()).value};
-          if (original != converted) { // C1601
+          if (original != converted &&
+              context.languageFeatures().ShouldWarn(
+                  common::UsageWarning::FoldingValueChecks)) { // C1601
             context.messages().Say(
                 "Nonzero bits truncated from BOZ literal constant in REAL intrinsic"_warn_en_US);
           }
diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp
index 0a6ff12049f301..81a00c5dcde5f9 100644
--- a/flang/lib/Evaluate/fold-integer.cpp
+++ b/flang/lib/Evaluate/fold-integer.cpp
@@ -297,7 +297,9 @@ static Expr<T> FoldCount(FoldingContext &context, FunctionRef<T> &&ref) {
     CountAccumulator<T, maskKind> accumulator{arrayAndMask->array};
     Constant<T> result{DoReduction<T>(arrayAndMask->array, arrayAndMask->mask,
         dim, Scalar<T>{}, accumulator)};
-    if (accumulator.overflow()) {
+    if (accumulator.overflow() &&
+        context.languageFeatures().ShouldWarn(
+            common::UsageWarning::FoldingException)) {
       context.messages().Say(
           "Result of intrinsic function COUNT overflows its result type"_warn_en_US);
     }
@@ -556,7 +558,9 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
   std::string name{intrinsic->name};
   auto FromInt64{[&name, &context](std::int64_t n) {
     Scalar<T> result{n};
-    if (result.ToInt64() != n) {
+    if (result.ToInt64() != n &&
+        context.languageFeatures().ShouldWarn(
+            common::UsageWarning::FoldingException)) {
       context.messages().Say(
           "Result of intrinsic function '%s' (%jd) overflows its result type"_warn_en_US,
           name, std::intmax_t{n});
@@ -567,7 +571,9 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
     return FoldElementalIntrinsic<T, T>(context, std::move(funcRef),
         ScalarFunc<T, T>([&context](const Scalar<T> &i) -> Scalar<T> {
           typename Scalar<T>::ValueWithOverflow j{i.ABS()};
-          if (j.overflow) {
+          if (j.overflow &&
+              context.languageFeatures().ShouldWarn(
+                  common::UsageWarning::FoldingException)) {
             context.messages().Say(
                 "abs(integer(kind=%d)) folding overflowed"_warn_en_US, KIND);
           }
@@ -587,7 +593,9 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
             return FoldElementalIntrinsic<T, TR>(context, std::move(funcRef),
                 ScalarFunc<T, TR>([&](const Scalar<TR> &x) {
                   auto y{x.template ToInteger<Scalar<T>>(mode)};
-                  if (y.flags.test(RealFlag::Overflow)) {
+                  if (y.flags.test(RealFlag::Overflow) &&
+                      context.languageFeatures().ShouldWarn(
+                          common::UsageWarning::FoldingException)) {
                     context.messages().Say(
                         "%s intrinsic folding overflow"_warn_en_US, name);
                   }
@@ -634,7 +642,9 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
         ScalarFunc<T, T, T>([&context](const Scalar<T> &x,
                                 const Scalar<T> &y) -> Scalar<T> {
           auto result{x.DIM(y)};
- ...
[truncated]

``````````

</details>


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


More information about the flang-commits mailing list