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: 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 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. 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 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