Skip to content

Commit 7605ad8

Browse files
authored
[flang] Always check procedure characterizability (llvm#92008)
When a procedure is defined with a subprogram but never referenced in a compilation unit, it may not be characterized until lowering, and any errors in characterization then may crash the compiler. So always ensure that procedure definitions are characterizable in declaration checking. Fixes llvm#91845.
1 parent c227bf1 commit 7605ad8

File tree

4 files changed

+17
-20
lines changed

4 files changed

+17
-20
lines changed

flang/lib/Semantics/check-declarations.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,15 @@ bool CheckHelper::IsResultOkToDiffer(const FunctionResult &result) {
13571357

13581358
void CheckHelper::CheckSubprogram(
13591359
const Symbol &symbol, const SubprogramDetails &details) {
1360+
// Evaluate a procedure definition's characteristics to flush out
1361+
// any errors that analysis might expose, in case this subprogram hasn't
1362+
// had any calls in this compilation unit that would have validated them.
1363+
if (!context_.HasError(symbol) && !details.isDummy() &&
1364+
!details.isInterface() && !details.stmtFunction()) {
1365+
if (!Procedure::Characterize(symbol, foldingContext_)) {
1366+
context_.SetError(symbol);
1367+
}
1368+
}
13601369
if (const Symbol *iface{FindSeparateModuleSubprogramInterface(&symbol)}) {
13611370
SubprogramMatchHelper{*this}.Check(symbol, *iface);
13621371
}

flang/lib/Semantics/resolve-names.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5013,8 +5013,7 @@ bool DeclarationVisitor::HasCycle(
50135013
if (procsInCycle.count(*interface) > 0) {
50145014
for (const auto &procInCycle : procsInCycle) {
50155015
Say(procInCycle->name(),
5016-
"The interface for procedure '%s' is recursively "
5017-
"defined"_err_en_US,
5016+
"The interface for procedure '%s' is recursively defined"_err_en_US,
50185017
procInCycle->name());
50195018
context().SetError(*procInCycle);
50205019
}

flang/test/Semantics/entry01.f90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ function ifunc()
8383
!ERROR: 'ibad1' is already declared in this scoping unit
8484
entry ibad1() result(ibad1res) ! C1570
8585
!ERROR: 'ibad2' is already declared in this scoping unit
86+
!ERROR: Procedure 'ibad2' is referenced before being sufficiently defined in a context where it must be so
8687
entry ibad2()
8788
!ERROR: ENTRY in a function may not have an alternate return dummy argument
8889
entry ibadalt(*) ! C1573
@@ -91,6 +92,7 @@ function ifunc()
9192
entry iok()
9293
!ERROR: Explicit RESULT('iok') of function 'isameres2' cannot have the same name as a distinct ENTRY into the same scope
9394
entry isameres2() result(iok) ! C1574
95+
!ERROR: Procedure 'iok2' is referenced before being sufficiently defined in a context where it must be so
9496
!ERROR: Explicit RESULT('iok2') of function 'isameres3' cannot have the same name as a distinct ENTRY into the same scope
9597
entry isameres3() result(iok2) ! C1574
9698
!ERROR: 'iok2' is already declared in this scoping unit

flang/test/Semantics/resolve102.f90

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,12 @@
44
!ERROR: Procedure 'sub' is recursively defined. Procedures in the cycle: 'sub', 'p2'
55
subroutine sub(p2)
66
PROCEDURE(sub) :: p2
7-
8-
call sub()
97
end subroutine
108

119
subroutine circular
12-
!ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: 'p', 'sub', 'p2'
1310
procedure(sub) :: p
14-
15-
call p(sub)
16-
1711
contains
12+
!ERROR: Procedure 'sub' is recursively defined. Procedures in the cycle: 'p', 'sub', 'p2'
1813
subroutine sub(p2)
1914
procedure(p) :: p2
2015
end subroutine
@@ -41,11 +36,10 @@ subroutine sub(p2)
4136

4237
subroutine mutual
4338
Procedure(sub1) :: p
44-
45-
Call p(sub)
46-
4739
contains
4840
!ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'p', 'sub1', 'arg'
41+
!ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'sub1', 'arg', 'sub', 'p2'
42+
!ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'sub1', 'arg'
4943
Subroutine sub1(arg)
5044
procedure(sub1) :: arg
5145
End Subroutine
@@ -57,15 +51,14 @@ Subroutine sub(p2)
5751

5852
subroutine mutual1
5953
Procedure(sub1) :: p
60-
61-
Call p(sub)
62-
6354
contains
6455
!ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'p', 'sub1', 'arg', 'sub', 'p2'
56+
!ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'sub1', 'arg', 'sub', 'p2'
6557
Subroutine sub1(arg)
6658
procedure(sub) :: arg
6759
End Subroutine
6860

61+
!ERROR: Procedure 'sub' is recursively defined. Procedures in the cycle: 'sub1', 'arg', 'sub', 'p2'
6962
Subroutine sub(p2)
7063
Procedure(sub1) :: p2
7164
End Subroutine
@@ -76,8 +69,6 @@ subroutine twoCycle
7669
!ERROR: The interface for procedure 'p2' is recursively defined
7770
procedure(p1) p2
7871
procedure(p2) p1
79-
call p1
80-
call p2
8172
end subroutine
8273

8374
subroutine threeCycle
@@ -87,9 +78,6 @@ subroutine threeCycle
8778
!ERROR: The interface for procedure 'p3' is recursively defined
8879
procedure(p2) p3
8980
procedure(p3) p1
90-
call p1
91-
call p2
92-
call p3
9381
end subroutine
9482

9583
module mutualSpecExprs
@@ -118,4 +106,3 @@ function ifunc(x)
118106
ifunc = x
119107
end
120108
end
121-

0 commit comments

Comments
 (0)