1 //===-- A template class for testing strto* functions -----------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "src/__support/CPP/limits.h"
10 #include "src/__support/CPP/type_traits.h"
11 #include "src/__support/macros/properties/architectures.h"
12 #include "src/errno/libc_errno.h"
13 #include "test/UnitTest/Test.h"
18 using LIBC_NAMESPACE::cpp::is_signed_v
;
20 static inline char int_to_b36_char(int input
) {
21 if (input
< 0 || input
> 36)
24 return static_cast<char>('0' + input
);
25 return static_cast<char>('A' + input
- 10);
28 template <typename ReturnT
>
29 struct StrtoTest
: public LIBC_NAMESPACE::testing::Test
{
30 using FunctionT
= ReturnT (*)(const char *, char **, int);
32 static constexpr ReturnT T_MAX
=
33 LIBC_NAMESPACE::cpp::numeric_limits
<ReturnT
>::max();
34 static constexpr ReturnT T_MIN
=
35 LIBC_NAMESPACE::cpp::numeric_limits
<ReturnT
>::min();
37 void InvalidBase(FunctionT func
) {
38 const char *ten
= "10";
40 ASSERT_EQ(func(ten
, nullptr, -1), ReturnT(0));
41 ASSERT_EQ(libc_errno
, EINVAL
);
44 void CleanBaseTenDecode(FunctionT func
) {
45 char *str_end
= nullptr;
47 // TODO: Look into collapsing these repeated segments.
48 const char *ten
= "10";
50 ASSERT_EQ(func(ten
, &str_end
, 10), ReturnT(10));
51 ASSERT_EQ(libc_errno
, 0);
52 EXPECT_EQ(str_end
- ten
, ptrdiff_t(2));
55 ASSERT_EQ(func(ten
, nullptr, 10), ReturnT(10));
56 ASSERT_EQ(libc_errno
, 0);
58 const char *hundred
= "100";
60 ASSERT_EQ(func(hundred
, &str_end
, 10), ReturnT(100));
61 ASSERT_EQ(libc_errno
, 0);
62 EXPECT_EQ(str_end
- hundred
, ptrdiff_t(3));
64 const char *big_number
= "1234567890";
66 ASSERT_EQ(func(big_number
, &str_end
, 10), ReturnT(1234567890));
67 ASSERT_EQ(libc_errno
, 0);
68 EXPECT_EQ(str_end
- big_number
, ptrdiff_t(10));
70 // This number is larger than 2^32, meaning that if long is only 32 bits
71 // wide, strtol will return LONG_MAX.
72 const char *bigger_number
= "12345678900";
74 if constexpr (sizeof(ReturnT
) < 8) {
75 ASSERT_EQ(func(bigger_number
, &str_end
, 10), T_MAX
);
76 ASSERT_EQ(libc_errno
, ERANGE
);
78 ASSERT_EQ(func(bigger_number
, &str_end
, 10), ReturnT(12345678900));
79 ASSERT_EQ(libc_errno
, 0);
81 EXPECT_EQ(str_end
- bigger_number
, ptrdiff_t(11));
83 const char *too_big_number
= "123456789012345678901";
85 ASSERT_EQ(func(too_big_number
, &str_end
, 10), T_MAX
);
86 ASSERT_EQ(libc_errno
, ERANGE
);
87 EXPECT_EQ(str_end
- too_big_number
, ptrdiff_t(21));
89 const char *long_number_range_test
=
90 "10000000000000000000000000000000000000000000000000";
92 ASSERT_EQ(func(long_number_range_test
, &str_end
, 10), T_MAX
);
93 ASSERT_EQ(libc_errno
, ERANGE
);
94 EXPECT_EQ(str_end
- long_number_range_test
, ptrdiff_t(50));
96 // For most negative numbers, the unsigned functions treat it the same as
97 // casting a negative variable to an unsigned type.
98 const char *negative
= "-100";
100 ASSERT_EQ(func(negative
, &str_end
, 10), ReturnT(-100));
101 ASSERT_EQ(libc_errno
, 0);
102 EXPECT_EQ(str_end
- negative
, ptrdiff_t(4));
104 const char *big_negative_number
= "-1234567890";
106 ASSERT_EQ(func(big_negative_number
, &str_end
, 10), ReturnT(-1234567890));
107 ASSERT_EQ(libc_errno
, 0);
108 EXPECT_EQ(str_end
- big_negative_number
, ptrdiff_t(11));
110 const char *too_big_negative_number
= "-123456789012345678901";
112 // If the number is signed, it should return the smallest negative number
113 // for the current type, but if it's unsigned it should max out and return
114 // the largest positive number for the current type. From the standard:
115 // "If the correct value is outside the range of representable values,
116 // LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, or ULLONG_MAX is
118 // Note that 0 is not on that list.
119 ASSERT_EQ(func(too_big_negative_number
, &str_end
, 10),
120 (is_signed_v
<ReturnT
> ? T_MIN
: T_MAX
));
121 ASSERT_EQ(libc_errno
, ERANGE
);
122 EXPECT_EQ(str_end
- too_big_negative_number
, ptrdiff_t(22));
125 void MessyBaseTenDecode(FunctionT func
) {
126 char *str_end
= nullptr;
128 const char *spaces_before
= " 10";
130 ASSERT_EQ(func(spaces_before
, &str_end
, 10), ReturnT(10));
131 ASSERT_EQ(libc_errno
, 0);
132 EXPECT_EQ(str_end
- spaces_before
, ptrdiff_t(7));
134 const char *spaces_after
= "10 ";
136 ASSERT_EQ(func(spaces_after
, &str_end
, 10), ReturnT(10));
137 ASSERT_EQ(libc_errno
, 0);
138 EXPECT_EQ(str_end
- spaces_after
, ptrdiff_t(2));
140 const char *word_before
= "word10";
142 ASSERT_EQ(func(word_before
, &str_end
, 10), ReturnT(0));
143 ASSERT_EQ(libc_errno
, 0);
144 EXPECT_EQ(str_end
- word_before
, ptrdiff_t(0));
146 const char *word_after
= "10word";
148 ASSERT_EQ(func(word_after
, &str_end
, 10), ReturnT(10));
149 ASSERT_EQ(libc_errno
, 0);
150 EXPECT_EQ(str_end
- word_after
, ptrdiff_t(2));
152 const char *two_numbers
= "10 999";
154 ASSERT_EQ(func(two_numbers
, &str_end
, 10), ReturnT(10));
155 ASSERT_EQ(libc_errno
, 0);
156 EXPECT_EQ(str_end
- two_numbers
, ptrdiff_t(2));
158 const char *two_signs
= "--10 999";
160 ASSERT_EQ(func(two_signs
, &str_end
, 10), ReturnT(0));
161 ASSERT_EQ(libc_errno
, 0);
162 EXPECT_EQ(str_end
- two_signs
, ptrdiff_t(0));
164 const char *sign_before
= "+2=4";
166 ASSERT_EQ(func(sign_before
, &str_end
, 10), ReturnT(2));
167 ASSERT_EQ(libc_errno
, 0);
168 EXPECT_EQ(str_end
- sign_before
, ptrdiff_t(2));
170 const char *sign_after
= "2+2=4";
172 ASSERT_EQ(func(sign_after
, &str_end
, 10), ReturnT(2));
173 ASSERT_EQ(libc_errno
, 0);
174 EXPECT_EQ(str_end
- sign_after
, ptrdiff_t(1));
176 const char *tab_before
= "\t10";
178 ASSERT_EQ(func(tab_before
, &str_end
, 10), ReturnT(10));
179 ASSERT_EQ(libc_errno
, 0);
180 EXPECT_EQ(str_end
- tab_before
, ptrdiff_t(3));
182 const char *all_together
= "\t -12345and+67890";
184 ASSERT_EQ(func(all_together
, &str_end
, 10), ReturnT(-12345));
185 ASSERT_EQ(libc_errno
, 0);
186 EXPECT_EQ(str_end
- all_together
, ptrdiff_t(9));
188 const char *just_spaces
= " ";
190 ASSERT_EQ(func(just_spaces
, &str_end
, 10), ReturnT(0));
191 ASSERT_EQ(libc_errno
, 0);
192 EXPECT_EQ(str_end
- just_spaces
, ptrdiff_t(0));
194 const char *just_space_and_sign
= " +";
196 ASSERT_EQ(func(just_space_and_sign
, &str_end
, 10), ReturnT(0));
197 ASSERT_EQ(libc_errno
, 0);
198 EXPECT_EQ(str_end
- just_space_and_sign
, ptrdiff_t(0));
201 void DecodeInOtherBases(FunctionT func
) {
202 // This test is excessively slow on the GPU, so we limit the innermost loop.
203 #if defined(LIBC_TARGET_ARCH_IS_GPU)
204 constexpr int limit
= 0;
206 constexpr int limit
= 36;
208 char small_string
[4] = {'\0', '\0', '\0', '\0'};
209 for (int base
= 2; base
<= 36; ++base
) {
210 for (int first_digit
= 0; first_digit
<= 36; ++first_digit
) {
211 small_string
[0] = int_to_b36_char(first_digit
);
212 if (first_digit
< base
) {
214 ASSERT_EQ(func(small_string
, nullptr, base
),
215 static_cast<ReturnT
>(first_digit
));
216 ASSERT_EQ(libc_errno
, 0);
219 ASSERT_EQ(func(small_string
, nullptr, base
), ReturnT(0));
220 ASSERT_EQ(libc_errno
, 0);
225 for (int base
= 2; base
<= 36; ++base
) {
226 for (int first_digit
= 0; first_digit
<= 36; ++first_digit
) {
227 small_string
[0] = int_to_b36_char(first_digit
);
228 for (int second_digit
= 0; second_digit
<= 36; ++second_digit
) {
229 small_string
[1] = int_to_b36_char(second_digit
);
230 if (first_digit
< base
&& second_digit
< base
) {
233 func(small_string
, nullptr, base
),
234 static_cast<ReturnT
>(second_digit
+ (first_digit
* base
)));
235 ASSERT_EQ(libc_errno
, 0);
236 } else if (first_digit
< base
) {
238 ASSERT_EQ(func(small_string
, nullptr, base
),
239 static_cast<ReturnT
>(first_digit
));
240 ASSERT_EQ(libc_errno
, 0);
243 ASSERT_EQ(func(small_string
, nullptr, base
), ReturnT(0));
244 ASSERT_EQ(libc_errno
, 0);
250 for (int base
= 2; base
<= 36; ++base
) {
251 for (int first_digit
= 0; first_digit
<= 36; ++first_digit
) {
252 small_string
[0] = int_to_b36_char(first_digit
);
253 for (int second_digit
= 0; second_digit
<= 36; ++second_digit
) {
254 small_string
[1] = int_to_b36_char(second_digit
);
255 for (int third_digit
= 0; third_digit
<= limit
; ++third_digit
) {
256 small_string
[2] = int_to_b36_char(third_digit
);
258 if (first_digit
< base
&& second_digit
< base
&&
259 third_digit
< base
) {
261 ASSERT_EQ(func(small_string
, nullptr, base
),
262 static_cast<ReturnT
>(third_digit
+
263 (second_digit
* base
) +
264 (first_digit
* base
* base
)));
265 ASSERT_EQ(libc_errno
, 0);
266 } else if (first_digit
< base
&& second_digit
< base
) {
269 func(small_string
, nullptr, base
),
270 static_cast<ReturnT
>(second_digit
+ (first_digit
* base
)));
271 ASSERT_EQ(libc_errno
, 0);
272 } else if (first_digit
< base
) {
273 // if the base is 16 there is a special case for the prefix 0X.
274 // The number is treated as a one digit hexadecimal.
275 if (base
== 16 && first_digit
== 0 && second_digit
== 33) {
276 if (third_digit
< base
) {
278 ASSERT_EQ(func(small_string
, nullptr, base
),
279 static_cast<ReturnT
>(third_digit
));
280 ASSERT_EQ(libc_errno
, 0);
283 ASSERT_EQ(func(small_string
, nullptr, base
), ReturnT(0));
284 ASSERT_EQ(libc_errno
, 0);
288 ASSERT_EQ(func(small_string
, nullptr, base
),
289 static_cast<ReturnT
>(first_digit
));
290 ASSERT_EQ(libc_errno
, 0);
294 ASSERT_EQ(func(small_string
, nullptr, base
), ReturnT(0));
295 ASSERT_EQ(libc_errno
, 0);
303 void CleanBaseSixteenDecode(FunctionT func
) {
304 char *str_end
= nullptr;
306 const char *no_prefix
= "123abc";
308 ASSERT_EQ(func(no_prefix
, &str_end
, 16), ReturnT(0x123abc));
309 ASSERT_EQ(libc_errno
, 0);
310 EXPECT_EQ(str_end
- no_prefix
, ptrdiff_t(6));
312 const char *yes_prefix
= "0x456def";
314 ASSERT_EQ(func(yes_prefix
, &str_end
, 16), ReturnT(0x456def));
315 ASSERT_EQ(libc_errno
, 0);
316 EXPECT_EQ(str_end
- yes_prefix
, ptrdiff_t(8));
318 const char *letter_after_prefix
= "0xabc123";
320 ASSERT_EQ(func(letter_after_prefix
, &str_end
, 16), ReturnT(0xabc123));
321 ASSERT_EQ(libc_errno
, 0);
322 EXPECT_EQ(str_end
- letter_after_prefix
, ptrdiff_t(8));
324 // These tests check what happens when the number passed is exactly the max
325 // value for the conversion.
327 // Max size for unsigned 32 bit numbers
329 const char *max_32_bit_value
= "0xFFFFFFFF";
331 ASSERT_EQ(func(max_32_bit_value
, &str_end
, 0),
332 ((is_signed_v
<ReturnT
> && sizeof(ReturnT
) == 4)
334 : ReturnT(0xFFFFFFFF)));
335 ASSERT_EQ(libc_errno
,
336 is_signed_v
<ReturnT
> && sizeof(ReturnT
) == 4 ? ERANGE
: 0);
337 EXPECT_EQ(str_end
- max_32_bit_value
, ptrdiff_t(10));
339 const char *negative_max_32_bit_value
= "-0xFFFFFFFF";
341 ASSERT_EQ(func(negative_max_32_bit_value
, &str_end
, 0),
342 ((is_signed_v
<ReturnT
> && sizeof(ReturnT
) == 4)
344 : -ReturnT(0xFFFFFFFF)));
345 ASSERT_EQ(libc_errno
,
346 is_signed_v
<ReturnT
> && sizeof(ReturnT
) == 4 ? ERANGE
: 0);
347 EXPECT_EQ(str_end
- negative_max_32_bit_value
, ptrdiff_t(11));
349 // Max size for signed 32 bit numbers
351 const char *max_31_bit_value
= "0x7FFFFFFF";
353 ASSERT_EQ(func(max_31_bit_value
, &str_end
, 0), ReturnT(0x7FFFFFFF));
354 ASSERT_EQ(libc_errno
, 0);
355 EXPECT_EQ(str_end
- max_31_bit_value
, ptrdiff_t(10));
357 const char *negative_max_31_bit_value
= "-0x7FFFFFFF";
359 ASSERT_EQ(func(negative_max_31_bit_value
, &str_end
, 0),
360 -ReturnT(0x7FFFFFFF));
361 ASSERT_EQ(libc_errno
, 0);
362 EXPECT_EQ(str_end
- negative_max_31_bit_value
, ptrdiff_t(11));
364 // Max size for unsigned 64 bit numbers
366 const char *max_64_bit_value
= "0xFFFFFFFFFFFFFFFF";
368 ASSERT_EQ(func(max_64_bit_value
, &str_end
, 0),
369 (is_signed_v
<ReturnT
> || sizeof(ReturnT
) < 8
371 : ReturnT(0xFFFFFFFFFFFFFFFF)));
372 ASSERT_EQ(libc_errno
,
373 (is_signed_v
<ReturnT
> || sizeof(ReturnT
) < 8 ? ERANGE
: 0));
374 EXPECT_EQ(str_end
- max_64_bit_value
, ptrdiff_t(18));
376 // See the end of CleanBase10Decode for an explanation of how this large
377 // negative number can end up as T_MAX.
378 const char *negative_max_64_bit_value
= "-0xFFFFFFFFFFFFFFFF";
381 func(negative_max_64_bit_value
, &str_end
, 0),
382 (is_signed_v
<ReturnT
>
384 : (sizeof(ReturnT
) < 8 ? T_MAX
: -ReturnT(0xFFFFFFFFFFFFFFFF))));
385 ASSERT_EQ(libc_errno
,
386 (is_signed_v
<ReturnT
> || sizeof(ReturnT
) < 8 ? ERANGE
: 0));
387 EXPECT_EQ(str_end
- negative_max_64_bit_value
, ptrdiff_t(19));
389 // Max size for signed 64 bit numbers
391 const char *max_63_bit_value
= "0x7FFFFFFFFFFFFFFF";
393 ASSERT_EQ(func(max_63_bit_value
, &str_end
, 0),
394 (sizeof(ReturnT
) < 8 ? T_MAX
: ReturnT(0x7FFFFFFFFFFFFFFF)));
395 ASSERT_EQ(libc_errno
, sizeof(ReturnT
) < 8 ? ERANGE
: 0);
396 EXPECT_EQ(str_end
- max_63_bit_value
, ptrdiff_t(18));
398 const char *negative_max_63_bit_value
= "-0x7FFFFFFFFFFFFFFF";
400 ASSERT_EQ(func(negative_max_63_bit_value
, &str_end
, 0),
401 (sizeof(ReturnT
) >= 8 ? -ReturnT(0x7FFFFFFFFFFFFFFF)
402 : (is_signed_v
<ReturnT
> ? T_MIN
: T_MAX
)));
403 ASSERT_EQ(libc_errno
, sizeof(ReturnT
) < 8 ? ERANGE
: 0);
404 EXPECT_EQ(str_end
- negative_max_63_bit_value
, ptrdiff_t(19));
407 void MessyBaseSixteenDecode(FunctionT func
) {
408 char *str_end
= nullptr;
410 const char *just_prefix
= "0x";
412 ASSERT_EQ(func(just_prefix
, &str_end
, 16), ReturnT(0));
413 ASSERT_EQ(libc_errno
, 0);
414 EXPECT_EQ(str_end
- just_prefix
, ptrdiff_t(1));
417 ASSERT_EQ(func(just_prefix
, &str_end
, 0), ReturnT(0));
418 ASSERT_EQ(libc_errno
, 0);
419 EXPECT_EQ(str_end
- just_prefix
, ptrdiff_t(1));
421 const char *prefix_with_x_after
= "0xx";
423 ASSERT_EQ(func(prefix_with_x_after
, &str_end
, 16), ReturnT(0));
424 ASSERT_EQ(libc_errno
, 0);
425 EXPECT_EQ(str_end
- prefix_with_x_after
, ptrdiff_t(1));
428 ASSERT_EQ(func(prefix_with_x_after
, &str_end
, 0), ReturnT(0));
429 ASSERT_EQ(libc_errno
, 0);
430 EXPECT_EQ(str_end
- prefix_with_x_after
, ptrdiff_t(1));
433 void AutomaticBaseSelection(FunctionT func
) {
434 char *str_end
= nullptr;
436 const char *base_ten
= "12345";
438 ASSERT_EQ(func(base_ten
, &str_end
, 0), ReturnT(12345));
439 ASSERT_EQ(libc_errno
, 0);
440 EXPECT_EQ(str_end
- base_ten
, ptrdiff_t(5));
442 const char *base_sixteen_no_prefix
= "123abc";
444 ASSERT_EQ(func(base_sixteen_no_prefix
, &str_end
, 0), ReturnT(123));
445 ASSERT_EQ(libc_errno
, 0);
446 EXPECT_EQ(str_end
- base_sixteen_no_prefix
, ptrdiff_t(3));
448 const char *base_sixteen_with_prefix
= "0x456def";
450 ASSERT_EQ(func(base_sixteen_with_prefix
, &str_end
, 0), ReturnT(0x456def));
451 ASSERT_EQ(libc_errno
, 0);
452 EXPECT_EQ(str_end
- base_sixteen_with_prefix
, ptrdiff_t(8));
454 const char *base_eight_with_prefix
= "012345";
456 ASSERT_EQ(func(base_eight_with_prefix
, &str_end
, 0), ReturnT(012345));
457 ASSERT_EQ(libc_errno
, 0);
458 EXPECT_EQ(str_end
- base_eight_with_prefix
, ptrdiff_t(6));
460 const char *just_zero
= "0";
462 ASSERT_EQ(func(just_zero
, &str_end
, 0), ReturnT(0));
463 ASSERT_EQ(libc_errno
, 0);
464 EXPECT_EQ(str_end
- just_zero
, ptrdiff_t(1));
466 const char *just_zero_x
= "0x";
468 ASSERT_EQ(func(just_zero_x
, &str_end
, 0), ReturnT(0));
469 ASSERT_EQ(libc_errno
, 0);
470 EXPECT_EQ(str_end
- just_zero_x
, ptrdiff_t(1));
472 const char *just_zero_eight
= "08";
474 ASSERT_EQ(func(just_zero_eight
, &str_end
, 0), ReturnT(0));
475 ASSERT_EQ(libc_errno
, 0);
476 EXPECT_EQ(str_end
- just_zero_eight
, ptrdiff_t(1));
480 template <typename ReturnType
>
481 StrtoTest(ReturnType (*)(const char *)) -> StrtoTest
<ReturnType
>;
483 #define STRTOL_TEST(name, func) \
484 using LlvmLibc##name##Test = StrtoTest<decltype(func("", nullptr, 0))>; \
485 TEST_F(LlvmLibc##name##Test, InvalidBase) { InvalidBase(func); } \
486 TEST_F(LlvmLibc##name##Test, CleanBaseTenDecode) { \
487 CleanBaseTenDecode(func); \
489 TEST_F(LlvmLibc##name##Test, MessyBaseTenDecode) { \
490 MessyBaseTenDecode(func); \
492 TEST_F(LlvmLibc##name##Test, DecodeInOtherBases) { \
493 DecodeInOtherBases(func); \
495 TEST_F(LlvmLibc##name##Test, CleanBaseSixteenDecode) { \
496 CleanBaseSixteenDecode(func); \
498 TEST_F(LlvmLibc##name##Test, MessyBaseSixteenDecode) { \
499 MessyBaseSixteenDecode(func); \
501 TEST_F(LlvmLibc##name##Test, AutomaticBaseSelection) { \
502 AutomaticBaseSelection(func); \