Skip to content

Commit 1253009

Browse files
committed
Revert "[flang] Detect circularly defined interfaces of procedures"
This reverts commit 93c5e6b. This patch updates resolve102.f90 which is now failing in 6 out 8 of our public buildbots: * http://lab.llvm.org:8011/#/builders/21/builds/9625 * http://lab.llvm.org:8011/#/builders/134/builds/2395 * http://lab.llvm.org:8011/#/builders/79/builds/6298 * http://lab.llvm.org:8011/#/builders/66/builds/2084 * http://lab.llvm.org:8011/#/builders/135/builds/2485 * http://lab.llvm.org:8011/#/builders/32/builds/3551 Please see the following revisions for more context: * https://reviews.llvm.org/D97201 * https://reviews.llvm.org/D97749
1 parent 7556abf commit 1253009

File tree

5 files changed

+23
-81
lines changed

5 files changed

+23
-81
lines changed

flang/include/flang/Semantics/semantics.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ class SemanticsContext {
199199
IndexVarKind kind;
200200
};
201201
std::map<SymbolRef, const IndexVarInfo> activeIndexVars_;
202-
SymbolSet errorSymbols_;
202+
std::set<SymbolRef> errorSymbols_;
203203
std::set<std::string> tempNames_;
204204
};
205205

flang/include/flang/Semantics/symbol.h

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@
1515
#include "flang/Common/reference.h"
1616
#include "llvm/ADT/DenseMapInfo.h"
1717
#include <array>
18-
#include <functional>
1918
#include <list>
2019
#include <optional>
21-
#include <unordered_set>
20+
#include <set>
2221
#include <vector>
2322

2423
namespace llvm {
@@ -596,7 +595,7 @@ class Symbol {
596595
bool operator==(const Symbol &that) const { return this == &that; }
597596
bool operator!=(const Symbol &that) const { return !(*this == that); }
598597
bool operator<(const Symbol &that) const {
599-
// For maps of symbols: collate them by source location
598+
// For sets of symbols: collate them by source location
600599
return name_.begin() < that.name_.begin();
601600
}
602601

@@ -766,13 +765,7 @@ inline bool operator<(SymbolRef x, SymbolRef y) { return *x < *y; }
766765
inline bool operator<(MutableSymbolRef x, MutableSymbolRef y) {
767766
return *x < *y;
768767
}
769-
struct SymbolHash {
770-
std::size_t operator()(SymbolRef symRef) const {
771-
std::hash<std::string> hasher;
772-
return hasher(symRef->name().ToString());
773-
}
774-
};
775-
using SymbolSet = std::unordered_set<SymbolRef, SymbolHash>;
768+
using SymbolSet = std::set<SymbolRef>;
776769

777770
} // namespace Fortran::semantics
778771

flang/lib/Evaluate/characteristics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ static std::optional<Procedure> CharacterizeProcedure(
369369
std::string procsList{GetSeenProcs(seenProcs)};
370370
context.messages().Say(symbol.name(),
371371
"Procedure '%s' is recursively defined. Procedures in the cycle:"
372-
" %s"_err_en_US,
372+
" '%s'"_err_en_US,
373373
symbol.name(), procsList);
374374
return std::nullopt;
375375
}

flang/lib/Semantics/resolve-names.cpp

Lines changed: 13 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,6 @@ class DeclarationVisitor : public ArraySpecVisitor,
10031003
context().SetError(symbol);
10041004
return symbol;
10051005
}
1006-
bool HasCycle(const Symbol &, const ProcInterface &);
10071006
};
10081007

