[flang-commits] [flang] 033b491 - [flang][runtime] Catch error on Ew.0 output editing (#78522)

via flang-commits flang-commits at lists.llvm.org
Thu Jan 25 14:33:13 PST 2024


Author: Peter Klausler
Date: 2024-01-25T14:33:08-08:00
New Revision: 033b491c756f58bceaa26f1c96ec645c8d3e5e45

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

LOG: [flang][runtime] Catch error on Ew.0 output editing (#78522)

An Ew.0(Ee) or Ew.0(Ee) output edit descriptor with a scale factor of
zero is an error condition, unless the output edit descriptor was
originally Gw.0(Ee), list-directed, or just E0/D0 with no .d part.

Fixes https://github.com/llvm/llvm-project/issues/78390.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/flang/runtime/edit-output.cpp b/flang/runtime/edit-output.cpp
index 26e066c85fed39..b474c8cd91bae4 100644
--- a/flang/runtime/edit-output.cpp
+++ b/flang/runtime/edit-output.cpp
@@ -334,6 +334,11 @@ bool RealOutputEditing<KIND>::EditEorDOutput(const DataEdit &edit) {
     }
     ++significantDigits;
     scale = std::min(scale, significantDigits + 1);
+  } else if (edit.digits.value_or(1) == 0 && !edit.variation) {
+    // F'2023 13.7.2.3.3 p5; does not apply to Gw.0(Ee) or E0(no d)
+    io_.GetIoErrorHandler().SignalError(IostatErrorInFormat,
+        "Output edit descriptor %cw.d must have d>0", edit.descriptor);
+    return false;
   }
   // In EN editing, multiple attempts may be necessary, so this is a loop.
   while (true) {
@@ -549,6 +554,7 @@ bool RealOutputEditing<KIND>::EditFOutput(const DataEdit &edit) {
 template <int KIND>
 DataEdit RealOutputEditing<KIND>::EditForGOutput(DataEdit edit) {
   edit.descriptor = 'E';
+  edit.variation = 'G'; // to suppress error for Ew.0
   int editWidth{edit.width.value_or(0)};
   int significantDigits{
       edit.digits.value_or(BinaryFloatingPoint::decimalPrecision)}; // 'd'
@@ -594,7 +600,9 @@ bool RealOutputEditing<KIND>::EditListDirectedOutput(const DataEdit &edit) {
   decimal::ConversionToDecimalResult converted{
       ConvertToDecimal(1, edit.modes.round)};
   if (IsInfOrNaN(converted.str, static_cast<int>(converted.length))) {
-    return EditEorDOutput(edit);
+    DataEdit copy{edit};
+    copy.variation = DataEdit::ListDirected;
+    return EditEorDOutput(copy);
   }
   int expo{converted.decimalExponent};
   // The decimal precision of 16-bit floating-point types is very low,
@@ -604,10 +612,12 @@ bool RealOutputEditing<KIND>::EditListDirectedOutput(const DataEdit &edit) {
       std::max(6, BinaryFloatingPoint::decimalPrecision)};
   if (expo < 0 || expo > maxExpo) {
     DataEdit copy{edit};
+    copy.variation = DataEdit::ListDirected;
     copy.modes.scale = 1; // 1P
     return EditEorDOutput(copy);
+  } else {
+    return EditFOutput(edit);
   }
-  return EditFOutput(edit);
 }
 
 // 13.7.2.3.6 in F'2023

diff  --git a/flang/runtime/format.h b/flang/runtime/format.h
index 989006ecd85cab..1fe0802ac43c69 100644
--- a/flang/runtime/format.h
+++ b/flang/runtime/format.h
@@ -63,7 +63,7 @@ struct DataEdit {
 
   static constexpr char DefinedDerivedType{'d'}; // DT defined I/O
 
-  char variation{'\0'}; // N, S, or X for EN, ES, EX
+  char variation{'\0'}; // N, S, or X for EN, ES, EX; G/l for original G/list
   std::optional<int> width; // the 'w' field; optional for A
   std::optional<int> digits; // the 'm' or 'd' field
   std::optional<int> expoDigits; // 'Ee' field

diff  --git a/flang/unittests/Runtime/NumericalFormatTest.cpp b/flang/unittests/Runtime/NumericalFormatTest.cpp
index 9dd2771fe4a753..03a2be3ca56df7 100644
--- a/flang/unittests/Runtime/NumericalFormatTest.cpp
+++ b/flang/unittests/Runtime/NumericalFormatTest.cpp
@@ -421,7 +421,7 @@ TEST(IOApiTests, FormatDoubleValues) {
               {"(E62.55,';')",
                   " 0.1000000000000000055511151231257827021181583404541015625E+"
                   "00;"},
-              {"(E0.0,';')", ".1E+00;"},
+              {"(E0.1,';')", ".1E+00;"},
               {"(E0.55,';')",
                   ".1000000000000000055511151231257827021181583404541015625E+"
                   "00;"},


        


More information about the flang-commits mailing list