From c458c033f6728a4d0aabc9296742f6f6a9d01536 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Wed, 29 Jan 2025 10:37:17 -0800 Subject: [PATCH] [flang] Handle indirect USE of ancestor module into submodule A USE statement within a submodule (possibly in a nested scope) is not allowed to USE the submodule's ancestor module directly, but it is permissible to USE that ancestor module indirectly via another unrelated module. Don't emit "already present in scope" errors for this case. Fixes https://github.com/llvm/llvm-project/issues/124731. --- flang/lib/Semantics/resolve-names.cpp | 9 +++++++++ flang/test/Semantics/bug124731.f90 | 24 ++++++++++++++++++++++++ flang/test/Semantics/self-use.f90 | 1 - 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 flang/test/Semantics/bug124731.f90 diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index 695c8265293a8..e5aa928f8d3bf 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -3354,6 +3354,15 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName, // use-associating the same symbol again -- ok return; } + if (useUltimate.owner().IsModule() && localUltimate.owner().IsSubmodule() && + DoesScopeContain(&useUltimate.owner(), localUltimate)) { + // Within a submodule, USE'ing a symbol that comes indirectly + // from the ancestor module, e.g. foo in: + // MODULE m1; INTERFACE; MODULE SUBROUTINE foo; END INTERFACE; END + // MODULE m2; USE m1; END + // SUBMODULE m1(sm); USE m2; CONTAINS; MODULE PROCEDURE foo; END; END + return; // ok, ignore it + } if (localUltimate.name() == useUltimate.name() && localUltimate.owner().IsModule() && useUltimate.owner().IsModule() && diff --git a/flang/test/Semantics/bug124731.f90 b/flang/test/Semantics/bug124731.f90 new file mode 100644 index 0000000000000..924b41dd1db48 --- /dev/null +++ b/flang/test/Semantics/bug124731.f90 @@ -0,0 +1,24 @@ +!RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s --allow-empty +!CHECK-NOT: error: +module m1 + interface + module subroutine foo + end + end interface + real x +end +module m2 + use m1 +end +submodule(m1) sm1 + use m2 ! ok + contains + module procedure foo + end +end +submodule(m1) sm2 + contains + subroutine bar + use m2 ! ok + end +end diff --git a/flang/test/Semantics/self-use.f90 b/flang/test/Semantics/self-use.f90 index 4bc66a24343c6..12433732fc330 100644 --- a/flang/test/Semantics/self-use.f90 +++ b/flang/test/Semantics/self-use.f90 @@ -15,7 +15,6 @@ subroutine modsub contains module subroutine separate !ERROR: Module 'm' cannot USE itself from its own submodule 'submod1' - !ERROR: Cannot use-associate 'separate'; it is already declared in this scope use m end end