diff --git a/flang/runtime/format-implementation.h b/flang/runtime/format-implementation.h --- a/flang/runtime/format-implementation.h +++ b/flang/runtime/format-implementation.h @@ -225,6 +225,7 @@ while (true) { std::optional repeat; bool unlimited{false}; + auto maybeReversionPoint{offset_}; CharType ch{GetNextChar(context)}; while (ch == ',' || ch == ':') { // Skip commas, and don't complain if they're missing; the format @@ -254,6 +255,7 @@ return 0; } stack_[height_].start = offset_ - 1; // the '(' + RUNTIME_CHECK(context, format_[stack_[height_].start] == '('); if (unlimited || height_ == 0) { stack_[height_].remaining = Iteration::unlimited; unlimitedLoopCheck = offset_ - 1; @@ -265,6 +267,12 @@ } else { stack_[height_].remaining = 0; } + if (height_ == 1) { + // Subtle point (F'2018 13.4 para 9): tha last parenthesized group + // at height 1 becomes the restart point after control reaches the + // end of the format, including its repeat count. + stack_[0].start = maybeReversionPoint - 1; + } ++height_; } else if (height_ == 0) { context.SignalError(IostatErrorInFormat, "FORMAT lacks initial '('"); @@ -276,14 +284,15 @@ } context.AdvanceRecord(); // implied / before rightmost ) } + auto restart{stack_[height_ - 1].start + 1}; if (stack_[height_ - 1].remaining == Iteration::unlimited) { - offset_ = stack_[height_ - 1].start + 1; + offset_ = restart; if (offset_ == unlimitedLoopCheck) { context.SignalError(IostatErrorInFormat, "Unlimited repetition in FORMAT lacks data edit descriptors"); } } else if (stack_[height_ - 1].remaining-- > 0) { - offset_ = stack_[height_ - 1].start + 1; + offset_ = restart; } else { --height_; } @@ -396,7 +405,7 @@ ++height_; } edit.repeat = 1; - if (height_ > 1) { + if (height_ > 1) { // Subtle: stack_[0].start doesn't necessarily point to '(' int start{stack_[height_ - 1].start}; if (format_[start] != '(') { if (stack_[height_ - 1].remaining > maxRepeat) {