summaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorPeter Klausler <pklausler@nvidia.com>2023-05-10 13:26:01 -0700
committerPeter Klausler <pklausler@nvidia.com>2023-05-16 10:19:00 -0700
commit689de4c6759fa810d827aee06a0ab060b01172ce (patch)
treeb823ba7d353c01e2a8f99f6c819aea48547dbfbe /flang
parented1539c6ad3d2c6e888985d21f841504f69beab3 (diff)
downloadllvm-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.md2
-rw-r--r--flang/include/flang/Semantics/symbol.h3
-rw-r--r--flang/lib/Semantics/resolve-names.cpp21
-rw-r--r--flang/lib/Semantics/symbol.cpp3
-rw-r--r--flang/test/Semantics/symbol26.f9023
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