[flang-commits] [flang] da63fee - [flang][runtime] Allow extra character for E0.0 output editing

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Fri Jun 3 17:41:36 PDT 2022


Author: Peter Klausler
Date: 2022-06-03T17:41:22-07:00
New Revision: da63fee0d091c43d4186888620bf8d5968e95228

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

LOG: [flang][runtime] Allow extra character for E0.0 output editing

When the digit count ('d') is zero in E0 editing, allow for one more
output character; otherwise, any - or + sign in the output causes
an output field overflow.

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

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 fd9b70f753d88..f76be339cc7b6 100644
--- a/flang/runtime/edit-output.cpp
+++ b/flang/runtime/edit-output.cpp
@@ -260,7 +260,11 @@ bool RealOutputEditing<binaryPrecision>::EditEorDOutput(const DataEdit &edit) {
   }
   if (editWidth == 0) { // "the processor selects the field width"
     if (edit.digits.has_value()) { // E0.d
-      editWidth = editDigits + 6; // -.666E+ee
+      if (editDigits == 0) { // E0.0
+        editWidth = 7; // -.0E+ee
+      } else {
+        editWidth = editDigits + 6; // -.666E+ee
+      }
     } else { // E0
       flags |= decimal::Minimize;
       significantDigits =

diff  --git a/flang/unittests/Runtime/NumericalFormatTest.cpp b/flang/unittests/Runtime/NumericalFormatTest.cpp
index a0c9680977413..0c8f7a0aad3ba 100644
--- a/flang/unittests/Runtime/NumericalFormatTest.cpp
+++ b/flang/unittests/Runtime/NumericalFormatTest.cpp
@@ -19,7 +19,7 @@ using namespace Fortran::runtime;
 using namespace Fortran::runtime::io;
 
 static bool CompareFormattedStrings(
-    const std::string &expect, const std::string &&got) {
+    const std::string &expect, const std::string &got) {
   std::string want{expect};
   want.resize(got.size(), ' ');
   return want == got;
@@ -32,24 +32,29 @@ static bool CompareFormattedStrings(
 
 // Perform format and compare the result with expected value
 static bool CompareFormatReal(
-    const char *format, double x, const char *expect) {
+    const char *format, double x, const char *expect, std::string &got) {
   char buffer[800];
   auto cookie{IONAME(BeginInternalFormattedOutput)(
       buffer, sizeof buffer, format, std::strlen(format))};
   EXPECT_TRUE(IONAME(OutputReal64)(cookie, x));
   auto status{IONAME(EndIoStatement)(cookie)};
   EXPECT_EQ(status, 0);
-  return CompareFormattedStrings(expect, std::string{buffer, sizeof buffer});
+  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);
 }
 
 // Convert raw uint64 into double, perform format, and compare with expected
-static bool CompareFormatReal(
-    const char *format, std::uint64_t xInt, const char *expect) {
+static bool CompareFormatReal(const char *format, std::uint64_t xInt,
+    const char *expect, std::string &got) {
   double x;
   static_assert(sizeof(double) == sizeof(std::uint64_t),
       "Size of double != size of uint64_t!");
   std::memcpy(&x, &xInt, sizeof xInt);
-  return CompareFormatReal(format, x, expect);
+  return CompareFormatReal(format, x, expect, got);
 }
 
 struct IOApiTests : CrashHandlerFixture {};
@@ -273,8 +278,10 @@ TEST(IOApiTests, FormatZeroes) {
   };
 
   for (auto const &[format, expect] : zeroes) {
-    ASSERT_TRUE(CompareFormatReal(format, 0.0, expect))
-        << "Failed to format " << format << ", expected " << expect;
+    std::string got;
+    ASSERT_TRUE(CompareFormatReal(format, 0.0, expect, got))
+        << "Failed to format " << format << ", expected " << expect << ", got "
+        << got;
   }
 }
 
@@ -302,8 +309,10 @@ TEST(IOApiTests, FormatOnes) {
   };
 
   for (auto const &[format, expect] : ones) {
-    ASSERT_TRUE(CompareFormatReal(format, 1.0, expect))
-        << "Failed to format " << format << ", expected " << expect;
+    std::string got;
+    ASSERT_TRUE(CompareFormatReal(format, 1.0, expect, got))
+        << "Failed to format " << format << ", expected " << expect << ", got "
+        << got;
   }
 }
 
@@ -315,8 +324,10 @@ TEST(IOApiTests, FormatNegativeOnes) {
       {"(G0,';')", "-1.;"},
   };
   for (auto const &[format, expect] : negOnes) {
-    ASSERT_TRUE(CompareFormatReal(format, -1.0, expect))
-        << "Failed to format " << format << ", expected " << expect;
+    std::string got;
+    ASSERT_TRUE(CompareFormatReal(format, -1.0, expect, got))
+        << "Failed to format " << format << ", expected " << expect << ", got "
+        << got;
   }
 }
 
@@ -383,7 +394,7 @@ TEST(IOApiTests, FormatDoubleValues) {
               {"(E62.55,';')",
                   " 0.1000000000000000055511151231257827021181583404541015625E+"
                   "00;"},
-              {"(E0.0,';')", "0.E+00;"},
+              {"(E0.0,';')", " 0.E+00;"},
               {"(E0.55,';')",
                   "0.1000000000000000055511151231257827021181583404541015625E+"
                   "00;"},
@@ -611,8 +622,10 @@ TEST(IOApiTests, FormatDoubleValues) {
 
   for (auto const &[value, cases] : testCases) {
     for (auto const &[format, expect] : cases) {
-      ASSERT_TRUE(CompareFormatReal(format, value, expect))
-          << "Failed to format " << format << ", expected " << expect;
+      std::string got;
+      ASSERT_TRUE(CompareFormatReal(format, value, expect, got))
+          << "Failed to format " << format << ", expected " << expect
+          << ", got " << got;
     }
   }
 
@@ -654,8 +667,10 @@ TEST(IOApiTests, FormatDoubleValues) {
   };
 
   for (auto const &[format, value, expect] : individualTestCases) {
-    ASSERT_TRUE(CompareFormatReal(format, value, expect))
-        << "Failed to format " << format << ", expected " << expect;
+    std::string got;
+    ASSERT_TRUE(CompareFormatReal(format, value, expect, got))
+        << "Failed to format " << format << ", expected " << expect << ", got "
+        << got;
   }
 }
 


        


More information about the flang-commits mailing list