diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -20,6 +20,7 @@ .ctype_utils libc.include.errno libc.src.errno.__errno_location + libc.utils.CPP.standalone_cpp ) add_header_library( diff --git a/libc/src/__support/str_conv_utils.h b/libc/src/__support/str_conv_utils.h --- a/libc/src/__support/str_conv_utils.h +++ b/libc/src/__support/str_conv_utils.h @@ -10,6 +10,7 @@ #define LIBC_SRC_STDLIB_STDLIB_UTILS_H #include "src/__support/ctype_utils.h" +#include "utils/CPP/Limits.h" #include #include @@ -50,8 +51,9 @@ // Takes a pointer to a string, a pointer to a string pointer, and the base to // convert to. This function is used as the backend for all of the string to int // functions. -static inline long long strtoll(const char *__restrict src, - char **__restrict str_end, int base) { +template +static inline T strtointeger(const char *__restrict src, + char **__restrict str_end, int base) { unsigned long long result = 0; if (base < 0 || base == 1 || base > 36) { @@ -73,9 +75,13 @@ src = src + 2; } + unsigned long long const NEGATIVE_MAX = + (__llvm_libc::cpp::NumericLimits::min() != 0) + ? __llvm_libc::cpp::NumericLimits::min() + : __llvm_libc::cpp::NumericLimits::max(); unsigned long long const ABS_MAX = - (result_sign == '+' ? LLONG_MAX - : static_cast(LLONG_MAX) + 1); + (result_sign == '+' ? __llvm_libc::cpp::NumericLimits::max() + : NEGATIVE_MAX); unsigned long long const ABS_MAX_DIV_BY_BASE = ABS_MAX / base; while (isalnum(*src)) { int cur_digit = b36_char_to_int(*src); @@ -100,9 +106,9 @@ if (str_end != nullptr) *str_end = const_cast(src); if (result_sign == '+') - return result; + return (T)(result); else - return -result; + return -(T)(result); } } // namespace internal diff --git a/libc/src/stdlib/strtoll.cpp b/libc/src/stdlib/strtoll.cpp --- a/libc/src/stdlib/strtoll.cpp +++ b/libc/src/stdlib/strtoll.cpp @@ -15,7 +15,7 @@ LLVM_LIBC_FUNCTION(long long, strtoll, (const char *__restrict str, char **__restrict str_end, int base)) { - return internal::strtoll(str, str_end, base); + return internal::strtointeger(str, str_end, base); } } // namespace __llvm_libc