[flang] Fix renames in module files
authorTim Keith <tkeith@nvidia.com>
Thu, 12 Sep 2019 16:24:04 +0000 (09:24 -0700)
committerGitHub <noreply@github.com>
Mon, 16 Sep 2019 14:54:27 +0000 (07:54 -0700)
When a module contains a use-association with rename, we have to be
careful to use the correct name (i.e. the local-name, not the use-name)
when writing out its `.mod` file.

When analyzing a `Name` in an expression, follow the use-association
for details, attributes, and constant values; but if we need to make a
`Designator` or `ProcedureDesignator`, use the local name.

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

flang/lib/semantics/expression.cc
flang/test/semantics/modfile03.f90

index 71e58cc..ab7a47c 100644 (file)
@@ -597,17 +597,25 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Name &n) {
   if (std::optional<int> kind{IsAcImpliedDo(n.source)}) {
     return AsMaybeExpr(ConvertToKind<TypeCategory::Integer>(
         *kind, AsExpr(ImpliedDoIndex{n.source})));
-  } else if (!context_.HasError(n)) {
+  } else if (context_.HasError(n)) {
+    return std::nullopt;
+  } else {
     const Symbol &ultimate{n.symbol->GetUltimate()};
     if (ultimate.detailsIf<semantics::TypeParamDetails>()) {
       // A bare reference to a derived type parameter (within a parameterized
       // derived type definition)
       return AsMaybeExpr(MakeBareTypeParamInquiry(&ultimate));
     } else {
-      return Designate(DataRef{ultimate});
+      const auto *details{ultimate.detailsIf<semantics::ObjectEntityDetails>()};
+      if (details && semantics::IsNamedConstant(ultimate) && details->type() &&
+          details->type()->AsIntrinsic() && !details->IsArray() &&
+          details->init()) {
+        return details->init();
+      } else {
+        return Designate(DataRef{*n.symbol});
+      }
     }
   }
-  return std::nullopt;
 }
 
 MaybeExpr ExpressionAnalyzer::Analyze(const parser::NamedConstant &n) {
@@ -1523,7 +1531,7 @@ auto ExpressionAnalyzer::Procedure(const parser::ProcedureDesignator &pd,
               // TODO: call with implicit interface
             }
             return CalleeAndArguments{
-                ProcedureDesignator{symbol}, std::move(arguments)};
+                ProcedureDesignator{*n.symbol}, std::move(arguments)};
           },
           [&](const parser::ProcComponentRef &pcr)
               -> std::optional<CalleeAndArguments> {
index 69ede3e..c40b16d 100644 (file)
@@ -52,3 +52,55 @@ end
 !use m1,only:x1
 !use m2,only:y1
 !end
+
+module m5a
+  integer, parameter :: k1 = 4
+  integer :: l1 = 2
+  type t1
+    real :: a
+  end type
+contains
+  pure integer function f1(i)
+    f1 = i
+  end
+end
+!Expect: m5a.mod
+!module m5a
+! integer(4),parameter::k1=4_4
+! integer(4)::l1
+! type::t1
+!  real(4)::a
+! end type
+!contains
+! pure function f1(i)
+!  integer(4)::i
+!  integer(4)::f1
+! end
+!end
+
+module m5b
+  use m5a, only: k2 => k1, l2 => l1, f2 => f1
+  character(l2, k2) :: x
+  interface
+    subroutine s(x, y)
+      import f2, l2
+      character(l2, k2) :: x
+      character(f2(l2)) :: y
+    end subroutine
+  end interface
+end
+!Expect: m5b.mod
+!module m5b
+! use m5a,only:k2=>k1
+! use m5a,only:l2=>l1
+! use m5a,only:f2=>f1
+! character(l2,4)::x
+! interface
+!  subroutine s(x,y)
+!   import::l2
+!   import::f2
+!   character(l2,4)::x
+!   character(f2(l2),1)::y
+!  end
+! end interface
+!end