Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions flang-rt/include/flang-rt/runtime/format-implementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,15 +427,24 @@ RT_API_ATTRS int FormatControl<CONTEXT>::CueUpNextDataEdit(
} else {
--chars;
}
EmitAscii(context, format_ + start, 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_) {
ReportBadFormat(context, "Invalid width on Hollerith in FORMAT",
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};
Expand Down
1 change: 1 addition & 0 deletions flang-rt/unittests/Runtime/NumericalFormatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions flang/docs/Extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
8 changes: 4 additions & 4 deletions flang/include/flang/Common/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 3 additions & 3 deletions flang/test/Semantics/io09.f90
Original file line number Diff line number Diff line change
@@ -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)')

Expand Down