Skip to content
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

[flang][runtime] Correct automatic parenthesized format repetition case #71436

Merged
merged 1 commit into from
Nov 13, 2023

Conversation

klausler
Copy link
Contributor

@klausler klausler commented Nov 6, 2023

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.

@klausler klausler changed the title [flang][runtime] Correct automaticparenthesized format repetition case [flang][runtime] Correct automatic parenthesized format repetition case Nov 6, 2023
@llvmbot llvmbot added flang:runtime flang Flang issues not falling into any other category labels Nov 6, 2023
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.
@llvmbot
Copy link
Collaborator

llvmbot commented Nov 6, 2023

@llvm/pr-subscribers-flang-runtime

Author: Peter Klausler (klausler)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/71436.diff

3 Files Affected:

  • (modified) flang/runtime/format-implementation.h (+3-2)
  • (modified) flang/runtime/format.h (+1)
  • (modified) flang/unittests/Runtime/Format.cpp (+4)
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) {

@klausler klausler merged commit ec4ba0f into llvm:main Nov 13, 2023
3 checks passed
@klausler klausler deleted the bug71343 branch November 13, 2023 22:52
zahiraam pushed a commit to zahiraam/llvm-project that referenced this pull request Nov 20, 2023
…se (llvm#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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:runtime flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants