diff options
author | Peter Klausler <pklausler@nvidia.com> | 2023-05-10 13:26:01 -0700 |
---|---|---|
committer | Peter Klausler <pklausler@nvidia.com> | 2023-05-16 10:19:00 -0700 |
commit | 689de4c6759fa810d827aee06a0ab060b01172ce (patch) | |
tree | b823ba7d353c01e2a8f99f6c819aea48547dbfbe /flang | |
parent | ed1539c6ad3d2c6e888985d21f841504f69beab3 (diff) | |
download | llvm-689de4c6759fa810d827aee06a0ab060b01172ce.tar.gz |
[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
Diffstat (limited to 'flang')
-rw-r--r-- | flang/docs/Extensions.md | 2 | ||||
-rw-r--r-- | flang/include/flang/Semantics/symbol.h | 3 | ||||
-rw-r--r-- | flang/lib/Semantics/resolve-names.cpp | 21 | ||||
-rw-r--r-- | flang/lib/Semantics/symbol.cpp | 3 | ||||
-rw-r--r-- | flang/test/Semantics/symbol26.f90 | 23 |
5 files changed, 45 insertions, 7 deletions
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md index cf6b65c0a6f5..a91596765a59 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 3e029c98fc2e..02d7136728c5 100644 --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -54,9 +54,12 @@ public: 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 57870a7ccce0..321f819e6b73 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -749,8 +749,6 @@ public: } 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 ca917531165c..d35938971d75 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 000000000000..f5e95853ca09 --- /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 |