Skip to content

Commit 534f8bc

Browse files
committed
[libc] Add inf/nan tests for strfrom*() functions
1 parent a51d13f commit 534f8bc

File tree

2 files changed

+82
-10
lines changed

2 files changed

+82
-10
lines changed

libc/test/src/stdlib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ add_header_library(
174174
StrfromTest.h
175175
DEPENDS
176176
libc.src.__support.CPP.type_traits
177+
libc.src.__support.FPUtil.fp_bits
177178
)
178179

179180
add_libc_test(

libc/test/src/stdlib/StrfromTest.h

Lines changed: 81 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/__support/CPP/type_traits.h"
10+
#include "src/__support/FPUtil/FPBits.h"
1011
#include "test/UnitTest/Test.h"
1112

1213
#define ASSERT_STREQ_LEN(actual_written, actual_str, expected_str) \
@@ -68,11 +69,27 @@ class StrfromTest : public LIBC_NAMESPACE::testing::Test {
6869
written = func(buff, 37, "A simple string with no conversions.", 1.0);
6970
ASSERT_STREQ_LEN(written, buff, "A simple string with no conversions.");
7071

71-
written =
72-
func(buff, 37,
73-
"%A simple string with one conversion, should overwrite.", 1.0);
74-
ASSERT_STREQ_LEN(written, buff, is_long_double ? "0X8P-3" : "0X1P+0");
75-
72+
if (is_long_double) {
73+
// 64-bit long double values require checking as they will give
74+
// a different result
75+
#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
76+
written =
77+
func(buff, 37,
78+
"%A simple string with one conversion, should overwrite.", 1.0);
79+
ASSERT_STREQ_LEN(written, buff, "0X1P+0");
80+
#else
81+
written =
82+
func(buff, 37,
83+
"%A simple string with one conversion, should overwrite.", 1.0);
84+
ASSERT_STREQ_LEN(written, buff, "0X8P-3");
85+
#endif
86+
} else {
87+
// not long double
88+
written =
89+
func(buff, 37,
90+
"%A simple string with one conversion, should overwrite.", 1.0);
91+
ASSERT_STREQ_LEN(written, buff, "0X1P+0");
92+
}
7693
written = func(buff, 74,
7794
"A simple string with one conversion in %A "
7895
"between, writes string as it is",
@@ -105,6 +122,13 @@ class StrfromTest : public LIBC_NAMESPACE::testing::Test {
105122
ASSERT_STREQ(buff, "1.05"); // Make sure that buff has not changed
106123
}
107124

125+
void infNanValues(FunctionT func) {
126+
if (is_double_prec)
127+
doublePrecInfNan(func);
128+
else if (!is_single_prec)
129+
longDoublePrecInfNan(func);
130+
}
131+
108132
void floatDecimalSinglePrec(FunctionT func) {
109133
char buff[70];
110134
int written;
@@ -336,8 +360,10 @@ class StrfromTest : public LIBC_NAMESPACE::testing::Test {
336360
}
337361

338362
void floatDecimalExpLongDoublePrec(FunctionT func) {
339-
char buff[100];
340-
int written;
363+
// Mark as maybe_unused to silence unused variable
364+
// warning when long double is not 80-bit
365+
[[maybe_unused]] char buff[100];
366+
[[maybe_unused]] int written;
341367

342368
#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
343369
written = func(buff, 90, "%.9e", 1000000000500000000.1L);
@@ -399,8 +425,10 @@ class StrfromTest : public LIBC_NAMESPACE::testing::Test {
399425
}
400426

401427
void floatDecimalAutoLongDoublePrec(FunctionT func) {
402-
char buff[100];
403-
int written;
428+
// Mark as maybe_unused to silence unused variable
429+
// warning when long double is not 80-bit
430+
[[maybe_unused]] char buff[100];
431+
[[maybe_unused]] int written;
404432

405433
#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
406434
written = func(buff, 99, "%g", 0xf.fffffffffffffffp+16380L);
@@ -413,6 +441,48 @@ class StrfromTest : public LIBC_NAMESPACE::testing::Test {
413441
ASSERT_STREQ_LEN(written, buff, "1e-99");
414442
#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
415443
}
444+
445+
void doublePrecInfNan(FunctionT func) {
446+
char buff[15];
447+
int written;
448+
449+
double inf = LIBC_NAMESPACE::fputil::FPBits<double>::inf().get_val();
450+
double nan = LIBC_NAMESPACE::fputil::FPBits<double>::quiet_nan().get_val();
451+
452+
written = func(buff, 10, "%f", inf);
453+
ASSERT_STREQ_LEN(written, buff, "inf");
454+
455+
written = func(buff, 10, "%A", -inf);
456+
ASSERT_STREQ_LEN(written, buff, "-INF");
457+
458+
written = func(buff, 10, "%f", nan);
459+
ASSERT_STREQ_LEN(written, buff, "nan");
460+
461+
written = func(buff, 10, "%A", -nan);
462+
ASSERT_STREQ_LEN(written, buff, "-NAN");
463+
}
464+
465+
void longDoublePrecInfNan(FunctionT func) {
466+
char buff[15];
467+
int written;
468+
469+
long double ld_inf =
470+
LIBC_NAMESPACE::fputil::FPBits<long double>::inf().get_val();
471+
long double ld_nan =
472+
LIBC_NAMESPACE::fputil::FPBits<long double>::quiet_nan().get_val();
473+
474+
written = func(buff, 10, "%f", ld_inf);
475+
ASSERT_STREQ_LEN(written, buff, "inf");
476+
477+
written = func(buff, 10, "%A", -ld_inf);
478+
ASSERT_STREQ_LEN(written, buff, "-INF");
479+
480+
written = func(buff, 10, "%f", ld_nan);
481+
ASSERT_STREQ_LEN(written, buff, "nan");
482+
483+
written = func(buff, 10, "%A", -ld_nan);
484+
ASSERT_STREQ_LEN(written, buff, "-NAN");
485+
}
416486
};
417487

418488
#define STRFROM_TEST(InputType, name, func) \
@@ -432,4 +502,5 @@ class StrfromTest : public LIBC_NAMESPACE::testing::Test {
432502
} \
433503
TEST_F(LlvmLibc##name##Test, InsufficientBufferSize) { \
434504
insufficentBufsize(func); \
435-
}
505+
} \
506+
TEST_F(LlvmLibc##name##Test, InfAndNanValues) { infNanValues(func); }

0 commit comments

Comments
 (0)