[flang] Extension: allow char string edit descriptors in input formats (#140624)

FORMAT("J=",I3) is accepted by a few other Fortran compilers as a valid
format for input as well as for output. The character string edit
descriptor "J=" is interpreted as if it had been 2X on input, causing
two characters to be skipped over. The skipped characters don't have to
match the characters in the literal string. An optional warning is
emitted under control of the -pedantic option.
This commit is contained in:
Peter Klausler
2025-05-28 13:58:22 -07:00
committed by GitHub
parent b574c811e8
commit 4c6b60a639
5 changed files with 23 additions and 9 deletions

View File

@@ -427,7 +427,11 @@ RT_API_ATTRS int FormatControl<CONTEXT>::CueUpNextDataEdit(
} else {
--chars;
}
if constexpr (std::is_base_of_v<InputStatementState, CONTEXT>) {
context.HandleRelativePosition(chars);
} else {
EmitAscii(context, format_ + start, chars);
}
} else if (ch == 'H') {
// 9HHOLLERITH
if (!repeat || *repeat < 1 || offset_ + *repeat > formatLength_) {
@@ -435,7 +439,12 @@ RT_API_ATTRS int FormatControl<CONTEXT>::CueUpNextDataEdit(
maybeReversionPoint);
return 0;
}
EmitAscii(context, format_ + offset_, static_cast<std::size_t>(*repeat));
if constexpr (std::is_base_of_v<InputStatementState, CONTEXT>) {
context.HandleRelativePosition(static_cast<std::size_t>(*repeat));
} else {
EmitAscii(
context, format_ + offset_, static_cast<std::size_t>(*repeat));
}
offset_ += *repeat;
} else if (ch >= 'A' && ch <= 'Z') {
int start{offset_ - 1};

View File

@@ -882,6 +882,7 @@ TEST(IOApiTests, EditDoubleInputValues) {
{"(F18.1)", " 125", 0x4029000000000000, 0},
{"(F18.2)", " 125", 0x3ff4000000000000, 0},
{"(F18.3)", " 125", 0x3fc0000000000000, 0},
{"('str',F3.0)", "xxx125", 0x405f400000000000, 0},
{"(-1P,F18.0)", " 125", 0x4093880000000000, 0}, // 1250
{"(1P,F18.0)", " 125", 0x4029000000000000, 0}, // 12.5
{"(BZ,F18.0)", " 125 ", 0x4093880000000000, 0}, // 1250

View File

@@ -424,6 +424,10 @@ end
* A zero field width is allowed for logical formatted output (`L0`).
* `OPEN(..., FORM='BINARY')` is accepted as a legacy synonym for
the standard `OPEN(..., FORM='UNFORMATTED', ACCESS='STREAM')`.
* A character string edit descriptor is allowed in an input format
with an optional compilation-time warning. When executed, it
is treated as an 'nX' positioning control descriptor that skips
over the same number of characters, without comparison.
### Extensions supported when enabled by options

View File

@@ -430,11 +430,11 @@ template <typename CHAR> void FormatValidator<CHAR>::NextToken() {
}
}
SetLength();
if (stmt_ == IoStmtKind::Read &&
previousToken_.kind() != TokenKind::DT) { // 13.3.2p6
ReportError("String edit descriptor in READ format expression");
} else if (token_.kind() != TokenKind::String) {
if (token_.kind() != TokenKind::String) {
ReportError("Unterminated string");
} else if (stmt_ == IoStmtKind::Read &&
previousToken_.kind() != TokenKind::DT) { // 13.3.2p6
ReportWarning("String edit descriptor in READ format expression");
}
break;
default:

View File

@@ -1,8 +1,8 @@
! RUN: %python %S/test_errors.py %s %flang_fc1
!ERROR: String edit descriptor in READ format expression
! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
!WARNING: String edit descriptor in READ format expression
read(*,'("abc")')
!ERROR: String edit descriptor in READ format expression
!ERROR: Unterminated string
!ERROR: Unterminated format expression
read(*,'("abc)')