Skip to content

[flang] Correct accessibility of name that is both generic and derive… #85098

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3391,12 +3391,25 @@ void ModuleVisitor::ApplyDefaultAccess() {
const auto *moduleDetails{
DEREF(currScope().symbol()).detailsIf<ModuleDetails>()};
CHECK(moduleDetails);
Attr defaultAttr{
DEREF(moduleDetails).isDefaultPrivate() ? Attr::PRIVATE : Attr::PUBLIC};
for (auto &pair : currScope()) {
Symbol &symbol{*pair.second};
if (!symbol.attrs().HasAny({Attr::PUBLIC, Attr::PRIVATE})) {
SetImplicitAttr(symbol,
DEREF(moduleDetails).isDefaultPrivate() ? Attr::PRIVATE
: Attr::PUBLIC);
Attr attr{defaultAttr};
if (auto *generic{symbol.detailsIf<GenericDetails>()}) {
if (generic->derivedType()) {
// If a generic interface has a derived type of the same
// name that has an explicit accessibility attribute, then
// the generic must have the same accessibility.
if (generic->derivedType()->attrs().test(Attr::PUBLIC)) {
attr = Attr::PUBLIC;
} else if (generic->derivedType()->attrs().test(Attr::PRIVATE)) {
attr = Attr::PRIVATE;
}
}
}
SetImplicitAttr(symbol, attr);
}
}
}
Expand Down
37 changes: 37 additions & 0 deletions flang/test/Semantics/resolve11.f90
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,40 @@ logical function gt(x, y)
!ERROR: The accessibility of 'OPERATOR(.GT.)' has already been specified as PUBLIC
private :: operator(.gt.)
end

module m4
private
type, public :: foo
end type
interface foo
procedure fun
end interface
contains
function fun
end
end

subroutine s4
!ERROR: 'fun' is PRIVATE in 'm4'
use m4, only: foo, fun
type(foo) x ! ok
print *, foo() ! ok
end

module m5
public
type, private :: foo
end type
interface foo
procedure fun
end interface
contains
function fun
end
end

subroutine s5
!ERROR: 'foo' is PRIVATE in 'm5'
use m5, only: foo, fun
print *, fun() ! ok
end