[flang-commits] [flang] 00e6513 - Revert "[flang] Detect circularly defined interfaces of procedures"

Andrzej Warzynski via flang-commits flang-commits at lists.llvm.org
Mon Mar 1 02:35:02 PST 2021


Author: Andrzej Warzynski
Date: 2021-03-01T10:34:49Z
New Revision: 00e6513374eb961065d6830b30205fb0f3001c43

URL: https://github.com/llvm/llvm-project/commit/00e6513374eb961065d6830b30205fb0f3001c43
DIFF: https://github.com/llvm/llvm-project/commit/00e6513374eb961065d6830b30205fb0f3001c43.diff

LOG: Revert "[flang] Detect circularly defined interfaces of procedures"

This reverts commit 07de0846a5055015b55dc2b8faa2143f9902e549.

The original patch has caused 6 out 8 of Flang's public buildbots to
fail. As I'm not sure what the fix should be, I'm reverting this for
now. Please see https://reviews.llvm.org/D97201 for more context and
discussion.

Added: 
    

Modified: 
    flang/include/flang/Semantics/symbol.h
    flang/lib/Evaluate/characteristics.cpp
    flang/lib/Semantics/resolve-names.cpp
    flang/test/Semantics/resolve102.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 7e838379eb439..f04b05afd6e4b 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -17,7 +17,7 @@
 #include <array>
 #include <list>
 #include <optional>
-#include <unordered_set>
+#include <set>
 #include <vector>
 
 namespace llvm {
@@ -38,12 +38,6 @@ using SymbolRef = common::Reference<const Symbol>;
 using SymbolVector = std::vector<SymbolRef>;
 using MutableSymbolRef = common::Reference<Symbol>;
 using MutableSymbolVector = std::vector<MutableSymbolRef>;
-struct SymbolHash {
-  std::size_t operator()(SymbolRef symRef) const {
-    return (std::size_t)(&symRef.get());
-  }
-};
-using SymbolSet = std::unordered_set<SymbolRef, SymbolHash>;
 
 // A module or submodule.
 class ModuleDetails {
@@ -600,10 +594,9 @@ class Symbol {
 
   bool operator==(const Symbol &that) const { return this == &that; }
   bool operator!=(const Symbol &that) const { return !(*this == that); }
-  // For maps using symbols as keys and sorting symbols.  Collate them by their
-  // position in the cooked character stream
   bool operator<(const Symbol &that) const {
-    return sortName_ < that.sortName_;
+    // For sets of symbols: collate them by source location
+    return name_.begin() < that.name_.begin();
   }
 
   int Rank() const {
@@ -660,7 +653,6 @@ class Symbol {
 private:
   const Scope *owner_;
   SourceName name_;
-  const char *sortName_; // used in the "<" operator for sorting symbols
   Attrs attrs_;
   Flags flags_;
   Scope *scope_{nullptr};
@@ -695,7 +687,6 @@ template <std::size_t BLOCK_SIZE> class Symbols {
     Symbol &symbol = Get();
     symbol.owner_ = &owner;
     symbol.name_ = name;
-    symbol.sortName_ = name.begin();
     symbol.attrs_ = attrs;
     symbol.details_ = std::move(details);
     return symbol;
@@ -774,6 +765,7 @@ inline bool operator<(SymbolRef x, SymbolRef y) { return *x < *y; }
 inline bool operator<(MutableSymbolRef x, MutableSymbolRef y) {
   return *x < *y;
 }
+using SymbolSet = std::set<SymbolRef>;
 
 } // namespace Fortran::semantics
 

diff  --git a/flang/lib/Evaluate/characteristics.cpp b/flang/lib/Evaluate/characteristics.cpp
index 9b15e3e8a1cbf..1e8370928f8a0 100644
--- a/flang/lib/Evaluate/characteristics.cpp
+++ b/flang/lib/Evaluate/characteristics.cpp
@@ -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;
   }

diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 7ace9fc61dacc..7f14121d40b26 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1003,7 +1003,6 @@ class DeclarationVisitor : public ArraySpecVisitor,
     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)}) {
@@ -2157,8 +2156,10 @@ void ScopeHandler::ApplyImplicitRules(
   if (allowForwardReference && ImplicitlyTypeForwardRef(symbol)) {
     return;
   }
-  Say(symbol.name(), "No explicit type declared for '%s'"_err_en_US);
-  context().SetError(symbol);
+  if (!context().HasError(symbol)) {
+    Say(symbol.name(), "No explicit type declared for '%s'"_err_en_US);
+    context().SetError(symbol);
+  }
 }
 
 // Extension: Allow forward references to scalar integer dummy arguments
@@ -3640,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)};
@@ -3678,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;
 }
@@ -5033,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,

diff  --git a/flang/test/Semantics/resolve102.f90 b/flang/test/Semantics/resolve102.f90
index 778323b1af5ca..d6894dbd43ab3 100644
--- a/flang/test/Semantics/resolve102.f90
+++ b/flang/test/Semantics/resolve102.f90
@@ -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 sub(p2)
 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: 'arg', 'p', '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', 'arg', 'p', '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 @@ Subroutine sub(p2)
       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


        


More information about the flang-commits mailing list