[flang] Handle subprogram declaration after call
authorTim Keith <tkeith@nvidia.com>
Fri, 22 Feb 2019 19:38:43 +0000 (11:38 -0800)
committerGitHub <noreply@github.com>
Thu, 28 Feb 2019 18:38:17 +0000 (10:38 -0800)
If an external subprogram is called and then declared, we have to
replace the `ProcEntityDetails` with `SubprogramDetails` in the symbol.
While doing so we can also check that the call was consistent with the
declaration for function vs. subprogram.

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

flang/lib/semantics/resolve-names.cc
flang/test/semantics/resolve09.f90

index 0d4d747..549f1e5 100644 (file)
@@ -1478,7 +1478,9 @@ void ScopeHandler::SayAlreadyDeclared(
 }
 void ScopeHandler::SayWithDecl(
     const parser::Name &name, const Symbol &symbol, MessageFixedText &&msg) {
-  Say2(name, std::move(msg), symbol, "Declaration of '%s'"_en_US);
+  Say2(name, std::move(msg), symbol,
+      symbol.test(Symbol::Flag::Implicit) ? "Implicit declaration of '%s'"_en_US
+                                          : "Declaration of '%s'"_en_US);
 }
 void ScopeHandler::SayDerivedType(
     const SourceName &name, MessageFixedText &&msg, const Scope &type) {
@@ -2340,6 +2342,20 @@ Symbol &SubprogramVisitor::PushSubprogramScope(
     const parser::Name &name, Symbol::Flag subpFlag) {
   auto *symbol{GetSpecificFromGeneric(name)};
   if (!symbol) {
+    if (auto *prev{FindSymbol(name)}) {
+      if (prev->attrs().test(Attr::EXTERNAL) &&
+          prev->has<ProcEntityDetails>()) {
+        // this subprogram was previously called, now being declared
+        if (!prev->test(subpFlag)) {
+          Say2(name,
+              subpFlag == Symbol::Flag::Function
+                  ? "'%s' was previously called as a subroutine"_err_en_US
+                  : "'%s' was previously called as a function"_err_en_US,
+              *prev, "Previous call of '%s'"_en_US);
+        }
+        EraseSymbol(name);
+      }
+    }
     symbol = &MakeSymbol(name, SubprogramDetails{});
     symbol->set(subpFlag);
   }
index 1616be6..4ab6013 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
+! Copyright (c) 2018-2019, NVIDIA CORPORATION.  All rights reserved.
 !
 ! Licensed under the Apache License, Version 2.0 (the "License");
 ! you may not use this file except in compliance with the License.
@@ -99,3 +99,29 @@ subroutine s5
     call foo()
   end block
 end
+
+subroutine s6
+  call a6()
+end
+!ERROR: 'a6' was previously called as a subroutine
+function a6()
+  a6 = 0.0
+end
+
+subroutine s7
+  x = a7()
+end
+!ERROR: 'a7' was previously called as a function
+subroutine a7()
+end
+
+!OK: use of a8 and b8 is consistent
+subroutine s8
+  call a8()
+  x = b8()
+end
+subroutine a8()
+end
+function b8()
+  b8 = 0.0
+end