mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 19:06:44 +00:00
[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.
This commit is contained in:
parent
245eb0a716
commit
b949a6f5e3
@ -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 @@ public:
|
||||
warnUsage_.set(UsageWarning::BadTypeForTarget);
|
||||
warnUsage_.set(UsageWarning::VectorSubscriptFinalization);
|
||||
warnUsage_.set(UsageWarning::UndefinedFunctionResult);
|
||||
warnUsage_.set(UsageWarning::UselessIomsg);
|
||||
}
|
||||
LanguageFeatureControl(const LanguageFeatureControl &) = default;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -125,6 +125,7 @@ private:
|
||||
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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user