From f1bcb921807248edca18831a4d8204a1479733c3 Mon Sep 17 00:00:00 2001 From: Tim Keith Date: Fri, 22 Feb 2019 11:38:43 -0800 Subject: [PATCH] [flang] Handle subprogram declaration after call 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 | 18 +++++++++++++++++- flang/test/semantics/resolve09.f90 | 28 +++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/flang/lib/semantics/resolve-names.cc b/flang/lib/semantics/resolve-names.cc index 0d4d747..549f1e5 100644 --- a/flang/lib/semantics/resolve-names.cc +++ b/flang/lib/semantics/resolve-names.cc @@ -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()) { + // 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); } diff --git a/flang/test/semantics/resolve09.f90 b/flang/test/semantics/resolve09.f90 index 1616be6..4ab6013 100644 --- a/flang/test/semantics/resolve09.f90 +++ b/flang/test/semantics/resolve09.f90 @@ -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 -- 2.7.4