Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libc / test / src / stdlib / StrtolTest.h
blob11794c4bfe05f8a113be9bc90e8cd3f7df16c439
1 //===-- A template class for testing strto* functions -----------*- C++ -*-===//
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 //===----------------------------------------------------------------------===//
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"
15 #include <limits.h>
16 #include <stddef.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)
22 return '0';
23 if (input < 10)
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";
39 libc_errno = 0;
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";
49 libc_errno = 0;
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));
54 libc_errno = 0;
55 ASSERT_EQ(func(ten, nullptr, 10), ReturnT(10));
56 ASSERT_EQ(libc_errno, 0);
58 const char *hundred = "100";
59 libc_errno = 0;
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";
65 libc_errno = 0;
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";
73 libc_errno = 0;
74 if constexpr (sizeof(ReturnT) < 8) {
75 ASSERT_EQ(func(bigger_number, &str_end, 10), T_MAX);
76 ASSERT_EQ(libc_errno, ERANGE);
77 } else {
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";
84 libc_errno = 0;
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";
91 libc_errno = 0;
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";
99 libc_errno = 0;
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";
105 libc_errno = 0;
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";
111 libc_errno = 0;
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
117 // returned"
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";
129 libc_errno = 0;
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 ";
135 libc_errno = 0;
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";
141 libc_errno = 0;
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";
147 libc_errno = 0;
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";
153 libc_errno = 0;
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";
159 libc_errno = 0;
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";
165 libc_errno = 0;
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";
171 libc_errno = 0;
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";
177 libc_errno = 0;
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";
183 libc_errno = 0;
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 = " ";
189 libc_errno = 0;
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 = " +";
195 libc_errno = 0;
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;
205 #else
206 constexpr int limit = 36;
207 #endif
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) {
213 libc_errno = 0;
214 ASSERT_EQ(func(small_string, nullptr, base),
215 static_cast<ReturnT>(first_digit));
216 ASSERT_EQ(libc_errno, 0);
217 } else {
218 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) {
231 libc_errno = 0;
232 ASSERT_EQ(
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) {
237 libc_errno = 0;
238 ASSERT_EQ(func(small_string, nullptr, base),
239 static_cast<ReturnT>(first_digit));
240 ASSERT_EQ(libc_errno, 0);
241 } else {
242 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) {
260 libc_errno = 0;
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) {
267 libc_errno = 0;
268 ASSERT_EQ(
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) {
277 libc_errno = 0;
278 ASSERT_EQ(func(small_string, nullptr, base),
279 static_cast<ReturnT>(third_digit));
280 ASSERT_EQ(libc_errno, 0);
281 } else {
282 libc_errno = 0;
283 ASSERT_EQ(func(small_string, nullptr, base), ReturnT(0));
284 ASSERT_EQ(libc_errno, 0);
286 } else {
287 libc_errno = 0;
288 ASSERT_EQ(func(small_string, nullptr, base),
289 static_cast<ReturnT>(first_digit));
290 ASSERT_EQ(libc_errno, 0);
292 } else {
293 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";
307 libc_errno = 0;
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";
313 libc_errno = 0;
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";
319 libc_errno = 0;
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";
330 libc_errno = 0;
331 ASSERT_EQ(func(max_32_bit_value, &str_end, 0),
332 ((is_signed_v<ReturnT> && sizeof(ReturnT) == 4)
333 ? T_MAX
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";
340 libc_errno = 0;
341 ASSERT_EQ(func(negative_max_32_bit_value, &str_end, 0),
342 ((is_signed_v<ReturnT> && sizeof(ReturnT) == 4)
343 ? T_MIN
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";
352 libc_errno = 0;
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";
358 libc_errno = 0;
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";
367 libc_errno = 0;
368 ASSERT_EQ(func(max_64_bit_value, &str_end, 0),
369 (is_signed_v<ReturnT> || sizeof(ReturnT) < 8
370 ? T_MAX
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";
379 libc_errno = 0;
380 ASSERT_EQ(
381 func(negative_max_64_bit_value, &str_end, 0),
382 (is_signed_v<ReturnT>
383 ? T_MIN
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";
392 libc_errno = 0;
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";
399 libc_errno = 0;
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";
411 libc_errno = 0;
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));
416 libc_errno = 0;
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";
422 libc_errno = 0;
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));
427 libc_errno = 0;
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";
437 libc_errno = 0;
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";
443 libc_errno = 0;
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";
449 libc_errno = 0;
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";
455 libc_errno = 0;
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";
461 libc_errno = 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";
467 libc_errno = 0;
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";
473 libc_errno = 0;
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); \