[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 https://github.com/llvm/llvm-project/issues/154954.
This commit is contained in:
parent
673e3051b0
commit
2c58d192a2
@ -532,7 +532,7 @@ RT_API_ATTRS common::optional<DataEdit> FormatControl<CONTEXT>::GetNextDataEdit(
|
||||
ReportBadFormat(context, "Excessive DT'iotype' in FORMAT", start);
|
||||
return common::nullopt;
|
||||
}
|
||||
edit.ioType[edit.ioTypeChars++] = ch;
|
||||
context.ioType[edit.ioTypeChars++] = ch;
|
||||
if (ch == quote) {
|
||||
++offset_;
|
||||
}
|
||||
@ -556,7 +556,7 @@ RT_API_ATTRS common::optional<DataEdit> FormatControl<CONTEXT>::GetNextDataEdit(
|
||||
ReportBadFormat(context, "Excessive DT(v_list) in FORMAT", start);
|
||||
return common::nullopt;
|
||||
}
|
||||
edit.vList[edit.vListEntries++] = n;
|
||||
context.vList[edit.vListEntries++] = n;
|
||||
auto ch{static_cast<char>(GetNextChar(context))};
|
||||
if (ch != ',') {
|
||||
ok = ch == ')';
|
||||
|
||||
@ -86,12 +86,11 @@ struct DataEdit {
|
||||
// defined I/O data edit descriptor
|
||||
RT_OFFLOAD_VAR_GROUP_BEGIN
|
||||
static constexpr std::size_t maxIoTypeChars{32};
|
||||
static constexpr std::size_t maxVListEntries{4};
|
||||
static constexpr std::size_t maxVListEntries{16};
|
||||
RT_OFFLOAD_VAR_GROUP_END
|
||||
std::uint8_t ioTypeChars{0};
|
||||
std::uint8_t vListEntries{0};
|
||||
char ioType[maxIoTypeChars];
|
||||
int vList[maxVListEntries];
|
||||
};
|
||||
|
||||
// Generates a sequence of DataEdits from a FORMAT statement or
|
||||
|
||||
@ -61,8 +61,14 @@ using IoDirectionState = std::conditional_t<D == Direction::Input,
|
||||
InputStatementState, OutputStatementState>;
|
||||
|
||||
// Common state for all kinds of formatted I/O
|
||||
template <Direction D> class FormattedIoStatementState {};
|
||||
template <> class FormattedIoStatementState<Direction::Input> {
|
||||
struct DefinedIoArgs {
|
||||
char ioType[DataEdit::maxIoTypeChars]; // IOTYPE string
|
||||
int vList[DataEdit::maxVListEntries]; // V_LIST(:) values
|
||||
};
|
||||
template <Direction D>
|
||||
class FormattedIoStatementState : public DefinedIoArgs {};
|
||||
template <>
|
||||
class FormattedIoStatementState<Direction::Input> : public DefinedIoArgs {
|
||||
public:
|
||||
RT_API_ATTRS std::size_t GetEditDescriptorChars() const;
|
||||
RT_API_ATTRS void GotChar(int);
|
||||
|
||||
@ -64,10 +64,11 @@ static RT_API_ATTRS common::optional<bool> DefinedFormattedIo(
|
||||
: *io.GetNextDataEdit(1)};
|
||||
char ioType[2 + edit.maxIoTypeChars];
|
||||
auto ioTypeLen{std::size_t{2} /*"DT"*/ + edit.ioTypeChars};
|
||||
auto &definedIoArgs{*io.get_if<DefinedIoArgs>()};
|
||||
if (edit.descriptor == DataEdit::DefinedDerivedType) {
|
||||
ioType[0] = 'D';
|
||||
ioType[1] = 'T';
|
||||
runtime::memcpy(ioType + 2, edit.ioType, edit.ioTypeChars);
|
||||
runtime::memcpy(ioType + 2, definedIoArgs.ioType, edit.ioTypeChars);
|
||||
} else {
|
||||
runtime::strcpy(
|
||||
ioType, io.mutableModes().inNamelist ? "NAMELIST" : "LISTDIRECTED");
|
||||
@ -81,7 +82,7 @@ static RT_API_ATTRS common::optional<bool> DefinedFormattedIo(
|
||||
if (integer8) {
|
||||
// Convert v_list values to INTEGER(8)
|
||||
for (int j{0}; j < edit.vListEntries; ++j) {
|
||||
vList64[j] = edit.vList[j];
|
||||
vList64[j] = definedIoArgs.vList[j];
|
||||
}
|
||||
vListDesc.Establish(
|
||||
TypeCategory::Integer, sizeof(std::int64_t), nullptr, 1);
|
||||
@ -91,7 +92,7 @@ static RT_API_ATTRS common::optional<bool> DefinedFormattedIo(
|
||||
static_cast<SubscriptValue>(sizeof(std::int64_t)));
|
||||
} else {
|
||||
vListDesc.Establish(TypeCategory::Integer, sizeof(int), nullptr, 1);
|
||||
vListDesc.set_base_addr(edit.vList);
|
||||
vListDesc.set_base_addr(definedIoArgs.vList);
|
||||
vListDesc.GetDimension(0).SetBounds(1, edit.vListEntries);
|
||||
vListDesc.GetDimension(0).SetByteStride(
|
||||
static_cast<SubscriptValue>(sizeof(int)));
|
||||
|
||||
@ -22,7 +22,7 @@ using namespace std::literals::string_literals;
|
||||
using ResultsTy = std::vector<std::string>;
|
||||
|
||||
// A test harness context for testing FormatControl
|
||||
class TestFormatContext : public IoErrorHandler {
|
||||
class TestFormatContext : public IoErrorHandler, public DefinedIoArgs {
|
||||
public:
|
||||
using CharType = char;
|
||||
TestFormatContext() : IoErrorHandler{"format.cpp", 1} {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user