-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[flang] Skim usage before marking unknown module externals as subrout… #83897
Conversation
…ines Name resolution needs to delay its default determination of module external procedures as subroutines until after it has skimmed the execution parts of module procedures. Fixes llvm#83622.
@llvm/pr-subscribers-flang-semantics Author: Peter Klausler (klausler) Changes…ines Name resolution needs to delay its default determination of module external procedures as subroutines until after it has skimmed the execution parts of module procedures. Fixes #83622. Full diff: https://github.com/llvm/llvm-project/pull/83897.diff 2 Files Affected:
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 5a95d3a98992a7..26cae833edfcff 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -8447,7 +8447,6 @@ void ResolveNamesVisitor::FinishSpecificationPart(
misparsedStmtFuncFound_ = false;
funcResultStack().CompleteFunctionResultType();
CheckImports();
- bool inModule{currScope().kind() == Scope::Kind::Module};
for (auto &pair : currScope()) {
auto &symbol{*pair.second};
if (NeedsExplicitType(symbol)) {
@@ -8462,13 +8461,6 @@ void ResolveNamesVisitor::FinishSpecificationPart(
if (symbol.has<GenericDetails>()) {
CheckGenericProcedures(symbol);
}
- if (inModule && symbol.attrs().test(Attr::EXTERNAL) &&
- !symbol.test(Symbol::Flag::Function) &&
- !symbol.test(Symbol::Flag::Subroutine)) {
- // in a module, external proc without return type is subroutine
- symbol.set(
- symbol.GetType() ? Symbol::Flag::Function : Symbol::Flag::Subroutine);
- }
if (!symbol.has<HostAssocDetails>()) {
CheckPossibleBadForwardRef(symbol);
}
@@ -8990,8 +8982,18 @@ void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
}
EndScopeForNode(node);
// Ensure that every object entity has a type.
+ bool inModule{node.GetKind() == ProgramTree::Kind::Module ||
+ node.GetKind() == ProgramTree::Kind::Submodule};
for (auto &pair : *node.scope()) {
- ApplyImplicitRules(*pair.second);
+ Symbol &symbol{*pair.second};
+ if (inModule && symbol.attrs().test(Attr::EXTERNAL) &&
+ !symbol.test(Symbol::Flag::Function) &&
+ !symbol.test(Symbol::Flag::Subroutine)) {
+ // in a module, external proc without return type is subroutine
+ symbol.set(
+ symbol.GetType() ? Symbol::Flag::Function : Symbol::Flag::Subroutine);
+ }
+ ApplyImplicitRules(symbol);
}
}
diff --git a/flang/test/Semantics/resolve09.f90 b/flang/test/Semantics/resolve09.f90
index c5e4277b3b6114..634b9861f3b67f 100644
--- a/flang/test/Semantics/resolve09.f90
+++ b/flang/test/Semantics/resolve09.f90
@@ -52,25 +52,49 @@ subroutine s3b()
end
end
-module m
- ! subroutine vs. function is determined at end of specification part
- external :: a
- procedure() :: b
+module m1
+ !Function vs subroutine in a module is resolved to a subroutine if
+ !no other information.
+ external :: exts, extf, extunk
+ procedure() :: procs, procf, procunk
contains
- subroutine s()
- call a()
- !ERROR: Cannot call subroutine 'b' like a function
- x = b()
+ subroutine s
+ call exts()
+ call procs()
+ x = extf()
+ x = procf()
end
end
+module m2
+ use m1
+ contains
+ subroutine test
+ call exts() ! ok
+ call procs() ! ok
+ call extunk() ! ok
+ call procunk() ! ok
+ x = extf() ! ok
+ x = procf() ! ok
+ !ERROR: Cannot call subroutine 'extunk' like a function
+ !ERROR: Function result characteristics are not known
+ x = extunk()
+ !ERROR: Cannot call subroutine 'procunk' like a function
+ !ERROR: Function result characteristics are not known
+ x = procunk()
+ end
+end
+
+module modulename
+end
+
! Call to entity in global scope, even with IMPORT, NONE
subroutine s4
block
import, none
integer :: i
- !ERROR: 'm' is not a callable procedure
- call m()
+ !ERROR: 'modulename' is not a callable procedure
+ call modulename()
end block
end
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All builds and tests correctly and looks good.
…ines
Name resolution needs to delay its default determination of module external procedures as subroutines until after it has skimmed the execution parts of module procedures.
Fixes #83622.