[flang-commits] [flang] 212beb6 - [flang] When formatting integers for Gw.d/Gw.dEe output, only 'w' matters

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Tue Aug 29 09:39:21 PDT 2023


Author: Peter Klausler
Date: 2023-08-29T09:33:10-07:00
New Revision: 212beb66f8d30fd17db0608bd195e88b9565f7df

URL: https://github.com/llvm/llvm-project/commit/212beb66f8d30fd17db0608bd195e88b9565f7df
DIFF: https://github.com/llvm/llvm-project/commit/212beb66f8d30fd17db0608bd195e88b9565f7df.diff

LOG: [flang] When formatting integers for Gw.d/Gw.dEe output, only 'w' matters

Leading zeros should appear only for Iw.m output formatting.
Gw, Gw.d, and Gw.dEe output editing all map to Iw with no ".m"
(Fortran 202X 13.7.5.2.2).

Differential Revision: https://reviews.llvm.org/D159037

Added: 
    

Modified: 
    flang/runtime/edit-output.cpp
    flang/unittests/Runtime/NumericalFormatTest.cpp

Removed: 
    


################################################################################
diff  --git a/flang/runtime/edit-output.cpp b/flang/runtime/edit-output.cpp
index 1625d8948b32fc..be0bb07f08bfe7 100644
--- a/flang/runtime/edit-output.cpp
+++ b/flang/runtime/edit-output.cpp
@@ -154,7 +154,8 @@ bool EditIntegerOutput(IoStatementState &io, const DataEdit &edit,
   int digits = end - p;
   int leadingZeroes{0};
   int editWidth{edit.width.value_or(0)};
-  if (edit.digits && digits <= *edit.digits) { // Iw.m
+  if (edit.descriptor == 'I' && edit.digits && digits <= *edit.digits) {
+    // Only Iw.m can produce leading zeroes, not Gw.d (F'202X 13.7.5.2.2)
     if (*edit.digits == 0 && n == 0) {
       // Iw.0 with zero value: output field must be blank.  For I0.0
       // and a zero value, emit one blank character.

diff  --git a/flang/unittests/Runtime/NumericalFormatTest.cpp b/flang/unittests/Runtime/NumericalFormatTest.cpp
index 40191137fe189c..833b16be0fc3f4 100644
--- a/flang/unittests/Runtime/NumericalFormatTest.cpp
+++ b/flang/unittests/Runtime/NumericalFormatTest.cpp
@@ -57,6 +57,22 @@ static bool CompareFormatReal(const char *format, std::uint64_t xInt,
   return CompareFormatReal(format, x, expect, got);
 }
 
+static bool CompareFormatInteger(
+    const char *format, std::int64_t x, const char *expect, std::string &got) {
+  char buffer[800];
+  auto cookie{IONAME(BeginInternalFormattedOutput)(
+      buffer, sizeof buffer, format, std::strlen(format))};
+  EXPECT_TRUE(IONAME(OutputInteger64)(cookie, x));
+  auto status{IONAME(EndIoStatement)(cookie)};
+  EXPECT_EQ(status, 0);
+  got = std::string{buffer, sizeof buffer};
+  auto lastNonBlank{got.find_last_not_of(" ")};
+  if (lastNonBlank != std::string::npos) {
+    got.resize(lastNonBlank + 1);
+  }
+  return CompareFormattedStrings(expect, got);
+}
+
 struct IOApiTests : CrashHandlerFixture {};
 
 TEST(IOApiTests, HelloWorldOutputTest) {
@@ -693,6 +709,71 @@ TEST(IOApiTests, FormatDoubleValues) {
   }
 }
 
+TEST(IOApiTests, FormatIntegerValues) {
+  using IntTestCaseTy = std::tuple<const char *, std::int64_t, const char *>;
+  static const std::vector<IntTestCaseTy> intTestCases{
+      {"(I4)", 0, "   0"},
+      {"(I4)", 1, "   1"},
+      {"(I4)", 9999, "9999"},
+      {"(SP,I4)", 1, "  +1"},
+      {"(SP,I4)", 9999, "****"},
+      {"(SP,I4)", 999, "+999"},
+      {"(I4)", -1, "  -1"},
+      {"(I4)", -9999, "****"},
+      {"(I4)", -999, "-999"},
+      {"(I4.2)", 1, "  01"},
+      {"(I4.2)", -1, " -01"},
+      {"(I4.2)", 999, " 999"},
+      {"(I4.4)", 999, "0999"},
+      {"(I0)", 0, "0"},
+      {"(I0)", 1, "1"},
+      {"(I0)", 9999, "9999"},
+      {"(SP,I0)", 1, "+1"},
+      {"(SP,I0)", 9999, "+9999"},
+      {"(SP,I0)", 999, "+999"},
+      {"(I0)", -1, "-1"},
+      {"(I0)", -9999, "-9999"},
+      {"(I0)", -999, "-999"},
+      {"(I0.2)", 1, "01"},
+      {"(I0.2)", -1, "-01"},
+      {"(I0.2)", 999, "999"},
+      {"(I0.4)", 999, "0999"},
+      {"(G4)", 0, "   0"},
+      {"(G4)", 1, "   1"},
+      {"(G4)", 9999, "9999"},
+      {"(SP,G4)", 1, "  +1"},
+      {"(SP,G4)", 9999, "****"},
+      {"(SP,G4)", 999, "+999"},
+      {"(G4)", -1, "  -1"},
+      {"(G4)", -9999, "****"},
+      {"(G4)", -999, "-999"},
+      {"(G4.2)", 1, "   1"},
+      {"(G4.2)", -1, "  -1"},
+      {"(G4.2)", 999, " 999"},
+      {"(G4.4)", 999, " 999"},
+      {"(G0)", 0, "0"},
+      {"(G0)", 1, "1"},
+      {"(G0)", 9999, "9999"},
+      {"(SP,G0)", 1, "+1"},
+      {"(SP,G0)", 9999, "+9999"},
+      {"(SP,G0)", 999, "+999"},
+      {"(G0)", -1, "-1"},
+      {"(G0)", -9999, "-9999"},
+      {"(G0)", -999, "-999"},
+      {"(G0.2)", 1, "1"},
+      {"(G0.2)", -1, "-1"},
+      {"(G0.2)", 999, "999"},
+      {"(G0.4)", 999, "999"},
+  };
+
+  for (auto const &[fmt, value, expect] : intTestCases) {
+    std::string got;
+    ASSERT_TRUE(CompareFormatInteger(fmt, value, expect, got))
+        << "Failed to format " << fmt << ", expected '" << expect << "', got '"
+        << got << "'";
+  }
+}
+
 //------------------------------------------------------------------------------
 /// Tests for input formatting real values
 //------------------------------------------------------------------------------


        


More information about the flang-commits mailing list