Skip to content

Commit 212beb6

Browse files
committed
[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
1 parent 294f632 commit 212beb6

File tree

2 files changed

+83
-1
lines changed

2 files changed

+83
-1
lines changed

flang/runtime/edit-output.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ bool EditIntegerOutput(IoStatementState &io, const DataEdit &edit,
154154
int digits = end - p;
155155
int leadingZeroes{0};
156156
int editWidth{edit.width.value_or(0)};
157-
if (edit.digits && digits <= *edit.digits) { // Iw.m
157+
if (edit.descriptor == 'I' && edit.digits && digits <= *edit.digits) {
158+
// Only Iw.m can produce leading zeroes, not Gw.d (F'202X 13.7.5.2.2)
158159
if (*edit.digits == 0 && n == 0) {
159160
// Iw.0 with zero value: output field must be blank. For I0.0
160161
// and a zero value, emit one blank character.

flang/unittests/Runtime/NumericalFormatTest.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,22 @@ static bool CompareFormatReal(const char *format, std::uint64_t xInt,
5757
return CompareFormatReal(format, x, expect, got);
5858
}
5959

60+
static bool CompareFormatInteger(
61+
const char *format, std::int64_t x, const char *expect, std::string &got) {
62+
char buffer[800];
63+
auto cookie{IONAME(BeginInternalFormattedOutput)(
64+
buffer, sizeof buffer, format, std::strlen(format))};
65+
EXPECT_TRUE(IONAME(OutputInteger64)(cookie, x));
66+
auto status{IONAME(EndIoStatement)(cookie)};
67+
EXPECT_EQ(status, 0);
68+
got = std::string{buffer, sizeof buffer};
69+
auto lastNonBlank{got.find_last_not_of(" ")};
70+
if (lastNonBlank != std::string::npos) {
71+
got.resize(lastNonBlank + 1);
72+
}
73+
return CompareFormattedStrings(expect, got);
74+
}
75+
6076
struct IOApiTests : CrashHandlerFixture {};
6177

6278
TEST(IOApiTests, HelloWorldOutputTest) {
@@ -693,6 +709,71 @@ TEST(IOApiTests, FormatDoubleValues) {
693709
}
694710
}
695711

712+
TEST(IOApiTests, FormatIntegerValues) {
713+
using IntTestCaseTy = std::tuple<const char *, std::int64_t, const char *>;
714+
static const std::vector<IntTestCaseTy> intTestCases{
715+
{"(I4)", 0, " 0"},
716+
{"(I4)", 1, " 1"},
717+
{"(I4)", 9999, "9999"},
718+
{"(SP,I4)", 1, " +1"},
719+
{"(SP,I4)", 9999, "****"},
720+
{"(SP,I4)", 999, "+999"},
721+
{"(I4)", -1, " -1"},
722+
{"(I4)", -9999, "****"},
723+
{"(I4)", -999, "-999"},
724+
{"(I4.2)", 1, " 01"},
725+
{"(I4.2)", -1, " -01"},
726+
{"(I4.2)", 999, " 999"},
727+
{"(I4.4)", 999, "0999"},
728+
{"(I0)", 0, "0"},
729+
{"(I0)", 1, "1"},
730+
{"(I0)", 9999, "9999"},
731+
{"(SP,I0)", 1, "+1"},
732+
{"(SP,I0)", 9999, "+9999"},
733+
{"(SP,I0)", 999, "+999"},
734+
{"(I0)", -1, "-1"},
735+
{"(I0)", -9999, "-9999"},
736+
{"(I0)", -999, "-999"},
737+
{"(I0.2)", 1, "01"},
738+
{"(I0.2)", -1, "-01"},
739+
{"(I0.2)", 999, "999"},
740+
{"(I0.4)", 999, "0999"},
741+
{"(G4)", 0, " 0"},
742+
{"(G4)", 1, " 1"},
743+
{"(G4)", 9999, "9999"},
744+
{"(SP,G4)", 1, " +1"},
745+
{"(SP,G4)", 9999, "****"},
746+
{"(SP,G4)", 999, "+999"},
747+
{"(G4)", -1, " -1"},
748+
{"(G4)", -9999, "****"},
749+
{"(G4)", -999, "-999"},
750+
{"(G4.2)", 1, " 1"},
751+
{"(G4.2)", -1, " -1"},
752+
{"(G4.2)", 999, " 999"},
753+
{"(G4.4)", 999, " 999"},
754+
{"(G0)", 0, "0"},
755+
{"(G0)", 1, "1"},
756+
{"(G0)", 9999, "9999"},
757+
{"(SP,G0)", 1, "+1"},
758+
{"(SP,G0)", 9999, "+9999"},
759+
{"(SP,G0)", 999, "+999"},
760+
{"(G0)", -1, "-1"},
761+
{"(G0)", -9999, "-9999"},
762+
{"(G0)", -999, "-999"},
763+
{"(G0.2)", 1, "1"},
764+
{"(G0.2)", -1, "-1"},
765+
{"(G0.2)", 999, "999"},
766+
{"(G0.4)", 999, "999"},
767+
};
768+
769+
for (auto const &[fmt, value, expect] : intTestCases) {
770+
std::string got;
771+
ASSERT_TRUE(CompareFormatInteger(fmt, value, expect, got))
772+
<< "Failed to format " << fmt << ", expected '" << expect << "', got '"
773+
<< got << "'";
774+
}
775+
}
776+
696777
//------------------------------------------------------------------------------
697778
/// Tests for input formatting real values
698779
//------------------------------------------------------------------------------

0 commit comments

Comments
 (0)