Skip to content

Commit ec4ba0f

Browse files
authored
[flang][runtime] Correct automatic parenthesized format repetition case (#71436)
In Fortran, a format automatically repeats, with a line break, until all the data items of a data transfer statement have been consumed. PRINT "(3I4)", 1, 2, 3, 4, 5, 6 prints two lines, for example, three values each. When there are nested parentheses in a format, the rightmost set of parentheses at the top level are used for automatic repetition. PRINT "(I4,2(I4))" 1, 2, 3, 4, 5, 6, 7 print three lines, with three values on the first and two each on the later ones. Fix a bug in format interpretation that causes the detection of the "rightmost" set of parentheses to take place on each pass, leading to problems when parentheses are even further nested.
1 parent 9652e9b commit ec4ba0f

File tree

3 files changed

+8
-2
lines changed

3 files changed

+8
-2
lines changed

flang/runtime/format-implementation.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,8 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
284284
} else {
285285
stack_[height_].remaining = 0;
286286
}
287-
if (height_ == 1) {
288-
// Subtle point (F'2018 13.4 para 9): tha last parenthesized group
287+
if (height_ == 1 && !hitEnd_) {
288+
// Subtle point (F'2018 13.4 para 9): the last parenthesized group
289289
// at height 1 becomes the restart point after control reaches the
290290
// end of the format, including its repeat count.
291291
stack_[0].start = maybeReversionPoint;
@@ -300,6 +300,7 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
300300
return 0; // end of FORMAT and no data items remain
301301
}
302302
context.AdvanceRecord(); // implied / before rightmost )
303+
hitEnd_ = true;
303304
}
304305
auto restart{stack_[height_ - 1].start};
305306
if (format_[restart] == '(') {

flang/runtime/format.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ template <typename CONTEXT> class FormatControl {
184184
const std::uint8_t maxHeight_{maxMaxHeight};
185185
std::uint8_t height_{0};
186186
bool freeFormat_{false};
187+
bool hitEnd_{false};
187188
const CharType *format_{nullptr};
188189
int formatLength_{0}; // in units of characters
189190
int offset_{0}; // next item is at format_[offset_]

flang/unittests/Runtime/Format.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ TEST(FormatTests, FormatStringTraversal) {
107107
ResultsTy{"'PI='", "F9.7", "'PI='", "F9.7"}, 1},
108108
{2, "(*('PI=',F9.7,:))", ResultsTy{"'PI='", "F9.7", "'PI='", "F9.7"}, 1},
109109
{1, "(3F9.7)", ResultsTy{"2*F9.7"}, 2},
110+
{9, "((I4,2(E10.1)))",
111+
ResultsTy{"I4", "E10.1", "E10.1", "/", "I4", "E10.1", "E10.1", "/",
112+
"I4", "E10.1", "E10.1"},
113+
1},
110114
};
111115

112116
for (const auto &[n, format, expect, repeat] : params) {

0 commit comments

Comments
 (0)