187c01607SMichael Jones //===-- Unittests for strtod ---------------------------------------------===//
287c01607SMichael Jones //
387c01607SMichael Jones // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
487c01607SMichael Jones // See https://llvm.org/LICENSE.txt for license information.
587c01607SMichael Jones // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
687c01607SMichael Jones //
787c01607SMichael Jones //===----------------------------------------------------------------------===//
887c01607SMichael Jones
987c01607SMichael Jones #include "src/__support/FPUtil/FPBits.h"
1087c01607SMichael Jones #include "src/stdlib/strtod.h"
1187c01607SMichael Jones
1287c01607SMichael Jones #include "utils/UnitTest/Test.h"
1304c681d1SAlex Brachet #include "utils/testutils/RoundingModeUtils.h"
1487c01607SMichael Jones
1587c01607SMichael Jones #include <errno.h>
1687c01607SMichael Jones #include <limits.h>
1787c01607SMichael Jones #include <stddef.h>
1887c01607SMichael Jones
1904c681d1SAlex Brachet using __llvm_libc::testutils::ForceRoundingModeTest;
2004c681d1SAlex Brachet using __llvm_libc::testutils::RoundingMode;
2104c681d1SAlex Brachet
2204c681d1SAlex Brachet class LlvmLibcStrToDTest : public __llvm_libc::testing::Test,
2304c681d1SAlex Brachet ForceRoundingModeTest<RoundingMode::Nearest> {
2487c01607SMichael Jones public:
run_test(const char * inputString,const ptrdiff_t expectedStrLen,const uint64_t expectedRawData,const int expectedErrno=0)2525226f3eSMichael Jones void run_test(const char *inputString, const ptrdiff_t expectedStrLen,
2687c01607SMichael Jones const uint64_t expectedRawData, const int expectedErrno = 0) {
2787c01607SMichael Jones // expectedRawData is the expected double result as a uint64_t, organized
2887c01607SMichael Jones // according to IEEE754:
2987c01607SMichael Jones //
3087c01607SMichael Jones // +-- 1 Sign Bit +-- 52 Mantissa bits
3187c01607SMichael Jones // | |
3287c01607SMichael Jones // | +-------------------------+------------------------+
3387c01607SMichael Jones // | | |
3487c01607SMichael Jones // SEEEEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
3587c01607SMichael Jones // | |
3687c01607SMichael Jones // +----+----+
3787c01607SMichael Jones // |
3887c01607SMichael Jones // +-- 11 Exponent Bits
3987c01607SMichael Jones //
4087c01607SMichael Jones // This is so that the result can be compared in parts.
4125226f3eSMichael Jones char *str_end = nullptr;
4287c01607SMichael Jones
4325226f3eSMichael Jones __llvm_libc::fputil::FPBits<double> expected_fp =
4487c01607SMichael Jones __llvm_libc::fputil::FPBits<double>(expectedRawData);
4587c01607SMichael Jones
4687c01607SMichael Jones errno = 0;
4725226f3eSMichael Jones double result = __llvm_libc::strtod(inputString, &str_end);
4887c01607SMichael Jones
4925226f3eSMichael Jones __llvm_libc::fputil::FPBits<double> actual_fp =
5087c01607SMichael Jones __llvm_libc::fputil::FPBits<double>(result);
5187c01607SMichael Jones
5225226f3eSMichael Jones EXPECT_EQ(str_end - inputString, expectedStrLen);
5387c01607SMichael Jones
5425226f3eSMichael Jones EXPECT_EQ(actual_fp.bits, expected_fp.bits);
5525226f3eSMichael Jones EXPECT_EQ(actual_fp.get_sign(), expected_fp.get_sign());
5625226f3eSMichael Jones EXPECT_EQ(actual_fp.get_exponent(), expected_fp.get_exponent());
5725226f3eSMichael Jones EXPECT_EQ(actual_fp.get_mantissa(), expected_fp.get_mantissa());
5887c01607SMichael Jones EXPECT_EQ(errno, expectedErrno);
5987c01607SMichael Jones }
6087c01607SMichael Jones };
6187c01607SMichael Jones
TEST_F(LlvmLibcStrToDTest,SimpleTest)6287c01607SMichael Jones TEST_F(LlvmLibcStrToDTest, SimpleTest) {
6325226f3eSMichael Jones run_test("123", 3, uint64_t(0x405ec00000000000));
6487c01607SMichael Jones
6587c01607SMichael Jones // This should fail on Eisel-Lemire, forcing a fallback to simple decimal
6687c01607SMichael Jones // conversion.
6725226f3eSMichael Jones run_test("12345678901234549760", 20, uint64_t(0x43e56a95319d63d8));
6887c01607SMichael Jones
6987c01607SMichael Jones // Found while looking for difficult test cases here:
7087c01607SMichael Jones // https://github.com/nigeltao/parse-number-fxx-test-data/blob/main/more-test-cases/golang-org-issue-36657.txt
7125226f3eSMichael Jones run_test("1090544144181609348835077142190", 31, uint64_t(0x462b8779f2474dfb));
7287c01607SMichael Jones
7325226f3eSMichael Jones run_test("0x123", 5, uint64_t(0x4072300000000000));
7487c01607SMichael Jones }
7587c01607SMichael Jones
7687c01607SMichael Jones // These are tests that have caused problems in the past.
TEST_F(LlvmLibcStrToDTest,SpecificFailures)7787c01607SMichael Jones TEST_F(LlvmLibcStrToDTest, SpecificFailures) {
7825226f3eSMichael Jones run_test("3E70000000000000", 16, uint64_t(0x7FF0000000000000), ERANGE);
7925226f3eSMichael Jones run_test("358416272e-33", 13, uint64_t(0x3adbbb2a68c9d0b9));
8025226f3eSMichael Jones run_test("2.16656806400000023841857910156251e9", 36,
8187c01607SMichael Jones uint64_t(0x41e0246690000001));
8225226f3eSMichael Jones run_test("27949676547093071875", 20, uint64_t(0x43f83e132bc608c9));
83*bf7f01d8SMichael Jones run_test(
84*bf7f01d8SMichael Jones "100000000000000000000000000000000000000000000000000000000000000000000000"
85*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
86*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
87*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
88*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
89*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
90*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
91*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
92*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
93*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
94*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
95*bf7f01d8SMichael Jones "000000000e-800",
96*bf7f01d8SMichael Jones 806, 0x3ff0000000000000);
97*bf7f01d8SMichael Jones run_test(
98*bf7f01d8SMichael Jones "100000000000000000000000000000000000000000000000000000000000000000000000"
99*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
100*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
101*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
102*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
103*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
104*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
105*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
106*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
107*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
108*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
109*bf7f01d8SMichael Jones "000000000e-799",
110*bf7f01d8SMichael Jones 806, 0x4024000000000000);
111*bf7f01d8SMichael Jones run_test(
112*bf7f01d8SMichael Jones "100000000000000000000000000000000000000000000000000000000000000000000000"
113*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
114*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
115*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
116*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
117*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
118*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
119*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
120*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
121*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
122*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
123*bf7f01d8SMichael Jones "0000000000e-800",
124*bf7f01d8SMichael Jones 807, 0x4024000000000000);
125*bf7f01d8SMichael Jones run_test(
126*bf7f01d8SMichael Jones "10000000000000000000000000000000000000000000000000000000000000000e-64",
127*bf7f01d8SMichael Jones 69, 0x3ff0000000000000);
128*bf7f01d8SMichael Jones run_test(
129*bf7f01d8SMichael Jones "100000000000000000000000000000000000000000000000000000000000000000000000"
130*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000e-128",
131*bf7f01d8SMichael Jones 134, 0x3ff0000000000000);
132*bf7f01d8SMichael Jones run_test("1000000000000000000000000000000000000000000000000000000000000000000"
133*bf7f01d8SMichael Jones "0000000000000000000000000000000000000000000000000000000000000000000"
134*bf7f01d8SMichael Jones "0000000000000000000000000000000000000000000000000000000000000000000"
135*bf7f01d8SMichael Jones "00000000000000000000000000000000000000000000000000000000e-256",
136*bf7f01d8SMichael Jones 262, 0x3ff0000000000000);
137*bf7f01d8SMichael Jones run_test("1000000000000000000000000000000000000000000000000000000000000000000"
138*bf7f01d8SMichael Jones "0000000000000000000000000000000000000000000000000000000000000000000"
139*bf7f01d8SMichael Jones "0000000000000000000000000000000000000000000000000000000000000000000"
140*bf7f01d8SMichael Jones "0000000000000000000000000000000000000000000000000000000000000000000"
141*bf7f01d8SMichael Jones "0000000000000000000000000000000000000000000000000000000000000000000"
142*bf7f01d8SMichael Jones "0000000000000000000000000000000000000000000000000000000000000000000"
143*bf7f01d8SMichael Jones "0000000000000000000000000000000000000000000000000000000000000000000"
144*bf7f01d8SMichael Jones "00000000000000000000000000000000000000000000e-512",
145*bf7f01d8SMichael Jones 518, 0x3ff0000000000000);
146*bf7f01d8SMichael Jones run_test(
147*bf7f01d8SMichael Jones "100000000000000000000000000000000000000000000000000000000000000000000000"
148*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
149*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
150*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
151*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
152*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
153*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
154*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
155*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
156*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
157*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
158*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
159*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
160*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
161*bf7f01d8SMichael Jones "00000000000000000e-1024",
162*bf7f01d8SMichael Jones 1031, 0x3ff0000000000000);
163*bf7f01d8SMichael Jones run_test(
164*bf7f01d8SMichael Jones "0"
165*bf7f01d8SMichael Jones "100000000000000000000000000000000000000000000000000000000000000000000000"
166*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
167*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
168*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
169*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
170*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
171*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
172*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
173*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
174*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
175*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
176*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
177*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
178*bf7f01d8SMichael Jones "000000000000000000000000000000000000000000000000000000000000000000000000"
179*bf7f01d8SMichael Jones "00000000000000000e-1024",
180*bf7f01d8SMichael Jones 1032, 0x3ff0000000000000);
18187c01607SMichael Jones }
18287c01607SMichael Jones
TEST_F(LlvmLibcStrToDTest,FuzzFailures)18387c01607SMichael Jones TEST_F(LlvmLibcStrToDTest, FuzzFailures) {
18425226f3eSMichael Jones run_test("-\xff\xff\xff\xff\xff\xff\xff\x01", 0, uint64_t(0));
18525226f3eSMichael Jones run_test("-.????", 0, uint64_t(0));
18625226f3eSMichael Jones run_test(
18725226f3eSMichael Jones "44444444444444444444444444444444444444444444444444A44444444444444444"
18887c01607SMichael Jones "44444444444*\x99\xff\xff\xff\xff",
18987c01607SMichael Jones 50, uint64_t(0x4a3e68fdd0e0b2d8));
19025226f3eSMichael Jones run_test("-NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNKNNNNNNNNNNNNNNNNNN?"
19187c01607SMichael Jones "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN?",
19287c01607SMichael Jones 0, uint64_t(0));
19325226f3eSMichael Jones run_test("0x.666E40", 9, uint64_t(0x3fd99b9000000000));
19487c01607SMichael Jones }
195