Skip to content

Commit dccc026

Browse files
authored
[flang][runtime] Allow INQUIRE(IOLENGTH=) in the presence of defined I/O (llvm#144541)
When I/O list items include instances of derived types for which defined I/O procedures exist, ignore them. Fixes llvm#144363.
1 parent 83b462a commit dccc026

File tree

2 files changed

+40
-30
lines changed

2 files changed

+40
-30
lines changed

flang-rt/lib/runtime/descriptor-io.cpp

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -451,39 +451,42 @@ RT_API_ATTRS int DescriptorIoTicket<DIR>::Begin(WorkQueue &workQueue) {
451451
if (const typeInfo::DerivedType *type{
452452
addendum ? addendum->derivedType() : nullptr}) {
453453
// derived type unformatted I/O
454-
if (table_) {
455-
if (const auto *definedIo{table_->Find(*type,
456-
DIR == Direction::Input
457-
? common::DefinedIo::ReadUnformatted
458-
: common::DefinedIo::WriteUnformatted)}) {
459-
if (definedIo->subroutine) {
460-
typeInfo::SpecialBinding special{DIR == Direction::Input
461-
? typeInfo::SpecialBinding::Which::ReadUnformatted
462-
: typeInfo::SpecialBinding::Which::WriteUnformatted,
463-
definedIo->subroutine, definedIo->isDtvArgPolymorphic, false,
464-
false};
465-
if (DefinedUnformattedIo(io_, instance_, *type, special)) {
466-
anyIoTookPlace_ = true;
467-
return StatOk;
454+
if (DIR == Direction::Input || !io_.get_if<InquireIOLengthState>()) {
455+
if (table_) {
456+
if (const auto *definedIo{table_->Find(*type,
457+
DIR == Direction::Input
458+
? common::DefinedIo::ReadUnformatted
459+
: common::DefinedIo::WriteUnformatted)}) {
460+
if (definedIo->subroutine) {
461+
typeInfo::SpecialBinding special{DIR == Direction::Input
462+
? typeInfo::SpecialBinding::Which::ReadUnformatted
463+
: typeInfo::SpecialBinding::Which::WriteUnformatted,
464+
definedIo->subroutine, definedIo->isDtvArgPolymorphic, false,
465+
false};
466+
if (DefinedUnformattedIo(io_, instance_, *type, special)) {
467+
anyIoTookPlace_ = true;
468+
return StatOk;
469+
}
470+
} else {
471+
int status{workQueue.BeginDerivedIo<DIR>(
472+
io_, instance_, *type, table_, anyIoTookPlace_)};
473+
return status == StatContinue ? StatOk : status; // done here
468474
}
469-
} else {
470-
int status{workQueue.BeginDerivedIo<DIR>(
471-
io_, instance_, *type, table_, anyIoTookPlace_)};
472-
return status == StatContinue ? StatOk : status; // done here
473475
}
474476
}
475-
}
476-
if (const typeInfo::SpecialBinding *special{
477-
type->FindSpecialBinding(DIR == Direction::Input
478-
? typeInfo::SpecialBinding::Which::ReadUnformatted
479-
: typeInfo::SpecialBinding::Which::WriteUnformatted)}) {
480-
if (!table_ || !table_->ignoreNonTbpEntries || special->IsTypeBound()) {
481-
// defined derived type unformatted I/O
482-
if (DefinedUnformattedIo(io_, instance_, *type, *special)) {
483-
anyIoTookPlace_ = true;
484-
return StatOk;
485-
} else {
486-
return IostatEnd;
477+
if (const typeInfo::SpecialBinding *special{
478+
type->FindSpecialBinding(DIR == Direction::Input
479+
? typeInfo::SpecialBinding::Which::ReadUnformatted
480+
: typeInfo::SpecialBinding::Which::WriteUnformatted)}) {
481+
if (!table_ || !table_->ignoreNonTbpEntries ||
482+
special->IsTypeBound()) {
483+
// defined derived type unformatted I/O
484+
if (DefinedUnformattedIo(io_, instance_, *type, *special)) {
485+
anyIoTookPlace_ = true;
486+
return StatOk;
487+
} else {
488+
return IostatEnd;
489+
}
487490
}
488491
}
489492
}

flang/docs/Extensions.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,13 @@ print *, [(j,j=1,10)]
868868
the elements for each component before proceeding to the next component.
869869
A program using defined assignment might be able to detect the difference.
870870

871+
* The standard forbids instances of derived types with defined unformatted
872+
WRITE subroutines from appearing in the I/O list of an `INQUIRE(IOLENGTH=...)`
873+
statement. It then also says that these defined I/O procedures should be
874+
ignored for that statement. So we allow them to appear (like most
875+
compilers) and don't use any defined unformatted WRITE that might have been
876+
defined.
877+
871878
## De Facto Standard Features
872879

873880
* `EXTENDS_TYPE_OF()` returns `.TRUE.` if both of its arguments have the

0 commit comments

Comments
 (0)