diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -1364,6 +1364,7 @@ void CheckImport(const SourceName &, const SourceName &); void HandleCall(Symbol::Flag, const parser::Call &); void HandleProcedureName(Symbol::Flag, const parser::Name &); + bool CheckImplicitNoneExternal(const SourceName &, const Symbol &); bool SetProcFlag(const parser::Name &, Symbol &, Symbol::Flag); void ResolveSpecificationParts(ProgramTree &); void AddSubpNames(ProgramTree &); @@ -5853,10 +5854,7 @@ return; } if (!symbol->attrs().test(Attr::INTRINSIC)) { - if (isImplicitNoneExternal() && !symbol->attrs().test(Attr::EXTERNAL)) { - Say(name, - "'%s' is an external procedure without the EXTERNAL" - " attribute in a scope with IMPLICIT NONE(EXTERNAL)"_err_en_US); + if (!CheckImplicitNoneExternal(name.source, *symbol)) { return; } MakeExternal(*symbol); @@ -5877,6 +5875,7 @@ if (!SetProcFlag(name, *symbol, flag)) { return; // reported error } + CheckImplicitNoneExternal(name.source, *symbol); if (IsProcedure(*symbol) || symbol->has() || symbol->has() || symbol->has()) { @@ -5895,6 +5894,18 @@ } } +bool ResolveNamesVisitor::CheckImplicitNoneExternal( + const SourceName &name, const Symbol &symbol) { + if (isImplicitNoneExternal() && !symbol.attrs().test(Attr::EXTERNAL) && + !symbol.attrs().test(Attr::INTRINSIC) && !symbol.HasExplicitInterface()) { + Say(name, + "'%s' is an external procedure without the EXTERNAL" + " attribute in a scope with IMPLICIT NONE(EXTERNAL)"_err_en_US); + return false; + } + return true; +} + // Variant of HandleProcedureName() for use while skimming the executable // part of a subprogram to catch calls to dummy procedures that are part // of the subprogram's interface, and to mark as procedures any symbols diff --git a/flang/test/Semantics/implicit07.f90 b/flang/test/Semantics/implicit07.f90 --- a/flang/test/Semantics/implicit07.f90 +++ b/flang/test/Semantics/implicit07.f90 @@ -1,9 +1,12 @@ ! RUN: %S/test_errors.sh %s %t %f18 implicit none(external) external x +integer :: f, i call x !ERROR: 'y' is an external procedure without the EXTERNAL attribute in a scope with IMPLICIT NONE(EXTERNAL) call y +!ERROR: 'f' is an external procedure without the EXTERNAL attribute in a scope with IMPLICIT NONE(EXTERNAL) +i = f() block !ERROR: 'z' is an external procedure without the EXTERNAL attribute in a scope with IMPLICIT NONE(EXTERNAL) call z