From 9196e1654089a66f0ad953b7529d95c71f1ad304 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Tue, 16 Sep 2025 11:41:08 -0700 Subject: [PATCH] [flang] Check I/O implied DO indices better We're not checking READ statement implied DO index variables at all, and we're not checking them for definability. --- flang/lib/Semantics/check-do-forall.cpp | 21 +++++++++++++++++---- flang/lib/Semantics/check-do-forall.h | 2 ++ flang/test/Semantics/definable07.f90 | 8 ++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 flang/test/Semantics/definable07.f90 diff --git a/flang/lib/Semantics/check-do-forall.cpp b/flang/lib/Semantics/check-do-forall.cpp index e258df86a4b1c..a2f3685950c1c 100644 --- a/flang/lib/Semantics/check-do-forall.cpp +++ b/flang/lib/Semantics/check-do-forall.cpp @@ -1177,14 +1177,27 @@ void DoForallChecker::Leave(const parser::IoControlSpec &ioControlSpec) { } } -void DoForallChecker::Leave(const parser::OutputImpliedDo &outputImpliedDo) { - const auto &control{std::get(outputImpliedDo.t)}; - const parser::Name &name{control.name.thing.thing}; +static void CheckIoImpliedDoIndex( + SemanticsContext &context, const parser::Name &name) { if (name.symbol) { - context_.CheckIndexVarRedefine(name.source, *name.symbol); + context.CheckIndexVarRedefine(name.source, *name.symbol); + if (auto why{WhyNotDefinable(name.source, name.symbol->owner(), + DefinabilityFlags{}, *name.symbol)}) { + context.Say(std::move(*why)); + } } } +void DoForallChecker::Leave(const parser::OutputImpliedDo &outputImpliedDo) { + CheckIoImpliedDoIndex(context_, + std::get(outputImpliedDo.t).name.thing.thing); +} + +void DoForallChecker::Leave(const parser::InputImpliedDo &inputImpliedDo) { + CheckIoImpliedDoIndex(context_, + std::get(inputImpliedDo.t).name.thing.thing); +} + void DoForallChecker::Leave(const parser::StatVariable &statVariable) { context_.CheckIndexVarRedefine(statVariable.v.thing.thing); } diff --git a/flang/lib/Semantics/check-do-forall.h b/flang/lib/Semantics/check-do-forall.h index 4a65818364d76..c32d4a26a4f45 100644 --- a/flang/lib/Semantics/check-do-forall.h +++ b/flang/lib/Semantics/check-do-forall.h @@ -26,6 +26,7 @@ struct ForallStmt; struct InquireSpec; struct IoControlSpec; struct OutputImpliedDo; +struct InputImpliedDo; struct StatVariable; } // namespace Fortran::parser @@ -55,6 +56,7 @@ class DoForallChecker : public virtual BaseChecker { void Leave(const parser::InquireSpec &); void Leave(const parser::IoControlSpec &); void Leave(const parser::OutputImpliedDo &); + void Leave(const parser::InputImpliedDo &); void Leave(const parser::StatVariable &); private: diff --git a/flang/test/Semantics/definable07.f90 b/flang/test/Semantics/definable07.f90 new file mode 100644 index 0000000000000..6da90e762e162 --- /dev/null +++ b/flang/test/Semantics/definable07.f90 @@ -0,0 +1,8 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 +integer, parameter :: j = 5 +real a(5) +!ERROR: 'j' is not a variable +read *, (a(j), j=1, 5) +!ERROR: 'j' is not a variable +print *, (a(j), j=1, 5) +end