[flang-commits] [flang] b949a6f - [flang] Warn on useless IOMSG= (#102250)

via flang-commits flang-commits at lists.llvm.org
Thu Aug 8 11:08:30 PDT 2024


Author: Peter Klausler
Date: 2024-08-08T11:08:26-07:00
New Revision: b949a6f5e3219290ce090895e284d12fc76f9d61

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

LOG: [flang] Warn on useless IOMSG= (#102250)

An I/O statement with IOMSG= but neither ERR= nor IOSTAT= deserves a
warning to the effect that it's not useful.

Added: 
    

Modified: 
    flang/include/flang/Common/Fortran-features.h
    flang/lib/Semantics/check-io.cpp
    flang/lib/Semantics/check-io.h
    flang/lib/Semantics/semantics.cpp
    flang/test/Semantics/io05.f90
    flang/test/Semantics/undef-result01.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h
index 518304191d63f7..6ef5f44c89db07 100644
--- a/flang/include/flang/Common/Fortran-features.h
+++ b/flang/include/flang/Common/Fortran-features.h
@@ -70,7 +70,7 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
     IgnoredIntrinsicFunctionType, PreviousScalarUse,
     RedeclaredInaccessibleComponent, ImplicitShared, IndexVarRedefinition,
     IncompatibleImplicitInterfaces, BadTypeForTarget,
-    VectorSubscriptFinalization, UndefinedFunctionResult)
+    VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg)
 
 using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
 using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;
@@ -145,6 +145,7 @@ class LanguageFeatureControl {
     warnUsage_.set(UsageWarning::BadTypeForTarget);
     warnUsage_.set(UsageWarning::VectorSubscriptFinalization);
     warnUsage_.set(UsageWarning::UndefinedFunctionResult);
+    warnUsage_.set(UsageWarning::UselessIomsg);
   }
   LanguageFeatureControl(const LanguageFeatureControl &) = default;
 

diff  --git a/flang/lib/Semantics/check-io.cpp b/flang/lib/Semantics/check-io.cpp
index 8bde737c4cb948..54e8e09cbf7e48 100644
--- a/flang/lib/Semantics/check-io.cpp
+++ b/flang/lib/Semantics/check-io.cpp
@@ -675,6 +675,7 @@ void IoChecker::Leave(const parser::BackspaceStmt &) {
   CheckForPureSubprogram();
   CheckForRequiredSpecifier(
       flags_.test(Flag::NumberUnit), "UNIT number"); // C1240
+  CheckForUselessIomsg();
   Done();
 }
 
@@ -682,6 +683,7 @@ void IoChecker::Leave(const parser::CloseStmt &) {
   CheckForPureSubprogram();
   CheckForRequiredSpecifier(
       flags_.test(Flag::NumberUnit), "UNIT number"); // C1208
+  CheckForUselessIomsg();
   Done();
 }
 
@@ -689,6 +691,7 @@ void IoChecker::Leave(const parser::EndfileStmt &) {
   CheckForPureSubprogram();
   CheckForRequiredSpecifier(
       flags_.test(Flag::NumberUnit), "UNIT number"); // C1240
+  CheckForUselessIomsg();
   Done();
 }
 
@@ -696,6 +699,7 @@ void IoChecker::Leave(const parser::FlushStmt &) {
   CheckForPureSubprogram();
   CheckForRequiredSpecifier(
       flags_.test(Flag::NumberUnit), "UNIT number"); // C1243
+  CheckForUselessIomsg();
   Done();
 }
 
@@ -708,6 +712,7 @@ void IoChecker::Leave(const parser::InquireStmt &stmt) {
         "UNIT number or FILE"); // C1246
     CheckForProhibitedSpecifier(IoSpecKind::File, IoSpecKind::Unit); // C1246
     CheckForRequiredSpecifier(IoSpecKind::Id, IoSpecKind::Pending); // C1248
+    CheckForUselessIomsg();
   }
   Done();
 }
@@ -742,11 +747,13 @@ void IoChecker::Leave(const parser::OpenStmt &) {
     CheckForProhibitedSpecifier(flags_.test(Flag::AccessStream),
         "STATUS='STREAM'", IoSpecKind::Recl); // 12.5.6.15
   }
+  CheckForUselessIomsg();
   Done();
 }
 
 void IoChecker::Leave(const parser::PrintStmt &) {
   CheckForPureSubprogram();
+  CheckForUselessIomsg();
   Done();
 }
 
