[llvm-branch-commits] [flang] 3a0352b - [flang] Fix bug with USE of USE of generic

Tim Keith via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Dec 15 16:17:18 PST 2020


Author: Tim Keith
Date: 2020-12-15T16:11:59-08:00
New Revision: 3a0352b85c14cb83150df62a9ea9ac3c4129060d

URL: https://github.com/llvm/llvm-project/commit/3a0352b85c14cb83150df62a9ea9ac3c4129060d
DIFF: https://github.com/llvm/llvm-project/commit/3a0352b85c14cb83150df62a9ea9ac3c4129060d.diff

LOG: [flang] Fix bug with USE of USE of generic

When merging use associations into a generic, we weren't handling
the case where the name that was use associated was itself a use
association. This is fixed by following that association to its
ultimate symbol (`useUltimate` in `DoAddUse`).

An example of the bug is `m12d` in `resolve17.f90`. `g` is associated
with `gc` in `m12c` which is associated with `gb` in `m12b`. It was that
last association that we weren't correctly following.

Differential Revision: https://reviews.llvm.org/D93343

Added: 
    

Modified: 
    flang/lib/Semantics/resolve-names.cpp
    flang/lib/Semantics/symbol.cpp
    flang/test/Semantics/resolve17.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index b0e0b0b80ebf..5ac787b61d68 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2371,38 +2371,40 @@ void ModuleVisitor::DoAddUse(const SourceName &location,
     const SourceName &localName, Symbol &localSymbol, const Symbol &useSymbol) {
   localSymbol.attrs() = useSymbol.attrs() & ~Attrs{Attr::PUBLIC, Attr::PRIVATE};
   localSymbol.flags() = useSymbol.flags();
+  const Symbol &useUltimate{useSymbol.GetUltimate()};
   if (auto *useDetails{localSymbol.detailsIf<UseDetails>()}) {
-    const Symbol &ultimate{localSymbol.GetUltimate()};
-    if (ultimate == useSymbol.GetUltimate()) {
+    const Symbol &localUltimate{localSymbol.GetUltimate()};
+    if (localUltimate == useUltimate) {
       // use-associating the same symbol again -- ok
-    } else if (ultimate.has<GenericDetails>() &&
-        useSymbol.has<GenericDetails>()) {
+    } else if (localUltimate.has<GenericDetails>() &&
+        useUltimate.has<GenericDetails>()) {
       // use-associating generics with the same names: merge them into a
       // new generic in this scope
-      auto generic1{ultimate.get<GenericDetails>()};
-      AddGenericUse(generic1, localName, useSymbol);
+      auto generic1{localUltimate.get<GenericDetails>()};
+      AddGenericUse(generic1, localName, useUltimate);
       generic1.AddUse(localSymbol);
       // useSymbol has specific g and so does generic1
-      auto &generic2{useSymbol.get<GenericDetails>()};
+      auto &generic2{useUltimate.get<GenericDetails>()};
       if (generic1.derivedType() && generic2.derivedType() &&
           generic1.derivedType() != generic2.derivedType()) {
         Say(location,
             "Generic interface '%s' has ambiguous derived types"
             " from modules '%s' and '%s'"_err_en_US,
             localSymbol.name(), GetUsedModule(*useDetails).name(),
-            useSymbol.owner().GetName().value());
+            useUltimate.owner().GetName().value());
         context().SetError(localSymbol);
       } else {
         generic1.CopyFrom(generic2);
       }
       EraseSymbol(localSymbol);
-      MakeSymbol(localSymbol.name(), ultimate.attrs(), std::move(generic1));
+      MakeSymbol(
+          localSymbol.name(), localUltimate.attrs(), std::move(generic1));
     } else {
       ConvertToUseError(localSymbol, location, *useModuleScope_);
     }
   } else if (auto *genericDetails{localSymbol.detailsIf<GenericDetails>()}) {
-    if (const auto *useDetails{useSymbol.detailsIf<GenericDetails>()}) {
-      AddGenericUse(*genericDetails, localName, useSymbol);
+    if (const auto *useDetails{useUltimate.detailsIf<GenericDetails>()}) {
+      AddGenericUse(*genericDetails, localName, useUltimate);
       if (genericDetails->derivedType() && useDetails->derivedType() &&
           genericDetails->derivedType() != useDetails->derivedType()) {
         Say(location,

diff  --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index ee6a4a15de83..656c993935cd 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -431,8 +431,11 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Details &details) {
           },
           [&](const UseErrorDetails &x) {
             os << " uses:";
+            char sep{':'};
             for (const auto &[location, module] : x.occurrences()) {
-              os << " from " << module->GetName().value() << " at " << location;
+              os << sep << " from " << module->GetName().value() << " at "
+                 << location;
+              sep = ',';
             }
           },
           [](const HostAssocDetails &) {},

diff  --git a/flang/test/Semantics/resolve17.f90 b/flang/test/Semantics/resolve17.f90
index 5aedaaa62003..2a2688749209 100644
--- a/flang/test/Semantics/resolve17.f90
+++ b/flang/test/Semantics/resolve17.f90
@@ -238,3 +238,30 @@ module m11c
   !ERROR: Generic interface 'g' has ambiguous derived types from modules 'm11a' and 'm11b'
   use m11b
 end module
+
+module m12a
+  interface ga
+    module procedure sa
+  end interface
+contains
+  subroutine sa(i)
+  end
+end
+module m12b
+  use m12a
+  interface gb
+    module procedure sb
+  end interface
+contains
+  subroutine sb(x)
+  end
+end
+module m12c
+  use m12b, only: gc => gb
+end
+module m12d
+  use m12a, only: g => ga
+  use m12c, only: g => gc
+  interface g
+  end interface
+end module


        


More information about the llvm-branch-commits mailing list