[flang-commits] [flang] cbcaae2 - [flang] Warn about assumed-rank items in I/O lists (#182957)
via flang-commits
flang-commits at lists.llvm.org
Thu Feb 26 06:59:54 PST 2026
Author: Peter Klausler
Date: 2026-02-26T06:59:49-08:00
New Revision: cbcaae2b5c33ef316f25538bc5cb4c88b71d2f22
URL: https://github.com/llvm/llvm-project/commit/cbcaae2b5c33ef316f25538bc5cb4c88b71d2f22
DIFF: https://github.com/llvm/llvm-project/commit/cbcaae2b5c33ef316f25538bc5cb4c88b71d2f22.diff
LOG: [flang] Warn about assumed-rank items in I/O lists (#182957)
An assumed-rank dummy argument is not a conforming I/O list or NAMELIST
group item. Add a -pedantic warning and some documentation.
Added:
flang/test/Semantics/io16.f90
Modified:
flang/docs/Extensions.md
flang/include/flang/Support/Fortran-features.h
flang/lib/Semantics/check-io.cpp
flang/lib/Semantics/check-io.h
flang/lib/Semantics/resolve-names.cpp
Removed:
################################################################################
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 79e6213f7f3c9..028e3ea80623f 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -483,6 +483,7 @@ end
are to the same value. Distinct initializations remain errors.
* A pointer component that has no default initialization or explicit value
in a structure constructor is defaulted to `NULL()`.
+* An assumed-rank entity is an acceptable `NAMELIST` group item.
### Extensions supported when enabled by options
diff --git a/flang/include/flang/Support/Fortran-features.h b/flang/include/flang/Support/Fortran-features.h
index f6c963d05fd54..e5cf915e9f78b 100644
--- a/flang/include/flang/Support/Fortran-features.h
+++ b/flang/include/flang/Support/Fortran-features.h
@@ -57,7 +57,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
ForwardRefExplicitTypeDummy, InaccessibleDeferredOverride,
CudaWarpMatchFunction, DoConcurrentOffload, TransferBOZ, Coarray,
PointerPassObject, MultipleIdenticalDATA,
- DefaultStructConstructorNullPointer)
+ DefaultStructConstructorNullPointer, AssumedRankIoItem)
// Portability and suspicious usage warnings
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
diff --git a/flang/lib/Semantics/check-io.cpp b/flang/lib/Semantics/check-io.cpp
index 19059ad1b1223..2d7e419e76ce0 100644
--- a/flang/lib/Semantics/check-io.cpp
+++ b/flang/lib/Semantics/check-io.cpp
@@ -327,10 +327,12 @@ void IoChecker::Enter(const parser::InputItem &spec) {
}
CheckForDefinableVariable(*var, "Input");
if (auto expr{AnalyzeExpr(context_, *var)}) {
+ auto at{var->GetSource()};
+ CheckForAssumedRank(UnwrapWholeSymbolDataRef(*expr), at);
CheckForBadIoType(*expr,
flags_.test(Flag::FmtOrNml) ? common::DefinedIo::ReadFormatted
: common::DefinedIo::ReadUnformatted,
- var->GetSource());
+ at);
}
}
@@ -651,11 +653,14 @@ void IoChecker::Enter(const parser::OutputItem &item) {
} else if (IsProcedure(*expr)) {
context_.Say(parser::FindSourceLocation(*x),
"Output item must not be a procedure"_err_en_US); // C1233
+ } else {
+ auto at{parser::FindSourceLocation(item)};
+ CheckForAssumedRank(UnwrapWholeSymbolDataRef(*expr), at);
+ CheckForBadIoType(*expr,
+ flags_.test(Flag::FmtOrNml) ? common::DefinedIo::WriteFormatted
+ : common::DefinedIo::WriteUnformatted,
+ at);
}
- CheckForBadIoType(*expr,
- flags_.test(Flag::FmtOrNml) ? common::DefinedIo::WriteFormatted
- : common::DefinedIo::WriteUnformatted,
- parser::FindSourceLocation(item));
}
}
}
@@ -1228,6 +1233,17 @@ parser::Message *IoChecker::CheckForBadIoType(const Symbol &symbol,
return nullptr;
}
+void IoChecker::CheckForAssumedRank(
+ const Symbol *symbol, parser::CharBlock namelistLocation) const {
+ if (symbol && IsAssumedRank(*symbol)) {
+ evaluate::AttachDeclaration(
+ context_.Say(namelistLocation,
+ "Assumed-rank object '%s' may not be an I/O list item"_err_en_US,
+ symbol->name()),
+ *symbol);
+ }
+}
+
void IoChecker::CheckNamelist(const Symbol &namelist, common::DefinedIo which,
parser::CharBlock namelistLocation) const {
if (!context_.HasError(namelist)) {
diff --git a/flang/lib/Semantics/check-io.h b/flang/lib/Semantics/check-io.h
index 2fb03c63afe35..96a07ce13f7bb 100644
--- a/flang/lib/Semantics/check-io.h
+++ b/flang/lib/Semantics/check-io.h
@@ -133,6 +133,7 @@ class IoChecker : public virtual BaseChecker {
const SomeExpr &, common::DefinedIo, parser::CharBlock) const;
parser::Message *CheckForBadIoType(
const Symbol &, common::DefinedIo, parser::CharBlock) const;
+ void CheckForAssumedRank(const Symbol *, parser::CharBlock) const;
void CheckNamelist(
const Symbol &, common::DefinedIo, parser::CharBlock) const;
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 9036defa0c711..35b1cc282fdd4 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -7228,6 +7228,13 @@ void DeclarationVisitor::FinishNamelists() {
} else if (!ConvertToObjectEntity(symbol->GetUltimate())) {
SayWithDecl(name, *symbol, "'%s' is not a variable"_err_en_US);
context().SetError(*groupSymbol);
+ } else if (IsAssumedRank(*symbol)) {
+ evaluate::AttachDeclaration(
+ context().Warn(common::LanguageFeature::AssumedRankIoItem,
+ name.source,
+ "Assumed-rank object '%s' should not be a namelist group item"_port_en_US,
+ symbol->name()),
+ *symbol);
}
symbol->GetUltimate().set(Symbol::Flag::InNamelist);
details->add_object(*symbol);
diff --git a/flang/test/Semantics/io16.f90 b/flang/test/Semantics/io16.f90
new file mode 100644
index 0000000000000..7d721d2ba40dc
--- /dev/null
+++ b/flang/test/Semantics/io16.f90
@@ -0,0 +1,15 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
+subroutine assumedRank(x, y)
+ real x(..), y(*)
+ !PORTABILITY: Assumed-rank object 'x' should not be a namelist group item [-Wassumed-rank-io-item]
+ !ERROR: A namelist group object 'y' must not be assumed-size
+ namelist /nml/x, y
+ !ERROR: Assumed-rank object 'x' may not be an I/O list item
+ !ERROR: Whole assumed-size array 'y' may not appear here without subscripts
+ read *, x, y
+ !ERROR: Assumed-rank object 'x' may not be an I/O list item
+ !ERROR: Whole assumed-size array 'y' may not appear here without subscripts
+ print *, x, y
+ read(*,nml=nml)
+ write(*,nml=nml)
+end
More information about the flang-commits
mailing list