[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