@@ -817,6 +824,7 @@ void IoChecker::Leave(const parser::RewindStmt &) {
   CheckForRequiredSpecifier(
       flags_.test(Flag::NumberUnit), "UNIT number"); // C1240
   CheckForPureSubprogram();
+  CheckForUselessIomsg();
   Done();
 }
 
@@ -824,6 +832,7 @@ void IoChecker::Leave(const parser::WaitStmt &) {
   CheckForRequiredSpecifier(
       flags_.test(Flag::NumberUnit), "UNIT number"); // C1237
   CheckForPureSubprogram();
+  CheckForUselessIomsg();
   Done();
 }
 
@@ -883,6 +892,7 @@ void IoChecker::LeaveReadWrite() const {
       "FMT or NML"); // C1227
   CheckForRequiredSpecifier(IoSpecKind::Round, flags_.test(Flag::FmtOrNml),
       "FMT or NML"); // C1227
+  CheckForUselessIomsg();
 }
 
 void IoChecker::SetSpecifier(IoSpecKind specKind) {
@@ -1057,6 +1067,15 @@ void IoChecker::CheckForPureSubprogram() const { // C1597
   }
 }
 
+void IoChecker::CheckForUselessIomsg() const {
+  if (specifierSet_.test(IoSpecKind::Iomsg) &&
+      !specifierSet_.test(IoSpecKind::Err) &&
+      !specifierSet_.test(IoSpecKind::Iostat) &&
+      context_.ShouldWarn(common::UsageWarning::UselessIomsg)) {
+    context_.Say("IOMSG= is useless without either ERR= or IOSTAT="_warn_en_US);
+  }
+}
+
 // Seeks out an allocatable or pointer ultimate component that is not
 // nested in a nonallocatable/nonpointer component with a specific
 // defined I/O procedure.

diff  --git a/flang/lib/Semantics/check-io.h b/flang/lib/Semantics/check-io.h
index 0ef166f7f100ed..2fb03c63afe353 100644
--- a/flang/lib/Semantics/check-io.h
+++ b/flang/lib/Semantics/check-io.h
@@ -125,6 +125,7 @@ class IoChecker : public virtual BaseChecker {
   void CheckForDefinableVariable(const A &var, const std::string &s) const;
 
   void CheckForPureSubprogram() const;
+  void CheckForUselessIomsg() const;
 
   parser::Message *CheckForBadIoType(const evaluate::DynamicType &,
       common::DefinedIo, parser::CharBlock) const;

diff  --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp
index 3cb24f6c6af437..f7a277d1b414f6 100644
--- a/flang/lib/Semantics/semantics.cpp
+++ b/flang/lib/Semantics/semantics.cpp
@@ -221,10 +221,13 @@ static bool PerformStatementSemantics(
   if (context.languageFeatures().IsEnabled(common::LanguageFeature::CUDA)) {
     SemanticsVisitor<CUDAChecker>{context}.Walk(program);
   }
-  if (!context.AnyFatalError()) {
+  if (!context.messages().AnyFatalError()) {
+    // Do this if all messages are only warnings
     if (context.ShouldWarn(common::UsageWarning::UndefinedFunctionResult)) {
       WarnUndefinedFunctionResult(context, context.globalScope());
     }
+  }
+  if (!context.AnyFatalError()) {
     pass2.CompileDataInitializationsIntoInitializers();
   }
   return !context.AnyFatalError();

diff  --git a/flang/test/Semantics/io05.f90 b/flang/test/Semantics/io05.f90
index 8480ea4b784c29..bef0d6db89524a 100644
--- a/flang/test/Semantics/io05.f90
+++ b/flang/test/Semantics/io05.f90
@@ -55,6 +55,7 @@
   inquire(1, read=c(1), write=c(2), sign=c(3), sign=c(4), read=c(5), write=c(1))
 
   !ERROR: Duplicate IOMSG specifier
+  !WARNING: IOMSG= is useless without either ERR= or IOSTAT=
   inquire(10, iomsg=msg, pos=ipos, iomsg=msg)
 
   !ERROR: If ID appears, PENDING must also appear

diff  --git a/flang/test/Semantics/undef-result01.f90 b/flang/test/Semantics/undef-result01.f90
index a372fcd544feea..dd73f9c76df0a5 100644
--- a/flang/test/Semantics/undef-result01.f90
+++ b/flang/test/Semantics/undef-result01.f90
@@ -121,6 +121,7 @@ integer function defdBySize()
 end
 
 character(40) function defdByIomsg()
+  !WARNING: IOMSG= is useless without either ERR= or IOSTAT=
   write(123,*,iomsg=defdByIomsg)
 end
 


        


More information about the flang-commits mailing list