[flang-commits] [flang] ec4ba0f - [flang][runtime] Correct automatic parenthesized format repetition case (#71436)
via flang-commits
flang-commits at lists.llvm.org
Mon Nov 13 14:52:56 PST 2023
Author: Peter Klausler
Date: 2023-11-13T14:52:51-08:00
New Revision: ec4ba0f5fe83c0e90ae6a56ffd417a4603e71501
URL: https://github.com/llvm/llvm-project/commit/ec4ba0f5fe83c0e90ae6a56ffd417a4603e71501
DIFF: https://github.com/llvm/llvm-project/commit/ec4ba0f5fe83c0e90ae6a56ffd417a4603e71501.diff
LOG: [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.
Added:
Modified:
flang/runtime/format-implementation.h
flang/runtime/format.h
flang/unittests/Runtime/Format.cpp
Removed:
################################################################################
diff --git a/flang/runtime/format-implementation.h b/flang/runtime/format-implementation.h
index 0daacc6bcccbb5f..57c176ea8d77cac 100644
--- a/flang/runtime/format-implementation.h
+++ b/flang/runtime/format-implementation.h
@@ -284,8 +284,8 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
} else {
stack_[height_].remaining = 0;
}
- if (height_ == 1) {
- // Subtle point (F'2018 13.4 para 9): tha last parenthesized group
+ if (height_ == 1 && !hitEnd_) {
+ // Subtle point (F'2018 13.4 para 9): the 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;
@@ -300,6 +300,7 @@ int FormatControl<CONTEXT>::CueUpNextDataEdit(Context &context, bool stop) {
return 0; // end of FORMAT and no data items remain
}
context.AdvanceRecord(); // implied / before rightmost )
+ hitEnd_ = true;
}
auto restart{stack_[height_ - 1].start};
if (format_[restart] == '(') {
diff --git a/flang/runtime/format.h b/flang/runtime/format.h
index b9f8f73a48dec7a..989006ecd85cab0 100644
--- a/flang/runtime/format.h
+++ b/flang/runtime/format.h
@@ -184,6 +184,7 @@ template <typename CONTEXT> class FormatControl {
const std::uint8_t maxHeight_{maxMaxHeight};
std::uint8_t height_{0};
bool freeFormat_{false};
+ bool hitEnd_{false};
const CharType *format_{nullptr};
int formatLength_{0}; // in units of characters
int offset_{0}; // next item is at format_[offset_]
diff --git a/flang/unittests/Runtime/Format.cpp b/flang/unittests/Runtime/Format.cpp
index 1f55b39d5905331..e9004b7798f3613 100644
--- a/flang/unittests/Runtime/Format.cpp
+++ b/flang/unittests/Runtime/Format.cpp
@@ -107,6 +107,10 @@ TEST(FormatTests, FormatStringTraversal) {
ResultsTy{"'PI='", "F9.7", "'PI='", "F9.7"}, 1},
{2, "(*('PI=',F9.7,:))", ResultsTy{"'PI='", "F9.7", "'PI='", "F9.7"}, 1},
{1, "(3F9.7)", ResultsTy{"2*F9.7"}, 2},
+ {9, "((I4,2(E10.1)))",
+ ResultsTy{"I4", "E10.1", "E10.1", "/", "I4", "E10.1", "E10.1", "/",
+ "I4", "E10.1", "E10.1"},
+ 1},
};
for (const auto &[n, format, expect, repeat] : params) {
More information about the flang-commits
mailing list