Skip to content

Commit 51f521b

Browse files
committed
[flang][runtime] Disable namelist storage sequence input when defined
The runtime supports a near-universal extension to namelist input that allows reading a sequence of values into a storage sequence beginning at an array element, e.g. &NML A(2)=1. 2. 3. / . Disable this extension when the type of the array has a defined formatted READ subroutine defined. That defined input procedure may itself not be using list-directed input, and might not notice a following slash or new input item name as such. Fixes #158496.
1 parent 8ae3aea commit 51f521b

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

flang-rt/lib/runtime/namelist.cpp

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,40 @@ static RT_API_ATTRS bool HandleSubscripts(IoStatementState &io,
258258
return false;
259259
}
260260

261-
static RT_API_ATTRS void StorageSequenceExtension(
262-
Descriptor &desc, const Descriptor &source) {
261+
static RT_API_ATTRS bool HasDefinedIoSubroutine(common::DefinedIo definedIo,
262+
typeInfo::SpecialBinding::Which specialBinding,
263+
const typeInfo::DerivedType *derivedType,
264+
const NonTbpDefinedIoTable *table) {
265+
for (; derivedType; derivedType = derivedType->GetParentType()) {
266+
if ((table && table->Find(*derivedType, definedIo) != nullptr) ||
267+
derivedType->FindSpecialBinding(specialBinding)) {
268+
return true;
269+
}
270+
}
271+
return false;
272+
}
273+
274+
static RT_API_ATTRS bool HasDefinedIoSubroutine(common::DefinedIo definedIo,
275+
typeInfo::SpecialBinding::Which specialBinding,
276+
const Descriptor &descriptor, const NonTbpDefinedIoTable *table) {
277+
const DescriptorAddendum *addendum{descriptor.Addendum()};
278+
return addendum &&
279+
HasDefinedIoSubroutine(
280+
definedIo, specialBinding, addendum->derivedType(), table);
281+
}
282+
283+
static RT_API_ATTRS void StorageSequenceExtension(Descriptor &desc,
284+
const Descriptor &source, const io::NonTbpDefinedIoTable *table) {
263285
// Support the near-universal extension of NAMELIST input into a
264286
// designatable storage sequence identified by its initial scalar array
265287
// element. For example, treat "A(1) = 1. 2. 3." as if it had been
266288
// "A(1:) = 1. 2. 3.".
267-
if (desc.rank() == 0 && (source.rank() == 1 || source.IsContiguous())) {
289+
// (But don't do this for derived types with defined formatted READs,
290+
// since they might do non-list-directed input that won't stop at the
291+
// next namelist input item name.)
292+
if (desc.rank() == 0 && (source.rank() == 1 || source.IsContiguous()) &&
293+
!HasDefinedIoSubroutine(common::DefinedIo::ReadFormatted,
294+
typeInfo::SpecialBinding::Which::ReadFormatted, desc, table)) {
268295
if (auto stride{source.rank() == 1
269296
? source.GetDimension(0).ByteStride()
270297
: static_cast<SubscriptValue>(source.ElementBytes())};
@@ -561,7 +588,8 @@ bool IODEF(InputNamelist)(Cookie cookie, const NamelistGroup &group) {
561588
next = io.GetCurrentChar(byteCount);
562589
} while (next && (*next == '(' || *next == '%'));
563590
if (lastSubscriptDescriptor) {
564-
StorageSequenceExtension(*lastSubscriptDescriptor, *lastSubscriptBase);
591+
StorageSequenceExtension(*lastSubscriptDescriptor, *lastSubscriptBase,
592+
group.nonTbpDefinedIo);
565593
}
566594
}
567595
// Skip the '='

flang/docs/Extensions.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,3 +930,6 @@ print *, [(j,j=1,10)]
930930
or contiguous array can be used as the initial element of a storage
931931
sequence. For example, "&GRP A(1)=1. 2. 3./" is treated as if had been
932932
"&GRP A(1:)=1. 2. 3./".
933+
This extension is necessarily disabled when the type of the array
934+
has an accessible defined formatted READ subroutine.
935+

0 commit comments

Comments
 (0)