[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