#include "src/__support/FPUtil/FPBits.h"
#include "src/stdlib/strtod.h"
#include "utils/UnitTest/Test.h"
#include "utils/testutils/RoundingModeUtils.h"
#include <errno.h>
#include <limits.h>
#include <stddef.h>
using __llvm_libc::testutils::ForceRoundingModeTest;
using __llvm_libc::testutils::RoundingMode;
class LlvmLibcStrToDTest : public __llvm_libc::testing::Test,
ForceRoundingModeTest<RoundingMode::Nearest> {
public:
void run_test(const char *inputString, const ptrdiff_t expectedStrLen,
const uint64_t expectedRawData, const int expectedErrno = 0) {
char *str_end = nullptr;
__llvm_libc::fputil::FPBits<double> expected_fp =
__llvm_libc::fputil::FPBits<double>(expectedRawData);
errno = 0;
double result = __llvm_libc::strtod(inputString, &str_end);
__llvm_libc::fputil::FPBits<double> actual_fp =
__llvm_libc::fputil::FPBits<double>(result);
EXPECT_EQ(str_end - inputString, expectedStrLen);
EXPECT_EQ(actual_fp.bits, expected_fp.bits);
EXPECT_EQ(actual_fp.get_sign(), expected_fp.get_sign());
EXPECT_EQ(actual_fp.get_exponent(), expected_fp.get_exponent());
EXPECT_EQ(actual_fp.get_mantissa(), expected_fp.get_mantissa());
EXPECT_EQ(errno, expectedErrno);
}
};
TEST_F(LlvmLibcStrToDTest, SimpleTest) {
run_test("123", 3, uint64_t(0x405ec00000000000));
run_test("12345678901234549760", 20, uint64_t(0x43e56a95319d63d8));
run_test("1090544144181609348835077142190", 31, uint64_t(0x462b8779f2474dfb));
run_test("0x123", 5, uint64_t(0x4072300000000000));
}
TEST_F(LlvmLibcStrToDTest, SpecificFailures) {
run_test("3E70000000000000", 16, uint64_t(0x7FF0000000000000), ERANGE);
run_test("358416272e-33", 13, uint64_t(0x3adbbb2a68c9d0b9));
run_test("2.16656806400000023841857910156251e9", 36,
uint64_t(0x41e0246690000001));
run_test("27949676547093071875", 20, uint64_t(0x43f83e132bc608c9));
run_test(
"100000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000e-800",
806, 0x3ff0000000000000);
run_test(
"100000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000e-799",
806, 0x4024000000000000);
run_test(
"100000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"0000000000e-800",
807, 0x4024000000000000);
run_test(
"10000000000000000000000000000000000000000000000000000000000000000e-64",
69, 0x3ff0000000000000);
run_test(
"100000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000e-128",
134, 0x3ff0000000000000);
run_test("1000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000000000e-256",
262, 0x3ff0000000000000);
run_test("1000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000e-512",
518, 0x3ff0000000000000);
run_test(
"100000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000e-1024",
1031, 0x3ff0000000000000);
run_test(
"0"
"100000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000e-1024",
1032, 0x3ff0000000000000);
}
TEST_F(LlvmLibcStrToDTest, FuzzFailures) {
run_test("-\xff\xff\xff\xff\xff\xff\xff\x01", 0, uint64_t(0));
run_test("-.????", 0, uint64_t(0));
run_test(
"44444444444444444444444444444444444444444444444444A44444444444444444"
"44444444444*\x99\xff\xff\xff\xff",
50, uint64_t(0x4a3e68fdd0e0b2d8));
run_test("-NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNKNNNNNNNNNNNNNNNNNN?"
"NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN?",
0, uint64_t(0));
run_test("0x.666E40", 9, uint64_t(0x3fd99b9000000000));
}