Skip to content

Commit 2c58d19

Browse files
authored
[flang][runtime] Expand IOTYPE and V_LIST (#160744)
The IOTYPE and V_LIST dummy arguments to a defined formatted I/O subroutine are extracted from a DT edit descriptor in a FORMAT. They are currently stored in the DataEdit structure, and their maximum sizes are rather small since DataEdits are sometimes returned or passed by value. This patch moves their storage into the FormattedIoStatementState structure and enlarges them a bit. Fixes #154954.
1 parent 673e305 commit 2c58d19

File tree

5 files changed

+16
-10
lines changed

5 files changed

+16
-10
lines changed

flang-rt/include/flang-rt/runtime/format-implementation.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ RT_API_ATTRS common::optional<DataEdit> FormatControl<CONTEXT>::GetNextDataEdit(
532532
ReportBadFormat(context, "Excessive DT'iotype' in FORMAT", start);
533533
return common::nullopt;
534534
}
535-
edit.ioType[edit.ioTypeChars++] = ch;
535+
context.ioType[edit.ioTypeChars++] = ch;
536536
if (ch == quote) {
537537
++offset_;
538538
}
@@ -556,7 +556,7 @@ RT_API_ATTRS common::optional<DataEdit> FormatControl<CONTEXT>::GetNextDataEdit(
556556
ReportBadFormat(context, "Excessive DT(v_list) in FORMAT", start);
557557
return common::nullopt;
558558
}
559-
edit.vList[edit.vListEntries++] = n;
559+
context.vList[edit.vListEntries++] = n;
560560
auto ch{static_cast<char>(GetNextChar(context))};
561561
if (ch != ',') {
562562
ok = ch == ')';

flang-rt/include/flang-rt/runtime/format.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,11 @@ struct DataEdit {
8686
// defined I/O data edit descriptor
8787
RT_OFFLOAD_VAR_GROUP_BEGIN
8888
static constexpr std::size_t maxIoTypeChars{32};
89-
static constexpr std::size_t maxVListEntries{4};
89+
static constexpr std::size_t maxVListEntries{16};
9090
RT_OFFLOAD_VAR_GROUP_END
9191
std::uint8_t ioTypeChars{0};
9292
std::uint8_t vListEntries{0};
9393
char ioType[maxIoTypeChars];
94-
int vList[maxVListEntries];
9594
};
9695

9796
// Generates a sequence of DataEdits from a FORMAT statement or

flang-rt/include/flang-rt/runtime/io-stmt.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,14 @@ using IoDirectionState = std::conditional_t<D == Direction::Input,
6161
InputStatementState, OutputStatementState>;
6262

6363
// Common state for all kinds of formatted I/O
64-
template <Direction D> class FormattedIoStatementState {};
65-
template <> class FormattedIoStatementState<Direction::Input> {
64+
struct DefinedIoArgs {
65+
char ioType[DataEdit::maxIoTypeChars]; // IOTYPE string
66+
int vList[DataEdit::maxVListEntries]; // V_LIST(:) values
67+
};
68+
template <Direction D>
69+
class FormattedIoStatementState : public DefinedIoArgs {};
70+
template <>
71+
class FormattedIoStatementState<Direction::Input> : public DefinedIoArgs {
6672
public:
6773
RT_API_ATTRS std::size_t GetEditDescriptorChars() const;
6874
RT_API_ATTRS void GotChar(int);

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,11 @@ static RT_API_ATTRS common::optional<bool> DefinedFormattedIo(
6464
: *io.GetNextDataEdit(1)};
6565
char ioType[2 + edit.maxIoTypeChars];
6666
auto ioTypeLen{std::size_t{2} /*"DT"*/ + edit.ioTypeChars};
67+
auto &definedIoArgs{*io.get_if<DefinedIoArgs>()};
6768
if (edit.descriptor == DataEdit::DefinedDerivedType) {
6869
ioType[0] = 'D';
6970
ioType[1] = 'T';
70-
runtime::memcpy(ioType + 2, edit.ioType, edit.ioTypeChars);
71+
runtime::memcpy(ioType + 2, definedIoArgs.ioType, edit.ioTypeChars);
7172
} else {
7273
runtime::strcpy(
7374
ioType, io.mutableModes().inNamelist ? "NAMELIST" : "LISTDIRECTED");
@@ -81,7 +82,7 @@ static RT_API_ATTRS common::optional<bool> DefinedFormattedIo(
8182
if (integer8) {
8283
// Convert v_list values to INTEGER(8)
8384
for (int j{0}; j < edit.vListEntries; ++j) {
84-
vList64[j] = edit.vList[j];
85+
vList64[j] = definedIoArgs.vList[j];
8586
}
8687
vListDesc.Establish(
8788
TypeCategory::Integer, sizeof(std::int64_t), nullptr, 1);
@@ -91,7 +92,7 @@ static RT_API_ATTRS common::optional<bool> DefinedFormattedIo(
9192
static_cast<SubscriptValue>(sizeof(std::int64_t)));
9293
} else {
9394
vListDesc.Establish(TypeCategory::Integer, sizeof(int), nullptr, 1);
94-
vListDesc.set_base_addr(edit.vList);
95+
vListDesc.set_base_addr(definedIoArgs.vList);
9596
vListDesc.GetDimension(0).SetBounds(1, edit.vListEntries);
9697
vListDesc.GetDimension(0).SetByteStride(
9798
static_cast<SubscriptValue>(sizeof(int)));

flang-rt/unittests/Runtime/Format.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ using namespace std::literals::string_literals;
2222
using ResultsTy = std::vector<std::string>;
2323

2424
// A test harness context for testing FormatControl
25-
class TestFormatContext : public IoErrorHandler {
25+
class TestFormatContext : public IoErrorHandler, public DefinedIoArgs {
2626
public:
2727
using CharType = char;
2828
TestFormatContext() : IoErrorHandler{"format.cpp", 1} {}

0 commit comments

Comments
 (0)