[flang-commits] [flang] fd4c958 - [flang] Correct handling of USE-associated generic override in nested scope
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Fri Mar 10 10:09:14 PST 2023
Author: Peter Klausler
Date: 2023-03-10T09:59:38-08:00
New Revision: fd4c958dc5b3e052e5e717c3bf0f914a70466d84
URL: https://github.com/llvm/llvm-project/commit/fd4c958dc5b3e052e5e717c3bf0f914a70466d84
DIFF: https://github.com/llvm/llvm-project/commit/fd4c958dc5b3e052e5e717c3bf0f914a70466d84.diff
LOG: [flang] Correct handling of USE-associated generic override in nested scope
As the new test here shows by failing with the current compiler with
a bogus error message about indistinguishable specific procedures in
a generic interface, name resolution needs to take care to not
copy a USE-associated generic into the current scope for extension
when the USE association is actually into an enclosing scope.
Differential Revision: https://reviews.llvm.org/D145750
Added:
flang/test/Semantics/symbol25.f90
Modified:
flang/lib/Semantics/resolve-names.cpp
Removed:
################################################################################
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index f5bbced783fc..ff5ae4af866d 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -7480,16 +7480,17 @@ void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
if (existing) {
Symbol &ultimate{existing->GetUltimate()};
if (auto *existingGeneric{ultimate.detailsIf<GenericDetails>()}) {
- if (const auto *existingUse{existing->detailsIf<UseDetails>()}) {
- // Create a local copy of a use associated generic so that
- // it can be locally extended without corrupting the original.
- genericDetails.CopyFrom(*existingGeneric);
- if (existingGeneric->specific()) {
- genericDetails.set_specific(*existingGeneric->specific());
- }
- AddGenericUse(genericDetails, existing->name(), existingUse->symbol());
- } else if (&existing->owner() == &currScope()) {
- if (existing == &ultimate) {
+ if (&existing->owner() == &currScope()) {
+ if (const auto *existingUse{existing->detailsIf<UseDetails>()}) {
+ // Create a local copy of a use associated generic so that
+ // it can be locally extended without corrupting the original.
+ genericDetails.CopyFrom(*existingGeneric);
+ if (existingGeneric->specific()) {
+ genericDetails.set_specific(*existingGeneric->specific());
+ }
+ AddGenericUse(
+ genericDetails, existing->name(), existingUse->symbol());
+ } else if (existing == &ultimate) {
// Extending an extant generic in the same scope
info.Resolve(existing);
return;
@@ -7497,6 +7498,8 @@ void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
// Host association of a generic is handled elsewhere
CHECK(existing->has<HostAssocDetails>());
}
+ } else {
+ // Create a new generic for this scope.
}
} else if (ultimate.has<SubprogramDetails>() ||
ultimate.has<SubprogramNameDetails>()) {
diff --git a/flang/test/Semantics/symbol25.f90 b/flang/test/Semantics/symbol25.f90
new file mode 100644
index 000000000000..ac3dd37ef92e
--- /dev/null
+++ b/flang/test/Semantics/symbol25.f90
@@ -0,0 +1,60 @@
+! RUN: %python %S/test_symbols.py %s %flang_fc1
+! Exercise generic redefinitions in inner procedures with conflicting subprograms.
+!DEF: /m Module
+module m
+ !DEF: /m/generic PUBLIC (Subroutine) Generic
+ interface generic
+ !DEF: /m/specific1 PUBLIC (Subroutine) Subprogram
+ module procedure :: specific1
+ end interface
+contains
+ !REF: /m/specific1
+ subroutine specific1
+ print *, 1
+ end subroutine
+ !DEF: /m/specific2 PUBLIC (Subroutine) Subprogram
+ subroutine specific2
+ print *, 2
+ end subroutine
+ !DEF: /m/test PUBLIC (Subroutine) Subprogram
+ subroutine test
+ !REF: /m/specific1
+ call generic
+ end subroutine
+ !DEF: /m/outer PUBLIC (Subroutine) Subprogram
+ subroutine outer
+ !DEF: /m/outer/inner1 (Subroutine) Subprogram
+ call inner1
+ contains
+ !REF: /m/outer/inner1
+ subroutine inner1
+ !DEF: /m/outer/inner1/generic (Subroutine) Generic
+ interface generic
+ !REF: /m/specific2
+ module procedure :: specific2
+ end interface
+ !REF: /m/specific2
+ call generic
+ end subroutine inner1
+ end subroutine outer
+end module m
+!DEF: /main MainProgram
+program main
+ !REF: /m
+ use :: m
+ !REF: /m/specific1
+ call generic
+ !DEF: /main/inner2 (Subroutine) Subprogram
+ call inner2
+contains
+ !REF: /main/inner2
+ subroutine inner2
+ !DEF: /main/inner2/generic (Subroutine) Generic
+ interface generic
+ !DEF: /main/specific2 (Subroutine) Use
+ module procedure :: specific2
+ end interface
+ !REF: /main/specific2
+ call generic
+ end subroutine inner2
+end program
More information about the flang-commits
mailing list