1 //===-- Unittests for strtod ---------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "src/__support/FPUtil/FPBits.h"
10 #include "src/stdlib/strtod.h"
11 
12 #include "utils/UnitTest/Test.h"
13 #include "utils/testutils/RoundingModeUtils.h"
14 
15 #include <errno.h>
16 #include <limits.h>
17 #include <stddef.h>
18 
19 using __llvm_libc::testutils::ForceRoundingModeTest;
20 using __llvm_libc::testutils::RoundingMode;
21 
22 class LlvmLibcStrToDTest : public __llvm_libc::testing::Test,
23                            ForceRoundingModeTest<RoundingMode::Nearest> {
24 public:
run_test(const char * inputString,const ptrdiff_t expectedStrLen,const uint64_t expectedRawData,const int expectedErrno=0)25   void run_test(const char *inputString, const ptrdiff_t expectedStrLen,
26                 const uint64_t expectedRawData, const int expectedErrno = 0) {
27     // expectedRawData is the expected double result as a uint64_t, organized
28     // according to IEEE754:
29     //
30     // +-- 1 Sign Bit                        +-- 52 Mantissa bits
31     // |                                     |
32     // |           +-------------------------+------------------------+
33     // |           |                                                  |
34     // SEEEEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
35     //  |         |
36     //  +----+----+
37     //       |
38     //       +-- 11 Exponent Bits
39     //
40     //  This is so that the result can be compared in parts.
41     char *str_end = nullptr;
42 
43     __llvm_libc::fputil::FPBits<double> expected_fp =
44         __llvm_libc::fputil::FPBits<double>(expectedRawData);
45 
46     errno = 0;
47     double result = __llvm_libc::strtod(inputString, &str_end);
48 
49     __llvm_libc::fputil::FPBits<double> actual_fp =
50         __llvm_libc::fputil::FPBits<double>(result);
51 
52     EXPECT_EQ(str_end - inputString, expectedStrLen);
53 
54     EXPECT_EQ(actual_fp.bits, expected_fp.bits);
55     EXPECT_EQ(actual_fp.get_sign(), expected_fp.get_sign());
56     EXPECT_EQ(actual_fp.get_exponent(), expected_fp.get_exponent());
57     EXPECT_EQ(actual_fp.get_mantissa(), expected_fp.get_mantissa());
58     EXPECT_EQ(errno, expectedErrno);
59   }
60 };
61 
TEST_F(LlvmLibcStrToDTest,SimpleTest)62 TEST_F(LlvmLibcStrToDTest, SimpleTest) {
63   run_test("123", 3, uint64_t(0x405ec00000000000));
64 
65   // This should fail on Eisel-Lemire, forcing a fallback to simple decimal
66   // conversion.
67   run_test("12345678901234549760", 20, uint64_t(0x43e56a95319d63d8));
68 
69   // Found while looking for difficult test cases here:
70   // https://github.com/nigeltao/parse-number-fxx-test-data/blob/main/more-test-cases/golang-org-issue-36657.txt
71   run_test("1090544144181609348835077142190", 31, uint64_t(0x462b8779f2474dfb));
72 
73   run_test("0x123", 5, uint64_t(0x4072300000000000));
74 }
75 
76 // These are tests that have caused problems in the past.
TEST_F(LlvmLibcStrToDTest,SpecificFailures)77 TEST_F(LlvmLibcStrToDTest, SpecificFailures) {
78   run_test("3E70000000000000", 16, uint64_t(0x7FF0000000000000), ERANGE);
79   run_test("358416272e-33", 13, uint64_t(0x3adbbb2a68c9d0b9));
80   run_test("2.16656806400000023841857910156251e9", 36,
81            uint64_t(0x41e0246690000001));
82   run_test("27949676547093071875", 20, uint64_t(0x43f83e132bc608c9));
83   run_test(
84       "100000000000000000000000000000000000000000000000000000000000000000000000"
85       "000000000000000000000000000000000000000000000000000000000000000000000000"
86       "000000000000000000000000000000000000000000000000000000000000000000000000"
87       "000000000000000000000000000000000000000000000000000000000000000000000000"
88       "000000000000000000000000000000000000000000000000000000000000000000000000"
89       "000000000000000000000000000000000000000000000000000000000000000000000000"
90       "000000000000000000000000000000000000000000000000000000000000000000000000"
91       "000000000000000000000000000000000000000000000000000000000000000000000000"
92       "000000000000000000000000000000000000000000000000000000000000000000000000"
93       "000000000000000000000000000000000000000000000000000000000000000000000000"
94       "000000000000000000000000000000000000000000000000000000000000000000000000"
95       "000000000e-800",
96       806, 0x3ff0000000000000);
97   run_test(
98       "100000000000000000000000000000000000000000000000000000000000000000000000"
99       "000000000000000000000000000000000000000000000000000000000000000000000000"
100       "000000000000000000000000000000000000000000000000000000000000000000000000"
101       "000000000000000000000000000000000000000000000000000000000000000000000000"
102       "000000000000000000000000000000000000000000000000000000000000000000000000"
103       "000000000000000000000000000000000000000000000000000000000000000000000000"
104       "000000000000000000000000000000000000000000000000000000000000000000000000"
105       "000000000000000000000000000000000000000000000000000000000000000000000000"
106       "000000000000000000000000000000000000000000000000000000000000000000000000"
107       "000000000000000000000000000000000000000000000000000000000000000000000000"
108       "000000000000000000000000000000000000000000000000000000000000000000000000"
109       "000000000e-799",
110       806, 0x4024000000000000);
111   run_test(
112       "100000000000000000000000000000000000000000000000000000000000000000000000"
113       "000000000000000000000000000000000000000000000000000000000000000000000000"
114       "000000000000000000000000000000000000000000000000000000000000000000000000"
115       "000000000000000000000000000000000000000000000000000000000000000000000000"
116       "000000000000000000000000000000000000000000000000000000000000000000000000"
117       "000000000000000000000000000000000000000000000000000000000000000000000000"
118       "000000000000000000000000000000000000000000000000000000000000000000000000"
119       "000000000000000000000000000000000000000000000000000000000000000000000000"
120       "000000000000000000000000000000000000000000000000000000000000000000000000"
121       "000000000000000000000000000000000000000000000000000000000000000000000000"
122       "000000000000000000000000000000000000000000000000000000000000000000000000"
123       "0000000000e-800",
124       807, 0x4024000000000000);
125   run_test(
126       "10000000000000000000000000000000000000000000000000000000000000000e-64",
127       69, 0x3ff0000000000000);
128   run_test(
129       "100000000000000000000000000000000000000000000000000000000000000000000000"
130       "000000000000000000000000000000000000000000000000000000000e-128",
131       134, 0x3ff0000000000000);
132   run_test("1000000000000000000000000000000000000000000000000000000000000000000"
133            "0000000000000000000000000000000000000000000000000000000000000000000"
134            "0000000000000000000000000000000000000000000000000000000000000000000"
135            "00000000000000000000000000000000000000000000000000000000e-256",
136            262, 0x3ff0000000000000);
137   run_test("1000000000000000000000000000000000000000000000000000000000000000000"
138            "0000000000000000000000000000000000000000000000000000000000000000000"
139            "0000000000000000000000000000000000000000000000000000000000000000000"
140            "0000000000000000000000000000000000000000000000000000000000000000000"
141            "0000000000000000000000000000000000000000000000000000000000000000000"
142            "0000000000000000000000000000000000000000000000000000000000000000000"
143            "0000000000000000000000000000000000000000000000000000000000000000000"
144            "00000000000000000000000000000000000000000000e-512",
145            518, 0x3ff0000000000000);
146   run_test(
147       "100000000000000000000000000000000000000000000000000000000000000000000000"
148       "000000000000000000000000000000000000000000000000000000000000000000000000"
149       "000000000000000000000000000000000000000000000000000000000000000000000000"
150       "000000000000000000000000000000000000000000000000000000000000000000000000"
151       "000000000000000000000000000000000000000000000000000000000000000000000000"
152       "000000000000000000000000000000000000000000000000000000000000000000000000"
153       "000000000000000000000000000000000000000000000000000000000000000000000000"
154       "000000000000000000000000000000000000000000000000000000000000000000000000"
155       "000000000000000000000000000000000000000000000000000000000000000000000000"
156       "000000000000000000000000000000000000000000000000000000000000000000000000"
157       "000000000000000000000000000000000000000000000000000000000000000000000000"
158       "000000000000000000000000000000000000000000000000000000000000000000000000"
159       "000000000000000000000000000000000000000000000000000000000000000000000000"
160       "000000000000000000000000000000000000000000000000000000000000000000000000"
161       "00000000000000000e-1024",
162       1031, 0x3ff0000000000000);
163   run_test(
164       "0"
165       "100000000000000000000000000000000000000000000000000000000000000000000000"
166       "000000000000000000000000000000000000000000000000000000000000000000000000"
167       "000000000000000000000000000000000000000000000000000000000000000000000000"
168       "000000000000000000000000000000000000000000000000000000000000000000000000"
169       "000000000000000000000000000000000000000000000000000000000000000000000000"
170       "000000000000000000000000000000000000000000000000000000000000000000000000"
171       "000000000000000000000000000000000000000000000000000000000000000000000000"
172       "000000000000000000000000000000000000000000000000000000000000000000000000"
173       "000000000000000000000000000000000000000000000000000000000000000000000000"
174       "000000000000000000000000000000000000000000000000000000000000000000000000"
175       "000000000000000000000000000000000000000000000000000000000000000000000000"
176       "000000000000000000000000000000000000000000000000000000000000000000000000"
177       "000000000000000000000000000000000000000000000000000000000000000000000000"
178       "000000000000000000000000000000000000000000000000000000000000000000000000"
179       "00000000000000000e-1024",
180       1032, 0x3ff0000000000000);
181 }
182 
TEST_F(LlvmLibcStrToDTest,FuzzFailures)183 TEST_F(LlvmLibcStrToDTest, FuzzFailures) {
184   run_test("-\xff\xff\xff\xff\xff\xff\xff\x01", 0, uint64_t(0));
185   run_test("-.????", 0, uint64_t(0));
186   run_test(
187       "44444444444444444444444444444444444444444444444444A44444444444444444"
188       "44444444444*\x99\xff\xff\xff\xff",
189       50, uint64_t(0x4a3e68fdd0e0b2d8));
190   run_test("-NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNKNNNNNNNNNNNNNNNNNN?"
191            "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN?",
192            0, uint64_t(0));
193   run_test("0x.666E40", 9, uint64_t(0x3fd99b9000000000));
194 }
195