[flang-commits] [flang] [flang][Semantics] Warn on repeated do-variable in nested I/O implied DO (PR #198757)
Eugene Epshteyn via flang-commits
flang-commits at lists.llvm.org
Wed May 20 06:25:30 PDT 2026
================
@@ -1191,16 +1191,70 @@ static void CheckIoImpliedDoIndex(
}
}
+// F2023 12.6.3p7: The do-variable of an io-implied-do that is in another
+// io-implied-do shall not appear as, nor be associated with, the do-variable
+// of the containing io-implied-do.
+void DoForallChecker::CheckActiveIoImpliedDoVar(const parser::Name &name) {
+ if (!name.symbol) {
+ return;
+ }
+ const Symbol &resolved{ResolveAssociations(*name.symbol)};
+ const EquivalenceSet *equivSet{FindEquivalenceSet(resolved)};
+ for (const Symbol *active : activeIoImpliedDoVars_) {
+ const Symbol &activeResolved{ResolveAssociations(*active)};
+ bool associated{&resolved == &activeResolved};
+ if (!associated && equivSet) {
+ for (const EquivalenceObject &obj : *equivSet) {
+ if (obj.symbol == activeResolved) {
+ associated = true;
+ break;
+ }
+ }
+ }
+ if (associated) {
+ if (name.symbol == active) {
+ context_.Warn(common::UsageWarning::IoImpliedDoIndexConflict,
+ name.source,
+ "I/O implied DO index '%s' appears in an enclosing I/O implied DO loop and should not have the same name"_warn_en_US,
+ name.source);
+ } else {
+ context_.Warn(common::UsageWarning::IoImpliedDoIndexConflict,
+ name.source,
+ "I/O implied DO index '%s' should not be associated with do-variable '%s' of an enclosing I/O implied DO loop"_warn_en_US,
+ name.source, active->name());
+ }
+ break;
+ }
+ }
+ activeIoImpliedDoVars_.insert(name.symbol);
+}
+
+void DoForallChecker::Enter(const parser::OutputImpliedDo &outputImpliedDo) {
+ CheckActiveIoImpliedDoVar(parser::UnwrapRef<parser::Name>(
+ std::get<parser::IoImpliedDoControl>(outputImpliedDo.t).Name()));
+}
+
+void DoForallChecker::Enter(const parser::InputImpliedDo &inputImpliedDo) {
+ CheckActiveIoImpliedDoVar(parser::UnwrapRef<parser::Name>(
+ std::get<parser::IoImpliedDoControl>(inputImpliedDo.t).Name()));
+}
+
void DoForallChecker::Leave(const parser::OutputImpliedDo &outputImpliedDo) {
- CheckIoImpliedDoIndex(context_,
- parser::UnwrapRef<parser::Name>(
- std::get<parser::IoImpliedDoControl>(outputImpliedDo.t).Name()));
+ const auto &name{parser::UnwrapRef<parser::Name>(
+ std::get<parser::IoImpliedDoControl>(outputImpliedDo.t).Name())};
+ CheckIoImpliedDoIndex(context_, name);
+ if (name.symbol) {
----------------
eugeneepshteyn wrote:
AI reviewer is concerned that this will break with sufficient nesting. Could you please check?
```
program p
integer :: cube(5,5,5), i, j, k
write(*,*) (((cube(i,j,k), k=1,5), (cube(i,j,k), k=1,5), j=1,5), k=1,5)
end
```
https://github.com/llvm/llvm-project/pull/198757
More information about the flang-commits
mailing list