[flang-commits] [flang] 689de4c - [flang] Apply default module accessibility rules a second time (bug#62598)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Tue May 16 10:19:06 PDT 2023


Author: Peter Klausler
Date: 2023-05-16T10:19:00-07:00
New Revision: 689de4c6759fa810d827aee06a0ab060b01172ce

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

LOG: [flang] Apply default module accessibility rules a second time (bug#62598)

Apply the default PUBLIC/PRIVATE accessibility of a module to its symbols
a second time after it is known that all symbols, including implicitly typed
names from NAMELIST groups and specification expressions in module subprograms,
have been created in its scope.

Fixes https://github.com/llvm/llvm-project/issues/62598.

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

Added: 
    flang/test/Semantics/symbol26.f90

Modified: 
    flang/docs/Extensions.md
    flang/include/flang/Semantics/symbol.h
    flang/lib/Semantics/resolve-names.cpp
    flang/lib/Semantics/symbol.cpp

Removed: 
    


################################################################################
diff  --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index cf6b65c0a6f5e..a91596765a594 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -453,7 +453,7 @@ end
   Other Fortran compilers disagree in their interpretations of this example;
   some seem to treat the references to `m` as if they were host associations
   to an implicitly typed variable (and print `3`), while others seem to
-  treat them as references to implicitly typed local variabless, and
+  treat them as references to implicitly typed local variables, and
   load uninitialized values.
 
   In f18, we chose to emit an error message for this case since the standard

diff  --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 3e029c98fc2e1..02d7136728c54 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -54,9 +54,12 @@ class ModuleDetails {
   const Scope *ancestor() const; // for submodule; nullptr for module
   const Scope *parent() const; // for submodule; nullptr for module
   void set_scope(const Scope *);
+  bool isDefaultPrivate() const { return isDefaultPrivate_; }
+  void set_isDefaultPrivate(bool yes = true) { isDefaultPrivate_ = yes; }
 
 private:
   bool isSubmodule_;
+  bool isDefaultPrivate_{false};
   const Scope *scope_{nullptr};
 };
 

diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 57870a7ccce02..321f819e6b733 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -749,8 +749,6 @@ class ModuleVisitor : public virtual ScopeHandler {
   }
 
 private:
-  // The default access spec for this module.
-  Attr defaultAccess_{Attr::PUBLIC};
   // The location of the last AccessStmt without access-ids, if any.
   std::optional<SourceName> prevAccessStmt_;
   // The scope of the module during a UseStmt
@@ -3119,7 +3117,6 @@ void ModuleVisitor::BeginModule(const parser::Name &name, bool isSubmodule) {
   auto &details{symbol.get<ModuleDetails>()};
   PushScope(Scope::Kind::Module, &symbol);
   details.set_scope(&currScope());
-  defaultAccess_ = Attr::PUBLIC;
   prevAccessStmt_ = std::nullopt;
 }
 
@@ -3142,10 +3139,15 @@ Scope *ModuleVisitor::FindModule(const parser::Name &name,
 }
 
 void ModuleVisitor::ApplyDefaultAccess() {
+  const auto *moduleDetails{
+      DEREF(currScope().symbol()).detailsIf<ModuleDetails>()};
+  CHECK(moduleDetails);
   for (auto &pair : currScope()) {
-    Symbol &symbol = *pair.second;
+    Symbol &symbol{*pair.second};
     if (!symbol.attrs().HasAny({Attr::PUBLIC, Attr::PRIVATE})) {
-      SetImplicitAttr(symbol, defaultAccess_);
+      SetImplicitAttr(symbol,
+          DEREF(moduleDetails).isDefaultPrivate() ? Attr::PRIVATE
+                                                  : Attr::PUBLIC);
     }
   }
 }
@@ -7319,7 +7321,8 @@ bool ModuleVisitor::Pre(const parser::AccessStmt &x) {
           .Attach(*prevAccessStmt_, "Previous declaration"_en_US);
     }
     prevAccessStmt_ = currStmtSource();
-    defaultAccess_ = accessAttr;
+    auto *moduleDetails{DEREF(currScope().symbol()).detailsIf<ModuleDetails>()};
+    DEREF(moduleDetails).set_isDefaultPrivate(accessAttr == Attr::PRIVATE);
   } else {
     for (const auto &accessId : accessIds) {
       GenericSpecInfo info{accessId.v.value()};
@@ -8232,6 +8235,12 @@ void ResolveNamesVisitor::ResolveExecutionParts(const ProgramTree &node) {
     Walk(*exec);
   }
   FinishNamelists();
+  if (node.IsModule()) {
+    // A second final pass to catch new symbols added from implicitly
+    // typed names in NAMELIST groups or the specification parts of
+    // module subprograms.
+    ApplyDefaultAccess();
+  }
   PopScope(); // converts unclassified entities into objects
   for (const auto &child : node.children()) {
     ResolveExecutionParts(child);

diff  --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index ca917531165cb..d35938971d753 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -494,6 +494,9 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Details &details) {
               }
               os << ")";
             }
+            if (x.isDefaultPrivate()) {
+              os << " isDefaultPrivate";
+            }
           },
           [&](const SubprogramNameDetails &x) {
             os << ' ' << EnumToString(x.kind());

diff  --git a/flang/test/Semantics/symbol26.f90 b/flang/test/Semantics/symbol26.f90
new file mode 100644
index 0000000000000..f5e95853ca099
--- /dev/null
+++ b/flang/test/Semantics/symbol26.f90
@@ -0,0 +1,23 @@
+! RUN: %python %S/test_symbols.py %s %flang_fc1
+! Regression test for https://github.com/llvm/llvm-project/issues/62598
+! Ensure that implicitly typed names in module NAMELIST groups receive
+! the module's default accessibility attribute.
+!DEF: /m Module
+module m
+ !DEF: /m/a PUBLIC Namelist
+ !DEF: /m/j PUBLIC (Implicit, InNamelist) ObjectEntity INTEGER(4)
+ namelist/a/j
+end module m
+!DEF: /main MainProgram
+program main
+ !DEF: /main/j (Implicit) ObjectEntity INTEGER(4)
+ j = 1
+contains
+ !DEF: /main/inner (Subroutine) Subprogram
+ subroutine inner
+  !REF: /m
+  use :: m
+  !DEF: /main/inner/j (Implicit, InNamelist) Use INTEGER(4)
+  j = 2
+ end subroutine
+end program


        


More information about the flang-commits mailing list