diff --git a/libc/src/__support/str_to_integer.h b/libc/src/__support/str_to_integer.h --- a/libc/src/__support/str_to_integer.h +++ b/libc/src/__support/str_to_integer.h @@ -135,7 +135,7 @@ ptrdiff_t str_len = is_number ? (src - original_src) : 0; - if (result == abs_max) { + if (error_val == ERANGE) { if (is_positive || IS_UNSIGNED) return {cpp::numeric_limits::max(), str_len, error_val}; else // T is signed and there is a negative overflow diff --git a/libc/test/src/stdlib/StrtolTest.h b/libc/test/src/stdlib/StrtolTest.h --- a/libc/test/src/stdlib/StrtolTest.h +++ b/libc/test/src/stdlib/StrtolTest.h @@ -313,6 +313,75 @@ ASSERT_EQ(func(letter_after_prefix, &str_end, 16), ReturnT(0xabc123)); ASSERT_EQ(libc_errno, 0); EXPECT_EQ(str_end - letter_after_prefix, ptrdiff_t(8)); + + // These tests check what happens when the number passed is exactly the max + // value for the conversion. + + // Max size for unsigned 32 bit numbers + + const char *max_32_bit_value = "0xFFFFFFFF"; + libc_errno = 0; + ASSERT_EQ(func(max_32_bit_value, &str_end, 0), + ((is_signed_v && sizeof(ReturnT) == 4) + ? T_MAX + : ReturnT(0xFFFFFFFF))); + ASSERT_EQ(libc_errno, 0); + EXPECT_EQ(str_end - max_32_bit_value, ptrdiff_t(10)); + + const char *negative_max_32_bit_value = "-0xFFFFFFFF"; + libc_errno = 0; + ASSERT_EQ(func(negative_max_32_bit_value, &str_end, 0), + ((is_signed_v && sizeof(ReturnT) == 4) + ? T_MIN + : -ReturnT(0xFFFFFFFF))); + ASSERT_EQ(libc_errno, 0); + EXPECT_EQ(str_end - negative_max_32_bit_value, ptrdiff_t(11)); + + // Max size for signed 32 bit numbers + + const char *max_31_bit_value = "0x7FFFFFFF"; + libc_errno = 0; + ASSERT_EQ(func(max_31_bit_value, &str_end, 0), ReturnT(0x7FFFFFFF)); + ASSERT_EQ(libc_errno, 0); + EXPECT_EQ(str_end - max_31_bit_value, ptrdiff_t(10)); + + const char *negative_max_31_bit_value = "-0x7FFFFFFF"; + libc_errno = 0; + ASSERT_EQ(func(negative_max_31_bit_value, &str_end, 0), + -ReturnT(0x7FFFFFFF)); + ASSERT_EQ(libc_errno, 0); + EXPECT_EQ(str_end - negative_max_31_bit_value, ptrdiff_t(11)); + + // Max size for unsigned 64 bit numbers + + const char *max_64_bit_value = "0xFFFFFFFFFFFFFFFF"; + libc_errno = 0; + ASSERT_EQ(func(max_64_bit_value, &str_end, 0), + (is_signed_v ? T_MAX : ReturnT(0xFFFFFFFFFFFFFFFF))); + ASSERT_EQ(libc_errno, (is_signed_v ? ERANGE : 0)); + EXPECT_EQ(str_end - max_64_bit_value, ptrdiff_t(18)); + + const char *negative_max_64_bit_value = "-0xFFFFFFFFFFFFFFFF"; + libc_errno = 0; + ASSERT_EQ(func(negative_max_64_bit_value, &str_end, 0), + (is_signed_v ? T_MIN : -ReturnT(0xFFFFFFFFFFFFFFFF))); + ASSERT_EQ(libc_errno, (is_signed_v ? ERANGE : 0)); + EXPECT_EQ(str_end - negative_max_64_bit_value, ptrdiff_t(19)); + + // Max size for signed 64 bit numbers + + const char *max_63_bit_value = "0x7FFFFFFFFFFFFFFF"; + libc_errno = 0; + ASSERT_EQ(func(max_63_bit_value, &str_end, 0), ReturnT(0x7FFFFFFFFFFFFFFF)); + ASSERT_EQ(libc_errno, 0); + EXPECT_EQ(str_end - max_63_bit_value, ptrdiff_t(18)); + + const char *negative_max_63_bit_value = "-0x7FFFFFFFFFFFFFFF"; + libc_errno = 0; + ASSERT_EQ(func(negative_max_63_bit_value, &str_end, 0), + -ReturnT(0x7FFFFFFFFFFFFFFF)); + ASSERT_EQ(libc_errno, 0); + EXPECT_EQ(str_end - negative_max_63_bit_value, ptrdiff_t(19)); } void MessyBaseSixteenDecode(FunctionT func) {