[flang-commits] [flang] dd41453 - [flang] Allow a generic-spec on a PUBLIC/PRIVATE statement to declare a generic

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Fri Sep 23 14:53:30 PDT 2022


Author: Peter Klausler
Date: 2022-09-23T14:17:42-07:00
New Revision: dd41453f1b5ee2b393f701c9f7b0619ec1dd8744

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

LOG: [flang] Allow a generic-spec on a PUBLIC/PRIVATE statement to declare a generic

A generic-spec can appear on a module accessibility control statement
even if it has not been declared as a generic interface, because there's
nothing else that it could be.

While here, simplify the parse tree and parser for AccessId, since
one of its alternatives is ambiguous with the other.

Differential Revision: https://reviews.llvm.org/D134471

Added: 
    flang/test/Semantics/modfile51.f90

Modified: 
    flang/include/flang/Parser/parse-tree.h
    flang/lib/Parser/Fortran-parsers.cpp
    flang/lib/Semantics/resolve-names.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index b37ad6179395a..16987fb9660a3 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -1356,10 +1356,8 @@ struct TypeDeclarationStmt {
 };
 
 // R828 access-id -> access-name | generic-spec
-struct AccessId {
-  UNION_CLASS_BOILERPLATE(AccessId);
-  std::variant<Name, common::Indirection<GenericSpec>> u;
-};
+// "access-name" is ambiguous with "generic-spec", so that's what's parsed
+WRAPPER_CLASS(AccessId, common::Indirection<GenericSpec>);
 
 // R827 access-stmt -> access-spec [[::] access-id-list]
 struct AccessStmt {

diff  --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp
index e1c2ad40963bb..a508ac2027ad0 100644
--- a/flang/lib/Parser/Fortran-parsers.cpp
+++ b/flang/lib/Parser/Fortran-parsers.cpp
@@ -758,8 +758,8 @@ TYPE_PARSER(construct<AccessStmt>(accessSpec,
             Parser<AccessId>{}))))
 
 // R828 access-id -> access-name | generic-spec
-TYPE_PARSER(construct<AccessId>(indirect(genericSpec)) ||
-    construct<AccessId>(name)) // initially ambiguous with genericSpec
+// "access-name" is ambiguous with "generic-spec"
+TYPE_PARSER(construct<AccessId>(indirect(genericSpec)))
 
 // R829 allocatable-stmt -> ALLOCATABLE [::] allocatable-decl-list
 TYPE_PARSER(construct<AllocatableStmt>("ALLOCATABLE" >> maybe("::"_tok) >>

diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 4beb0207710f4..a339f868b1e0c 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -7102,24 +7102,12 @@ bool ModuleVisitor::Pre(const parser::AccessStmt &x) {
     defaultAccess_ = accessAttr;
   } else {
     for (const auto &accessId : accessIds) {
-      common::visit(
-          common::visitors{
-              [=](const parser::Name &y) {
-                Resolve(y, SetAccess(y.source, accessAttr));
-              },
-              [=](const Indirection<parser::GenericSpec> &y) {
-                auto info{GenericSpecInfo{y.value()}};
-                const auto &symbolName{info.symbolName()};
-                if (auto *symbol{FindInScope(symbolName)}) {
-                  info.Resolve(&SetAccess(symbolName, accessAttr, symbol));
-                } else if (info.kind().IsName()) {
-                  info.Resolve(&SetAccess(symbolName, accessAttr));
-                } else {
-                  Say(symbolName, "Generic spec '%s' not found"_err_en_US);
-                }
-              },
-          },
-          accessId.u);
+      GenericSpecInfo info{accessId.v.value()};
+      auto *symbol{FindInScope(info.symbolName())};
+      if (!symbol && !info.kind().IsName()) {
+        symbol = &MakeSymbol(info.symbolName(), Attrs{}, GenericDetails{});
+      }
+      info.Resolve(&SetAccess(info.symbolName(), accessAttr, symbol));
     }
   }
   return false;

diff  --git a/flang/test/Semantics/modfile51.f90 b/flang/test/Semantics/modfile51.f90
new file mode 100644
index 0000000000000..a8ac0df2b45c1
--- /dev/null
+++ b/flang/test/Semantics/modfile51.f90
@@ -0,0 +1,21 @@
+! RUN: %python %S/test_modfile.py %s %flang_fc1
+! Allow a generic spec that is not a name to be declared on an
+! accessibility control statement
+module m
+  public :: assignment(=)
+  public :: read(unformatted)
+  public :: operator(.eq.)
+  public :: operator(.smooth.)
+end module
+
+!Expect: m.mod
+!module m
+!interface assignment(=)
+!end interface
+!interface read(unformatted)
+!end interface
+!interface operator(.eq.)
+!end interface
+!interface operator(.smooth.)
+!end interface
+!end


        


More information about the flang-commits mailing list