[flang] Fix writing defined operators to .mod files
authorTim Keith <tkeith@nvidia.com>
Tue, 20 Aug 2019 19:05:44 +0000 (12:05 -0700)
committerTim Keith <tkeith@nvidia.com>
Fri, 23 Aug 2019 14:14:55 +0000 (07:14 -0700)
When defined operators were written to .mod files in USE statement
they did not come out correctly. They have to be emitted with
`PutGenericName()` so that `operator` is included.

Original-commit: flang-compiler/f18@d40e65a2f9c176f5334adb8132ef65273cf3615f
Reviewed-on: https://github.com/flang-compiler/f18/pull/675
Tree-same-pre-rewrite: false

flang/lib/semantics/mod-file.cc
flang/test/semantics/modfile07.f90

index 0f39107..7dffe82 100644 (file)
@@ -334,7 +334,8 @@ void ModFileWriter::PutSubprogram(const Symbol &symbol) {
 }
 
 static std::ostream &PutGenericName(std::ostream &os, const Symbol &symbol) {
-  if (symbol.get<GenericDetails>().kind() == GenericKind::DefinedOp) {
+  const auto *details{symbol.GetUltimate().detailsIf<GenericDetails>()};
+  if (details && details->kind() == GenericKind::DefinedOp) {
     return PutLower(os << "operator(", symbol) << ')';
   } else {
     return PutLower(os, symbol);
@@ -357,9 +358,9 @@ void ModFileWriter::PutUse(const Symbol &symbol) {
   auto &details{symbol.get<UseDetails>()};
   auto &use{details.symbol()};
   PutLower(uses_ << "use ", details.module());
-  PutLower(uses_ << ",only:", symbol);
+  PutGenericName(uses_ << ",only:", symbol);
   if (use.name() != symbol.name()) {
-    PutLower(uses_ << "=>", use);
+    PutGenericName(uses_ << "=>", use);
   }
   uses_ << '\n';
   PutUseExtraAttr(Attr::VOLATILE, symbol, use);
index dde8eff..0351eed 100644 (file)
@@ -13,7 +13,7 @@
 ! limitations under the License.
 
 ! Check modfile generation for generic interfaces
-module m
+module m1
   interface foo
     real function s1(x,y)
       real x,y
@@ -43,8 +43,8 @@ contains
     integer x,y
   end function
 end
-!Expect: m.mod
-!module m
+!Expect: m1.mod
+!module m1
 ! interface foo
 !  procedure::s1
 !  procedure::s2
@@ -92,6 +92,35 @@ end
 ! end
 !end
 
+module m1b
+  use m1
+end
+!Expect: m1b.mod
+!module m1b
+! use m1,only:foo
+! use m1,only:s1
+! use m1,only:s2
+! use m1,only:operator(+)
+! use m1,only:bar
+! use m1,only:operator(.bar.)
+! use m1,only:s3
+! use m1,only:s4
+!end
+
+module m1c
+  use m1, only: myfoo => foo
+  use m1, only: operator(.bar.)
+  use m1, only: operator(.mybar.) => operator(.bar.)
+  use m1, only: operator(+)
+end
+!Expect: m1c.mod
+!module m1c
+! use m1,only:myfoo=>foo
+! use m1,only:operator(.bar.)
+! use m1,only:operator(.mybar.)=>operator(.bar.)
+! use m1,only:operator(+)
+!end
+
 module m2
   interface foo
     procedure foo