forked from OSchip/llvm-project
Revert "[flang] Detect circularly defined interfaces of procedures"
This reverts commit 93c5e6bb49
.
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
This commit is contained in:
parent
7556abf821
commit
1253009eb2
|
@ -199,7 +199,7 @@ private:
|
|||
IndexVarKind kind;
|
||||
};
|
||||
std::map<SymbolRef, const IndexVarInfo> activeIndexVars_;
|
||||
SymbolSet errorSymbols_;
|
||||
std::set<SymbolRef> errorSymbols_;
|
||||
std::set<std::string> tempNames_;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,10 +15,9 @@
|
|||
#include "flang/Common/reference.h"
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <optional>
|
||||
#include <unordered_set>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -596,7 +595,7 @@ public:
|
|||
bool operator==(const Symbol &that) const { return this == &that; }
|
||||
bool operator!=(const Symbol &that) const { return !(*this == that); }
|
||||
bool operator<(const Symbol &that) const {
|
||||
// For maps of symbols: collate them by source location
|
||||
// For sets of symbols: collate them by source location
|
||||
return name_.begin() < that.name_.begin();
|
||||
}
|
||||
|
||||
|
@ -766,13 +765,7 @@ inline bool operator<(SymbolRef x, SymbolRef y) { return *x < *y; }
|
|||
inline bool operator<(MutableSymbolRef x, MutableSymbolRef y) {
|
||||
return *x < *y;
|
||||
}
|
||||
struct SymbolHash {
|
||||
std::size_t operator()(SymbolRef symRef) const {
|
||||
std::hash<std::string> hasher;
|
||||
return hasher(symRef->name().ToString());
|
||||
}
|
||||
};
|
||||
using SymbolSet = std::unordered_set<SymbolRef, SymbolHash>;
|
||||
using SymbolSet = std::set<SymbolRef>;
|
||||
|
||||
} // namespace Fortran::semantics
|
||||
|
||||
|
|
|
@ -369,7 +369,7 @@ static std::optional<Procedure> CharacterizeProcedure(
|
|||
std::string procsList{GetSeenProcs(seenProcs)};
|
||||
context.messages().Say(symbol.name(),
|
||||
"Procedure '%s' is recursively defined. Procedures in the cycle:"
|
||||
" %s"_err_en_US,
|
||||
" '%s'"_err_en_US,
|
||||
symbol.name(), procsList);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
|
@ -1003,7 +1003,6 @@ private:
|
|||
context().SetError(symbol);
|
||||
return symbol;
|
||||
}
|
||||
bool HasCycle(const Symbol &, const ProcInterface &);
|
||||
};
|
||||
|
||||
// Resolve construct entities and statement entities.
|
||||
|
@ -2133,7 +2132,7 @@ static bool NeedsType(const Symbol &symbol) {
|
|||
|
||||
void ScopeHandler::ApplyImplicitRules(
|
||||
Symbol &symbol, bool allowForwardReference) {
|
||||
if (context().HasError(symbol) || !NeedsType(symbol)) {
|
||||
if (!NeedsType(symbol)) {
|
||||
return;
|
||||
}
|
||||
if (const DeclTypeSpec * type{GetImplicitType(symbol)}) {
|
||||
|
@ -3642,35 +3641,6 @@ Symbol &DeclarationVisitor::DeclareUnknownEntity(
|
|||
}
|
||||
}
|
||||
|
||||
bool DeclarationVisitor::HasCycle(
|
||||
const Symbol &procSymbol, const ProcInterface &interface) {
|
||||
SymbolSet procsInCycle;
|
||||
procsInCycle.insert(procSymbol);
|
||||
const ProcInterface *thisInterface{&interface};
|
||||
bool haveInterface{true};
|
||||
while (haveInterface) {
|
||||
haveInterface = false;
|
||||
if (const Symbol * interfaceSymbol{thisInterface->symbol()}) {
|
||||
if (procsInCycle.count(*interfaceSymbol) > 0) {
|
||||
for (const auto procInCycle : procsInCycle) {
|
||||
Say(procInCycle->name(),
|
||||
"The interface for procedure '%s' is recursively "
|
||||
"defined"_err_en_US,
|
||||
procInCycle->name());
|
||||
context().SetError(*procInCycle);
|
||||
}
|
||||
return true;
|
||||
} else if (const auto *procDetails{
|
||||
interfaceSymbol->detailsIf<ProcEntityDetails>()}) {
|
||||
haveInterface = true;
|
||||
thisInterface = &procDetails->interface();
|
||||
procsInCycle.insert(*interfaceSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Symbol &DeclarationVisitor::DeclareProcEntity(
|
||||
const parser::Name &name, Attrs attrs, const ProcInterface &interface) {
|
||||
Symbol &symbol{DeclareEntity<ProcEntityDetails>(name, attrs)};
|
||||
|
@ -3680,20 +3650,20 @@ Symbol &DeclarationVisitor::DeclareProcEntity(
|
|||
"The interface for procedure '%s' has already been "
|
||||
"declared"_err_en_US);
|
||||
context().SetError(symbol);
|
||||
} else if (HasCycle(symbol, interface)) {
|
||||
return symbol;
|
||||
} else if (interface.type()) {
|
||||
symbol.set(Symbol::Flag::Function);
|
||||
} else if (interface.symbol()) {
|
||||
if (interface.symbol()->test(Symbol::Flag::Function)) {
|
||||
} else {
|
||||
if (interface.type()) {
|
||||
symbol.set(Symbol::Flag::Function);
|
||||
} else if (interface.symbol()->test(Symbol::Flag::Subroutine)) {
|
||||
symbol.set(Symbol::Flag::Subroutine);
|
||||
} else if (interface.symbol()) {
|
||||
if (interface.symbol()->test(Symbol::Flag::Function)) {
|
||||
symbol.set(Symbol::Flag::Function);
|
||||
} else if (interface.symbol()->test(Symbol::Flag::Subroutine)) {
|
||||
symbol.set(Symbol::Flag::Subroutine);
|
||||
}
|
||||
}
|
||||
details->set_interface(interface);
|
||||
SetBindNameOn(symbol);
|
||||
SetPassNameOn(symbol);
|
||||
}
|
||||
details->set_interface(interface);
|
||||
SetBindNameOn(symbol);
|
||||
SetPassNameOn(symbol);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
@ -5035,7 +5005,7 @@ Symbol *DeclarationVisitor::NoteInterfaceName(const parser::Name &name) {
|
|||
|
||||
void DeclarationVisitor::CheckExplicitInterface(const parser::Name &name) {
|
||||
if (const Symbol * symbol{name.symbol}) {
|
||||
if (!context().HasError(*symbol) && !symbol->HasExplicitInterface()) {
|
||||
if (!symbol->HasExplicitInterface()) {
|
||||
Say(name,
|
||||
"'%s' must be an abstract interface or a procedure with "
|
||||
"an explicit interface"_err_en_US,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
! RUN: %S/test_errors.sh %s %t %f18
|
||||
|
||||
! Tests for circularly defined procedures
|
||||
!ERROR: Procedure 'sub' is recursively defined. Procedures in the cycle: 'p2', 'sub'
|
||||
!ERROR: Procedure 'sub' is recursively defined. Procedures in the cycle: ''sub', 'p2''
|
||||
subroutine sub(p2)
|
||||
PROCEDURE(sub) :: p2
|
||||
|
||||
|
@ -9,7 +9,7 @@ subroutine sub(p2)
|
|||
end subroutine
|
||||
|
||||
subroutine circular
|
||||
!ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: 'p2', 'p', 'sub'
|
||||
!ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: ''p', 'sub', 'p2''
|
||||
procedure(sub) :: p
|
||||
|
||||
call p(sub)
|
||||
|
@ -21,7 +21,7 @@ subroutine circular
|
|||
end subroutine circular
|
||||
|
||||
program iface
|
||||
!ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: 'p2', 'p', 'sub'
|
||||
!ERROR: Procedure 'p' is recursively defined. Procedures in the cycle: ''p', 'sub', 'p2''
|
||||
procedure(sub) :: p
|
||||
interface
|
||||
subroutine sub(p2)
|
||||
|
@ -38,7 +38,7 @@ Program mutual
|
|||
Call p(sub)
|
||||
|
||||
contains
|
||||
!ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'p', 'arg', 'sub1'
|
||||
!ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: ''p', 'sub1', 'arg''
|
||||
Subroutine sub1(arg)
|
||||
procedure(sub1) :: arg
|
||||
End Subroutine
|
||||
|
@ -54,7 +54,7 @@ Program mutual1
|
|||
Call p(sub)
|
||||
|
||||
contains
|
||||
!ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: 'p2', 'sub', 'p', 'arg', 'sub1'
|
||||
!ERROR: Procedure 'sub1' is recursively defined. Procedures in the cycle: ''p', 'sub1', 'arg', 'sub', 'p2''
|
||||
Subroutine sub1(arg)
|
||||
procedure(sub) :: arg
|
||||
End Subroutine
|
||||
|
@ -63,24 +63,3 @@ Program mutual1
|
|||
Procedure(sub1) :: p2
|
||||
End Subroutine
|
||||
End Program
|
||||
|
||||
program twoCycle
|
||||
!ERROR: The interface for procedure 'p1' is recursively defined
|
||||
!ERROR: The interface for procedure 'p2' is recursively defined
|
||||
procedure(p1) p2
|
||||
procedure(p2) p1
|
||||
call p1
|
||||
call p2
|
||||
end program
|
||||
|
||||
program threeCycle
|
||||
!ERROR: The interface for procedure 'p1' is recursively defined
|
||||
!ERROR: The interface for procedure 'p2' is recursively defined
|
||||
procedure(p1) p2
|
||||
!ERROR: The interface for procedure 'p3' is recursively defined
|
||||
procedure(p2) p3
|
||||
procedure(p3) p1
|
||||
call p1
|
||||
call p2
|
||||
call p3
|
||||
end program
|
||||
|
|
Loading…
Reference in New Issue