[flang-commits] [flang] [flang] Check I/O implied DO indices better (PR #159150)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Tue Sep 16 11:44:44 PDT 2025


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/159150

We're not checking READ statement implied DO index variables at all, and we're not checking them for definability.

>From 9196e1654089a66f0ad953b7529d95c71f1ad304 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
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<parser::IoImpliedDoControl>(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<parser::IoImpliedDoControl>(outputImpliedDo.t).name.thing.thing);
+}
+
+void DoForallChecker::Leave(const parser::InputImpliedDo &inputImpliedDo) {
+  CheckIoImpliedDoIndex(context_,
+      std::get<parser::IoImpliedDoControl>(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



More information about the flang-commits mailing list