[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