1*71db0c75SAndroid Build Coastguard Worker //===-- A template class for testing ato* functions -------------*- C++ -*-===// 2*71db0c75SAndroid Build Coastguard Worker // 3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information. 5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*71db0c75SAndroid Build Coastguard Worker // 7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 8*71db0c75SAndroid Build Coastguard Worker 9*71db0c75SAndroid Build Coastguard Worker #include "src/__support/CPP/limits.h" // INT_MAX, INT_MIN, LLONG_MAX, LLONG_MIN 10*71db0c75SAndroid Build Coastguard Worker #include "src/__support/CPP/type_traits.h" 11*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/Test.h" 12*71db0c75SAndroid Build Coastguard Worker 13*71db0c75SAndroid Build Coastguard Worker using LIBC_NAMESPACE::cpp::is_same_v; 14*71db0c75SAndroid Build Coastguard Worker 15*71db0c75SAndroid Build Coastguard Worker template <typename ReturnT> 16*71db0c75SAndroid Build Coastguard Worker struct AtoTest : public LIBC_NAMESPACE::testing::Test { 17*71db0c75SAndroid Build Coastguard Worker using FunctionT = ReturnT (*)(const char *); 18*71db0c75SAndroid Build Coastguard Worker validNumbersAtoTest19*71db0c75SAndroid Build Coastguard Worker void validNumbers(FunctionT func) { 20*71db0c75SAndroid Build Coastguard Worker const char *zero = "0"; 21*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(zero), static_cast<ReturnT>(0)); 22*71db0c75SAndroid Build Coastguard Worker 23*71db0c75SAndroid Build Coastguard Worker const char *ten = "10"; 24*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(ten), static_cast<ReturnT>(10)); 25*71db0c75SAndroid Build Coastguard Worker 26*71db0c75SAndroid Build Coastguard Worker const char *negative_hundred = "-100"; 27*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(negative_hundred), static_cast<ReturnT>(-100)); 28*71db0c75SAndroid Build Coastguard Worker 29*71db0c75SAndroid Build Coastguard Worker const char *positive_thousand = "+1000"; 30*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(positive_thousand), static_cast<ReturnT>(1000)); 31*71db0c75SAndroid Build Coastguard Worker 32*71db0c75SAndroid Build Coastguard Worker const char *spaces_before = " 12345"; 33*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(spaces_before), static_cast<ReturnT>(12345)); 34*71db0c75SAndroid Build Coastguard Worker 35*71db0c75SAndroid Build Coastguard Worker const char *tabs_before = "\t\t\t\t67890"; 36*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(tabs_before), static_cast<ReturnT>(67890)); 37*71db0c75SAndroid Build Coastguard Worker 38*71db0c75SAndroid Build Coastguard Worker const char *letters_after = "123abc"; 39*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(letters_after), static_cast<ReturnT>(123)); 40*71db0c75SAndroid Build Coastguard Worker 41*71db0c75SAndroid Build Coastguard Worker const char *letters_between = "456def789"; 42*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(letters_between), static_cast<ReturnT>(456)); 43*71db0c75SAndroid Build Coastguard Worker 44*71db0c75SAndroid Build Coastguard Worker const char *all_together = "\t 110 times 5 = 550"; 45*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(all_together), static_cast<ReturnT>(110)); 46*71db0c75SAndroid Build Coastguard Worker 47*71db0c75SAndroid Build Coastguard Worker const char *biggest_int = "2147483647"; 48*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(biggest_int), static_cast<ReturnT>(INT_MAX)); 49*71db0c75SAndroid Build Coastguard Worker 50*71db0c75SAndroid Build Coastguard Worker const char *smallest_int = "-2147483648"; 51*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(smallest_int), static_cast<ReturnT>(INT_MIN)); 52*71db0c75SAndroid Build Coastguard Worker 53*71db0c75SAndroid Build Coastguard Worker if constexpr (sizeof(ReturnT) >= 8) { 54*71db0c75SAndroid Build Coastguard Worker const char *biggest_long_long = "9223372036854775807"; 55*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(biggest_long_long), static_cast<ReturnT>(LLONG_MAX)); 56*71db0c75SAndroid Build Coastguard Worker 57*71db0c75SAndroid Build Coastguard Worker const char *smallest_long_long = "-9223372036854775808"; 58*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(smallest_long_long), static_cast<ReturnT>(LLONG_MIN)); 59*71db0c75SAndroid Build Coastguard Worker } 60*71db0c75SAndroid Build Coastguard Worker 61*71db0c75SAndroid Build Coastguard Worker // If this is atoi and the size of int is less than the size of long, then 62*71db0c75SAndroid Build Coastguard Worker // we parse as long and cast to int to match existing behavior. This only 63*71db0c75SAndroid Build Coastguard Worker // matters for cases where the result would be outside of the int range, and 64*71db0c75SAndroid Build Coastguard Worker // those cases are undefined, so we can choose whatever output value we 65*71db0c75SAndroid Build Coastguard Worker // want. In this case we have chosen to cast since that matches existing 66*71db0c75SAndroid Build Coastguard Worker // implementations and makes differential fuzzing easier, but no user should 67*71db0c75SAndroid Build Coastguard Worker // rely on this behavior. 68*71db0c75SAndroid Build Coastguard Worker if constexpr (is_same_v<ReturnT, int> && sizeof(ReturnT) < sizeof(long)) { 69*71db0c75SAndroid Build Coastguard Worker 70*71db0c75SAndroid Build Coastguard Worker static_assert(sizeof(int) == 4); 71*71db0c75SAndroid Build Coastguard Worker 72*71db0c75SAndroid Build Coastguard Worker const char *bigger_than_biggest_int = "2147483649"; 73*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(bigger_than_biggest_int), 74*71db0c75SAndroid Build Coastguard Worker static_cast<ReturnT>(2147483649)); 75*71db0c75SAndroid Build Coastguard Worker 76*71db0c75SAndroid Build Coastguard Worker const char *smaller_than_smallest_int = "-2147483649"; 77*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(smaller_than_smallest_int), 78*71db0c75SAndroid Build Coastguard Worker static_cast<ReturnT>(-2147483649)); 79*71db0c75SAndroid Build Coastguard Worker } 80*71db0c75SAndroid Build Coastguard Worker } 81*71db0c75SAndroid Build Coastguard Worker nonBaseTenWholeNumbersAtoTest82*71db0c75SAndroid Build Coastguard Worker void nonBaseTenWholeNumbers(FunctionT func) { 83*71db0c75SAndroid Build Coastguard Worker const char *hexadecimal = "0x10"; 84*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(hexadecimal), static_cast<ReturnT>(0)); 85*71db0c75SAndroid Build Coastguard Worker 86*71db0c75SAndroid Build Coastguard Worker const char *octal = "010"; 87*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(octal), static_cast<ReturnT>(10)); 88*71db0c75SAndroid Build Coastguard Worker 89*71db0c75SAndroid Build Coastguard Worker const char *decimal_point = "5.9"; 90*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(decimal_point), static_cast<ReturnT>(5)); 91*71db0c75SAndroid Build Coastguard Worker } 92*71db0c75SAndroid Build Coastguard Worker notNumbersAtoTest93*71db0c75SAndroid Build Coastguard Worker void notNumbers(FunctionT func) { 94*71db0c75SAndroid Build Coastguard Worker const char *ten_as_word = "ten"; 95*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(ten_as_word), static_cast<ReturnT>(0)); 96*71db0c75SAndroid Build Coastguard Worker 97*71db0c75SAndroid Build Coastguard Worker const char *lots_of_letters = 98*71db0c75SAndroid Build Coastguard Worker "wtragsdhfgjykutjdyfhgnchgmjhkyurktfgjhlu;po7urtdjyfhgklyk"; 99*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(func(lots_of_letters), static_cast<ReturnT>(0)); 100*71db0c75SAndroid Build Coastguard Worker } 101*71db0c75SAndroid Build Coastguard Worker }; 102*71db0c75SAndroid Build Coastguard Worker 103*71db0c75SAndroid Build Coastguard Worker template <typename ReturnType> 104*71db0c75SAndroid Build Coastguard Worker AtoTest(ReturnType (*)(const char *)) -> AtoTest<ReturnType>; 105*71db0c75SAndroid Build Coastguard Worker 106*71db0c75SAndroid Build Coastguard Worker #define ATOI_TEST(name, func) \ 107*71db0c75SAndroid Build Coastguard Worker using LlvmLibc##name##Test = AtoTest<decltype(func(""))>; \ 108*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, ValidNumbers) { validNumbers(func); } \ 109*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, NonBaseTenWholeNumbers) { \ 110*71db0c75SAndroid Build Coastguard Worker nonBaseTenWholeNumbers(func); \ 111*71db0c75SAndroid Build Coastguard Worker } \ 112*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibc##name##Test, NotNumbers) { notNumbers(func); } 113