Skip to content

Commit 13cd0a9

Browse files
authored
[flang] Skim usage before marking unknown module externals as subrout… (llvm#83897)
…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.
1 parent a9304ed commit 13cd0a9

File tree

2 files changed

+45
-19
lines changed

2 files changed

+45
-19
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8447,7 +8447,6 @@ void ResolveNamesVisitor::FinishSpecificationPart(
84478447
misparsedStmtFuncFound_ = false;
84488448
funcResultStack().CompleteFunctionResultType();
84498449
CheckImports();
8450-
bool inModule{currScope().kind() == Scope::Kind::Module};
84518450
for (auto &pair : currScope()) {
84528451
auto &symbol{*pair.second};
84538452
if (NeedsExplicitType(symbol)) {
@@ -8462,13 +8461,6 @@ void ResolveNamesVisitor::FinishSpecificationPart(
84628461
if (symbol.has<GenericDetails>()) {
84638462
CheckGenericProcedures(symbol);
84648463
}
8465-
if (inModule && symbol.attrs().test(Attr::EXTERNAL) &&
8466-
!symbol.test(Symbol::Flag::Function) &&
8467-
!symbol.test(Symbol::Flag::Subroutine)) {
8468-
// in a module, external proc without return type is subroutine
8469-
symbol.set(
8470-
symbol.GetType() ? Symbol::Flag::Function : Symbol::Flag::Subroutine);
8471-
}
84728464
if (!symbol.has<HostAssocDetails>()) {
84738465
CheckPossibleBadForwardRef(symbol);
84748466
}
@@ -8990,8 +8982,18 @@ void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
89908982
}
89918983
EndScopeForNode(node);
89928984
// Ensure that every object entity has a type.
8985+
bool inModule{node.GetKind() == ProgramTree::Kind::Module ||
8986+
node.GetKind() == ProgramTree::Kind::Submodule};
89938987
for (auto &pair : *node.scope()) {
8994-
ApplyImplicitRules(*pair.second);
8988+
Symbol &symbol{*pair.second};
8989+
if (inModule && symbol.attrs().test(Attr::EXTERNAL) &&
8990+
!symbol.test(Symbol::Flag::Function) &&
8991+
!symbol.test(Symbol::Flag::Subroutine)) {
8992+
// in a module, external proc without return type is subroutine
8993+
symbol.set(
8994+
symbol.GetType() ? Symbol::Flag::Function : Symbol::Flag::Subroutine);
8995+
}
8996+
ApplyImplicitRules(symbol);
89958997
}
89968998
}
89978999

flang/test/Semantics/resolve09.f90

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,49 @@ subroutine s3b()
5252
end
5353
end
5454

55-
module m
56-
! subroutine vs. function is determined at end of specification part
57-
external :: a
58-
procedure() :: b
55+
module m1
56+
!Function vs subroutine in a module is resolved to a subroutine if
57+
!no other information.
58+
external :: exts, extf, extunk
59+
procedure() :: procs, procf, procunk
5960
contains
60-
subroutine s()
61-
call a()
62-
!ERROR: Cannot call subroutine 'b' like a function
63-
x = b()
61+
subroutine s
62+
call exts()
63+
call procs()
64+
x = extf()
65+
x = procf()
6466
end
6567
end
6668

69+
module m2
70+
use m1
71+
contains
72+
subroutine test
73+
call exts() ! ok
74+
call procs() ! ok
75+
call extunk() ! ok
76+
call procunk() ! ok
77+
x = extf() ! ok
78+
x = procf() ! ok
79+
!ERROR: Cannot call subroutine 'extunk' like a function
80+
!ERROR: Function result characteristics are not known
81+
x = extunk()
82+
!ERROR: Cannot call subroutine 'procunk' like a function
83+
!ERROR: Function result characteristics are not known
84+
x = procunk()
85+
end
86+
end
87+
88+
module modulename
89+
end
90+
6791
! Call to entity in global scope, even with IMPORT, NONE
6892
subroutine s4
6993
block
7094
import, none
7195
integer :: i
72-
!ERROR: 'm' is not a callable procedure
73-
call m()
96+
!ERROR: 'modulename' is not a callable procedure
97+
call modulename()
7498
end block
7599
end
76100

0 commit comments

Comments
 (0)