Skip to content

Commit 702a86a

Browse files
authored
[flang] Correct accessibility of name that is both generic and derive… (#85098)
…d type When the same name is used for a derived type and generic interface in a module, and no explicit PUBLIC or PRIVATE statement appears for the name but the derived type definition does have an explicit accessibility, that accessibility must also apply to the generic interface.
1 parent 605abe0 commit 702a86a

File tree

2 files changed

+53
-3
lines changed

2 files changed

+53
-3
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3391,12 +3391,25 @@ void ModuleVisitor::ApplyDefaultAccess() {
33913391
const auto *moduleDetails{
33923392
DEREF(currScope().symbol()).detailsIf<ModuleDetails>()};
33933393
CHECK(moduleDetails);
3394+
Attr defaultAttr{
3395+
DEREF(moduleDetails).isDefaultPrivate() ? Attr::PRIVATE : Attr::PUBLIC};
33943396
for (auto &pair : currScope()) {
33953397
Symbol &symbol{*pair.second};
33963398
if (!symbol.attrs().HasAny({Attr::PUBLIC, Attr::PRIVATE})) {
3397-
SetImplicitAttr(symbol,
3398-
DEREF(moduleDetails).isDefaultPrivate() ? Attr::PRIVATE
3399-
: Attr::PUBLIC);
3399+
Attr attr{defaultAttr};
3400+
if (auto *generic{symbol.detailsIf<GenericDetails>()}) {
3401+
if (generic->derivedType()) {
3402+
// If a generic interface has a derived type of the same
3403+
// name that has an explicit accessibility attribute, then
3404+
// the generic must have the same accessibility.
3405+
if (generic->derivedType()->attrs().test(Attr::PUBLIC)) {
3406+
attr = Attr::PUBLIC;
3407+
} else if (generic->derivedType()->attrs().test(Attr::PRIVATE)) {
3408+
attr = Attr::PRIVATE;
3409+
}
3410+
}
3411+
}
3412+
SetImplicitAttr(symbol, attr);
34003413
}
34013414
}
34023415
}

flang/test/Semantics/resolve11.f90

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,40 @@ logical function gt(x, y)
4949
!ERROR: The accessibility of 'OPERATOR(.GT.)' has already been specified as PUBLIC
5050
private :: operator(.gt.)
5151
end
52+
53+
module m4
54+
private
55+
type, public :: foo
56+
end type
57+
interface foo
58+
procedure fun
59+
end interface
60+
contains
61+
function fun
62+
end
63+
end
64+
65+
subroutine s4
66+
!ERROR: 'fun' is PRIVATE in 'm4'
67+
use m4, only: foo, fun
68+
type(foo) x ! ok
69+
print *, foo() ! ok
70+
end
71+
72+
module m5
73+
public
74+
type, private :: foo
75+
end type
76+
interface foo
77+
procedure fun
78+
end interface
79+
contains
80+
function fun
81+
end
82+
end
83+
84+
subroutine s5
85+
!ERROR: 'foo' is PRIVATE in 'm5'
86+
use m5, only: foo, fun
87+
print *, fun() ! ok
88+
end

0 commit comments

Comments
 (0)