Skip to content

Commit 8fc1a64

Browse files
authored
[flang] Emit error when DEFERRED binding overrides non-DEFERRED (#139325)
Fixes #138915.
1 parent 1d8ecbe commit 8fc1a64

File tree

3 files changed

+32
-13
lines changed

3 files changed

+32
-13
lines changed

flang/lib/Evaluate/tools.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,16 +1196,6 @@ parser::Message *AttachDeclaration(
11961196
const auto *assoc{unhosted->detailsIf<semantics::HostAssocDetails>()}) {
11971197
unhosted = &assoc->symbol();
11981198
}
1199-
if (const auto *binding{
1200-
unhosted->detailsIf<semantics::ProcBindingDetails>()}) {
1201-
if (binding->symbol().name() != symbol.name()) {
1202-
message.Attach(binding->symbol().name(),
1203-
"Procedure '%s' of type '%s' is bound to '%s'"_en_US, symbol.name(),
1204-
symbol.owner().GetName().value(), binding->symbol().name());
1205-
return &message;
1206-
}
1207-
unhosted = &binding->symbol();
1208-
}
12091199
if (const auto *use{symbol.detailsIf<semantics::UseDetails>()}) {
12101200
message.Attach(use->location(),
12111201
"'%s' is USE-associated with '%s' in module '%s'"_en_US, symbol.name(),
@@ -1214,6 +1204,14 @@ parser::Message *AttachDeclaration(
12141204
message.Attach(
12151205
unhosted->name(), "Declaration of '%s'"_en_US, unhosted->name());
12161206
}
1207+
if (const auto *binding{
1208+
unhosted->detailsIf<semantics::ProcBindingDetails>()}) {
1209+
if (binding->symbol().name() != symbol.name()) {
1210+
message.Attach(binding->symbol().name(),
1211+
"Procedure '%s' of type '%s' is bound to '%s'"_en_US, symbol.name(),
1212+
symbol.owner().GetName().value(), binding->symbol().name());
1213+
}
1214+
}
12171215
return &message;
12181216
}
12191217

flang/lib/Semantics/check-declarations.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2555,6 +2555,9 @@ void CheckHelper::CheckProcBinding(
25552555
const Symbol &symbol, const ProcBindingDetails &binding) {
25562556
const Scope &dtScope{symbol.owner()};
25572557
CHECK(dtScope.kind() == Scope::Kind::DerivedType);
2558+
bool isInaccessibleDeferred{false};
2559+
const Symbol *overridden{
2560+
FindOverriddenBinding(symbol, isInaccessibleDeferred)};
25582561
if (symbol.attrs().test(Attr::DEFERRED)) {
25592562
if (const Symbol *dtSymbol{dtScope.symbol()}) {
25602563
if (!dtSymbol->attrs().test(Attr::ABSTRACT)) { // C733
@@ -2568,6 +2571,11 @@ void CheckHelper::CheckProcBinding(
25682571
"Type-bound procedure '%s' may not be both DEFERRED and NON_OVERRIDABLE"_err_en_US,
25692572
symbol.name());
25702573
}
2574+
if (overridden && !overridden->attrs().test(Attr::DEFERRED)) {
2575+
SayWithDeclaration(*overridden,
2576+
"Override of non-DEFERRED '%s' must not be DEFERRED"_err_en_US,
2577+
symbol.name());
2578+
}
25712579
}
25722580
if (binding.symbol().attrs().test(Attr::INTRINSIC) &&
25732581
!context_.intrinsics().IsSpecificIntrinsicFunction(
@@ -2576,9 +2584,7 @@ void CheckHelper::CheckProcBinding(
25762584
"Intrinsic procedure '%s' is not a specific intrinsic permitted for use in the definition of binding '%s'"_err_en_US,
25772585
binding.symbol().name(), symbol.name());
25782586
}
2579-
bool isInaccessibleDeferred{false};
2580-
if (const Symbol *
2581-
overridden{FindOverriddenBinding(symbol, isInaccessibleDeferred)}) {
2587+
if (overridden) {
25822588
if (isInaccessibleDeferred) {
25832589
SayWithDeclaration(*overridden,
25842590
"Override of PRIVATE DEFERRED '%s' must appear in its module"_err_en_US,

flang/test/Semantics/bug138915.f90

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
! RUN: %python %S/test_errors.py %s %flang_fc1
2+
module m
3+
type base
4+
contains
5+
procedure, nopass :: tbp
6+
end type
7+
type, extends(base), abstract :: child
8+
contains
9+
!ERROR: Override of non-DEFERRED 'tbp' must not be DEFERRED
10+
procedure(tbp), deferred, nopass :: tbp
11+
end type
12+
contains
13+
subroutine tbp
14+
end
15+
end

0 commit comments

Comments
 (0)