10091008
// Resolve construct entities and statement entities.
@@ -2133,7 +2132,7 @@ static bool NeedsType(const Symbol &symbol) {
21332132

21342133
void ScopeHandler::ApplyImplicitRules(
21352134
Symbol &symbol, bool allowForwardReference) {
2136-
if (context().HasError(symbol) || !NeedsType(symbol)) {
2135+
if (!NeedsType(symbol)) {
21372136
return;
21382137
}
21392138
if (const DeclTypeSpec * type{GetImplicitType(symbol)}) {
@@ -3642,35 +3641,6 @@ Symbol &DeclarationVisitor::DeclareUnknownEntity(
36423641
}
36433642
}
36443643

3645-
bool DeclarationVisitor::HasCycle(
3646-
const Symbol &procSymbol, const ProcInterface &interface) {
3647-
SymbolSet procsInCycle;
3648-
procsInCycle.insert(procSymbol);
3649-
const ProcInterface *thisInterface{&interface};
3650-
bool haveInterface{true};
3651-
while (haveInterface) {
3652-
haveInterface = false;
3653-
if (const Symbol * interfaceSymbol{thisInterface->symbol()}) {
3654-
if (procsInCycle.count(*interfaceSymbol) > 0) {
3655-
for (const auto procInCycle : procsInCycle) {
3656-
Say(procInCycle->name(),
3657-
"The interface for procedure '%s' is recursively "
3658-
"defined"_err_en_US,
3659-
procInCycle->name());
3660-
context().SetError(*procInCycle);
3661-
}
3662-
return true;
3663-
} else if (const auto *procDetails{
3664-
interfaceSymbol->detailsIf<ProcEntityDetails>()}) {
3665-
haveInterface = true;
3666-
thisInterface = &procDetails->interface();
3667-
procsInCycle.insert(*interfaceSymbol);
3668-
}
3669-
}
3670-
}
3671-
return false;
3672-
}
3673-
36743644
Symbol &DeclarationVisitor::DeclareProcEntity(
36753645
const parser::Name &name, Attrs attrs, const ProcInterface &interface) {
36763646
Symbol &symbol{DeclareEntity<ProcEntityDetails>(name, attrs)};
@@ -3680,20 +3650,20 @@ Symbol &DeclarationVisitor::DeclareProcEntity(
36803650
"The interface for procedure '%s' has already been "
36813651
"declared"_err_en_US);
36823652
context().SetError(symbol);
3683-
} else if (HasCycle(symbol, interface)) {
3684-
return symbol;
3685-
} else if (interface.type()) {
3686-
symbol.set(Symbol::Flag::Function);
3687-
} else if (interface.symbol()) {
3688-
if (interface.symbol()->test(Symbol::Flag::Function)) {
3653+
} else {
3654+
if (interface.type()) {
36893655
symbol.set(Symbol::Flag::Function);
3690-
} else if (interface.symbol()->test(Symbol::Flag::Subroutine)) {
3691-
symbol.set(Symbol::Flag::Subroutine);
3656+
} else if (interface.symbol()) {
3657+
if (interface.symbol()->test(Symbol::Flag::Function)) {
3658+
symbol.set(Symbol::Flag::Function);
3659+
} else if (interface.symbol()->test(Symbol::Flag::Subroutine)) {
3660+
symbol.set(Symbol::Flag::Subroutine);
3661+
}
36923662
}
3663+
details->set_interface(interface);
3664+
SetBindNameOn(symbol);
3665+
SetPassNameOn(symbol);
36933666
}
3694-
details->set_interface(interface);
3695-
SetBindNameOn(symbol);
3696-
SetPassNameOn(symbol);
36973667
}
36983668
return symbol;
36993669
}
@@ -5035,7 +5005,7 @@ Symbol *DeclarationVisitor::NoteInterfaceName(const parser::Name &name) {
50355005

50365006
void DeclarationVisitor::CheckExplicitInterface(const parser::Name &name) {
50375007
if (const Symbol * symbol{name.symbol}) {
5038-
if (!context().HasError(*symbol) && !symbol->HasExplicitInterface()) {
5008+
if (!symbol->HasExplicitInterface()) {
50395009
Say(name,
50405010
"'%s' must be an abstract interface or a procedure with "
50415011
"an explicit interface"_err_en_US,

flang/test/Semantics/resolve102.f90

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
! RUN: %S/test_errors.sh %s %t %f18
22

33
! Tests for circularly defined procedures
4-
!ERROR: Procedure 'sub' is recursively defined. Procedures in the cycle: 'p2', 'sub'
4+
!ERROR: Procedure 'sub' is recursively defined. Procedures in the cycle: ''sub', 'p2''
55
subroutine sub(p2)
66
PROCEDURE(sub) :: p2
77

88
call sub()
99
end subroutine
1010

1111
subroutine circular
12-
!ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: 'p2', 'p', 'sub'
12+
!ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: ''p', 'sub', 'p2''
1313
procedure(sub) :: p
1414

1515
call p(sub)
@@ -21,7 +21,7 @@ subroutine sub(p2)
2121
end subroutine circular
2222

2323
program iface
24-
!ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: 'p2', 'p', 'sub'
24+
!ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: ''p', 'sub', 'p2''
2525
procedure(sub) :: p
2626
interface
2727
subroutine sub(p2)
@@ -38,7 +38,7 @@ Program mutual
3838
Call p(sub)
3939

4040
contains
41-
!ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'p', 'arg', 'sub1'
41+
!ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: ''p', 'sub1', 'arg''
4242
Subroutine sub1(arg)
4343
procedure(sub1) :: arg
4444
End Subroutine
@@ -54,7 +54,7 @@ Program mutual1
5454
Call p(sub)
5555

5656
contains
57-
!ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'p2', 'sub', 'p', 'arg', 'sub1'
57+
!ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: ''p', 'sub1', 'arg', 'sub', 'p2''
5858
Subroutine sub1(arg)
5959
procedure(sub) :: arg
6060
End Subroutine
@@ -63,24 +63,3 @@ Subroutine sub(p2)
6363
Procedure(sub1) :: p2
6464
End Subroutine
6565
End Program
66-
67-
program twoCycle
68-
!ERROR: The interface for procedure 'p1' is recursively defined
69-
!ERROR: The interface for procedure 'p2' is recursively defined
70-
procedure(p1) p2
71-
procedure(p2) p1
72-
call p1
73-
call p2
74-
end program
75-
76-
program threeCycle
77-
!ERROR: The interface for procedure 'p1' is recursively defined
78-
!ERROR: The interface for procedure 'p2' is recursively defined
79-
procedure(p1) p2
80-
!ERROR: The interface for procedure 'p3' is recursively defined
81-
procedure(p2) p3
82-
procedure(p3) p1
83-
call p1
84-
call p2
85-
call p3
86-
end program

0 commit comments

Comments
 (0)