Skip to content

Commit 4b23d4c

Browse files
authored
[flang] Extension: allow override of inaccessible DEFERRED binding (#142691)
Inaccessible procedure bindings can't be overridden, but DEFERRED bindings must be in a non-abstract extension. We presently emit an error for an attempt to override an inaccessible binding in this case. But some compilers accept this usage, and since it seems safe enough, I'll allow it with an optional warning. Codes can avoid this warning and conform to the standard by changing the deferred bindings to be public.
1 parent 43abd25 commit 4b23d4c

File tree

6 files changed

+23
-9
lines changed

6 files changed

+23
-9
lines changed

flang/docs/Extensions.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ end
164164
No other Fortran compiler enforces C7108 (to our knowledge);
165165
they all resolve the ambiguity by interpreting the call as a function
166166
reference. We do the same, with a portability warning.
167+
* An override for an inaccessible procedure binding works only within
168+
the same module; other apparent overrides of inaccessible bindings
169+
are actually new bindings of the same name.
170+
In the case of `DEFERRED` bindings in an `ABSTRACT` derived type,
171+
however, overrides are necessary, so they are permitted for inaccessible
172+
bindings with an optional warning.
167173

168174
## Extensions, deletions, and legacy features supported by default
169175

flang/include/flang/Support/Fortran-features.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
5555
UndefinableAsynchronousOrVolatileActual, AutomaticInMainProgram, PrintCptr,
5656
SavedLocalInSpecExpr, PrintNamelist, AssumedRankPassedToNonAssumedRank,
5757
IgnoreIrrelevantAttributes, Unsigned, AmbiguousStructureConstructor,
58-
ContiguousOkForSeqAssociation, ForwardRefExplicitTypeDummy)
58+
ContiguousOkForSeqAssociation, ForwardRefExplicitTypeDummy,
59+
InaccessibleDeferredOverride)
5960

6061
// Portability and suspicious usage warnings
6162
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,

flang/lib/Evaluate/tools.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1206,7 +1206,8 @@ parser::Message *AttachDeclaration(
12061206
}
12071207
if (const auto *binding{
12081208
unhosted->detailsIf<semantics::ProcBindingDetails>()}) {
1209-
if (binding->symbol().name() != symbol.name()) {
1209+
if (!symbol.attrs().test(semantics::Attr::DEFERRED) &&
1210+
binding->symbol().name() != symbol.name()) {
12101211
message.Attach(binding->symbol().name(),
12111212
"Procedure '%s' of type '%s' is bound to '%s'"_en_US, symbol.name(),
12121213
symbol.owner().GetName().value(), binding->symbol().name());

flang/lib/Semantics/check-declarations.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2586,9 +2586,12 @@ void CheckHelper::CheckProcBinding(
25862586
}
25872587
if (overridden) {
25882588
if (isInaccessibleDeferred) {
2589-
SayWithDeclaration(*overridden,
2590-
"Override of PRIVATE DEFERRED '%s' must appear in its module"_err_en_US,
2591-
symbol.name());
2589+
evaluate::AttachDeclaration(
2590+
Warn(common::LanguageFeature::InaccessibleDeferredOverride,
2591+
symbol.name(),
2592+
"Override of PRIVATE DEFERRED '%s' should appear in its module"_warn_en_US,
2593+
symbol.name()),
2594+
*overridden);
25922595
}
25932596
if (overridden->attrs().test(Attr::NON_OVERRIDABLE)) {
25942597
SayWithDeclaration(*overridden,

flang/lib/Semantics/runtime-type-info.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1018,9 +1018,11 @@ SymbolVector CollectBindings(const Scope &dtScope) {
10181018
if (overriderIter != localBindings.end()) {
10191019
Symbol &overrider{*overriderIter->second};
10201020
if (symbol.attrs().test(Attr::PRIVATE) &&
1021+
!symbol.attrs().test(Attr::DEFERRED) &&
10211022
FindModuleContaining(symbol.owner()) !=
10221023
FindModuleContaining(dtScope)) {
1023-
// Don't override inaccessible PRIVATE bindings
1024+
// Don't override inaccessible PRIVATE bindings, unless
1025+
// they are deferred
10241026
auto &binding{overrider.get<ProcBindingDetails>()};
10251027
binding.set_numPrivatesNotOverridden(
10261028
binding.numPrivatesNotOverridden() + 1);

flang/test/Semantics/deferred01.f90

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
! RUN: %python %S/test_errors.py %s %flang_fc1
1+
! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic -Werror
22
! Deferred TBPs must be overridden, but when they are private, those
3-
! overrides must appear in the same module.
3+
! overrides are required to appear in the same module. We allow overrides
4+
! elsewhere as an extension.
45
module m1
56
type, abstract :: absBase
67
contains
@@ -18,7 +19,7 @@ module m2
1819
use m1
1920
type, extends(absBase) :: ext
2021
contains
21-
!ERROR: Override of PRIVATE DEFERRED 'deferredtbp' must appear in its module
22+
!WARNING: Override of PRIVATE DEFERRED 'deferredtbp' should appear in its module
2223
procedure :: deferredTbp => implTbp
2324
end type
2425
contains

0 commit comments

Comments
 (0)