diff --git a/libc/src/__support/ctype_utils.h b/libc/src/__support/ctype_utils.h index be0f25330af9e..61b7a0aeb5b67 100644 --- a/libc/src/__support/ctype_utils.h +++ b/libc/src/__support/ctype_utils.h @@ -27,7 +27,7 @@ namespace internal { // as well as a way to support non-ASCII character encodings. // Similarly, do not change these functions to use case ranges. e.g. -// bool islower(int ch) { +// bool islower(char ch) { // switch(ch) { // case 'a'...'z': // return true; @@ -37,7 +37,7 @@ namespace internal { // EBCDIC. Technically we could use some smaller ranges, but that's even harder // to read. -LIBC_INLINE static constexpr bool islower(int ch) { +LIBC_INLINE static constexpr bool islower(char ch) { switch (ch) { case 'a': case 'b': @@ -71,7 +71,7 @@ LIBC_INLINE static constexpr bool islower(int ch) { } } -LIBC_INLINE static constexpr bool isupper(int ch) { +LIBC_INLINE static constexpr bool isupper(char ch) { switch (ch) { case 'A': case 'B': @@ -105,7 +105,7 @@ LIBC_INLINE static constexpr bool isupper(int ch) { } } -LIBC_INLINE static constexpr bool isdigit(int ch) { +LIBC_INLINE static constexpr bool isdigit(char ch) { switch (ch) { case '0': case '1': @@ -123,7 +123,7 @@ LIBC_INLINE static constexpr bool isdigit(int ch) { } } -LIBC_INLINE static constexpr int tolower(int ch) { +LIBC_INLINE static constexpr char tolower(char ch) { switch (ch) { case 'A': return 'a'; @@ -182,7 +182,7 @@ LIBC_INLINE static constexpr int tolower(int ch) { } } -LIBC_INLINE static constexpr int toupper(int ch) { +LIBC_INLINE static constexpr char toupper(char ch) { switch (ch) { case 'a': return 'A'; @@ -241,7 +241,7 @@ LIBC_INLINE static constexpr int toupper(int ch) { } } -LIBC_INLINE static constexpr bool isalpha(int ch) { +LIBC_INLINE static constexpr bool isalpha(char ch) { switch (ch) { case 'a': case 'b': @@ -301,7 +301,7 @@ LIBC_INLINE static constexpr bool isalpha(int ch) { } } -LIBC_INLINE static constexpr bool isalnum(int ch) { +LIBC_INLINE static constexpr bool isalnum(char ch) { switch (ch) { case 'a': case 'b': @@ -371,7 +371,7 @@ LIBC_INLINE static constexpr bool isalnum(int ch) { } } -LIBC_INLINE static constexpr int b36_char_to_int(int ch) { +LIBC_INLINE static constexpr int b36_char_to_int(char ch) { switch (ch) { case '0': return 0; @@ -476,7 +476,7 @@ LIBC_INLINE static constexpr int b36_char_to_int(int ch) { } } -LIBC_INLINE static constexpr int int_to_b36_char(int num) { +LIBC_INLINE static constexpr char int_to_b36_char(int num) { // Can't actually use LIBC_ASSERT here because it depends on integer_to_string // which depends on this. @@ -559,7 +559,7 @@ LIBC_INLINE static constexpr int int_to_b36_char(int num) { } } -LIBC_INLINE static constexpr bool isspace(int ch) { +LIBC_INLINE static constexpr bool isspace(char ch) { switch (ch) { case ' ': case '\t': @@ -574,7 +574,7 @@ LIBC_INLINE static constexpr bool isspace(int ch) { } // not yet encoding independent. -LIBC_INLINE static constexpr bool isgraph(int ch) { +LIBC_INLINE static constexpr bool isgraph(char ch) { return 0x20 < ch && ch < 0x7f; } diff --git a/libc/src/__support/integer_to_string.h b/libc/src/__support/integer_to_string.h index 29449bd739730..5e7369de00962 100644 --- a/libc/src/__support/integer_to_string.h +++ b/libc/src/__support/integer_to_string.h @@ -378,9 +378,8 @@ template class IntegerToString { using UNSIGNED_T = make_integral_or_big_int_unsigned_t; LIBC_INLINE static char digit_char(uint8_t digit) { - const int result = internal::int_to_b36_char(digit); - return static_cast(Fmt::IS_UPPERCASE ? internal::toupper(result) - : result); + const char result = internal::int_to_b36_char(digit); + return Fmt::IS_UPPERCASE ? internal::toupper(result) : result; } LIBC_INLINE static void diff --git a/libc/src/ctype/CMakeLists.txt b/libc/src/ctype/CMakeLists.txt index 8830c1bccf9ea..68e982bd4529e 100644 --- a/libc/src/ctype/CMakeLists.txt +++ b/libc/src/ctype/CMakeLists.txt @@ -6,6 +6,7 @@ add_entrypoint_object( isalnum.h DEPENDS libc.include.ctype + libc.src.__support.CPP.limits libc.src.__support.ctype_utils ) @@ -16,6 +17,7 @@ add_entrypoint_object( HDRS isalpha.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils ) @@ -50,6 +52,7 @@ add_entrypoint_object( HDRS isdigit.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils ) @@ -60,6 +63,7 @@ add_entrypoint_object( HDRS isgraph.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils ) @@ -70,6 +74,7 @@ add_entrypoint_object( HDRS islower.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils ) @@ -88,6 +93,7 @@ add_entrypoint_object( HDRS ispunct.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils ) @@ -97,6 +103,9 @@ add_entrypoint_object( isspace.cpp HDRS isspace.h + DEPENDS + libc.src.__support.CPP.limits + libc.src.__support.ctype_utils ) add_entrypoint_object( @@ -106,6 +115,7 @@ add_entrypoint_object( HDRS isupper.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils ) @@ -116,6 +126,7 @@ add_entrypoint_object( HDRS isxdigit.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils ) @@ -126,6 +137,7 @@ add_entrypoint_object( HDRS tolower.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils ) @@ -144,6 +156,7 @@ add_entrypoint_object( HDRS toupper.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils ) @@ -160,6 +173,7 @@ add_entrypoint_object( isalnum_l.h DEPENDS libc.include.ctype + libc.src.__support.CPP.limits libc.src.__support.ctype_utils libc.hdr.types.locale_t ) @@ -171,6 +185,7 @@ add_entrypoint_object( HDRS isalpha_l.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils libc.hdr.types.locale_t ) @@ -202,6 +217,7 @@ add_entrypoint_object( HDRS isdigit_l.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils libc.hdr.types.locale_t ) @@ -224,6 +240,7 @@ add_entrypoint_object( HDRS islower_l.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils libc.hdr.types.locale_t ) @@ -257,6 +274,8 @@ add_entrypoint_object( isspace_l.h DEPENDS libc.hdr.types.locale_t + libc.src.__support.CPP.limits + libc.src.__support.ctype_utils ) add_entrypoint_object( @@ -266,6 +285,7 @@ add_entrypoint_object( HDRS isupper_l.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils libc.hdr.types.locale_t ) @@ -277,6 +297,7 @@ add_entrypoint_object( HDRS isxdigit_l.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils libc.hdr.types.locale_t ) @@ -288,6 +309,7 @@ add_entrypoint_object( HDRS tolower_l.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils libc.hdr.types.locale_t ) @@ -299,6 +321,7 @@ add_entrypoint_object( HDRS toupper_l.h DEPENDS + libc.src.__support.CPP.limits libc.src.__support.ctype_utils libc.hdr.types.locale_t ) diff --git a/libc/src/ctype/isalnum.cpp b/libc/src/ctype/isalnum.cpp index 54a3e35748879..102b5e79e4a18 100644 --- a/libc/src/ctype/isalnum.cpp +++ b/libc/src/ctype/isalnum.cpp @@ -7,15 +7,18 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isalnum.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isalnum, (int c)) { - return static_cast(internal::isalnum(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::isalnum(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isalnum_l.cpp b/libc/src/ctype/isalnum_l.cpp index 671d9b75c4c33..173e1c174121e 100644 --- a/libc/src/ctype/isalnum_l.cpp +++ b/libc/src/ctype/isalnum_l.cpp @@ -7,15 +7,18 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isalnum_l.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isalnum_l, (int c, locale_t)) { - return static_cast(internal::isalnum(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::isalnum(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isalpha.cpp b/libc/src/ctype/isalpha.cpp index 78b26f6a486ea..7c874bf373866 100644 --- a/libc/src/ctype/isalpha.cpp +++ b/libc/src/ctype/isalpha.cpp @@ -8,6 +8,7 @@ #include "src/ctype/isalpha.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" #include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" @@ -15,7 +16,9 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isalpha, (int c)) { - return static_cast(internal::isalpha(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::isalpha(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isalpha_l.cpp b/libc/src/ctype/isalpha_l.cpp index 0619d979bedf2..982bcc569faaf 100644 --- a/libc/src/ctype/isalpha_l.cpp +++ b/libc/src/ctype/isalpha_l.cpp @@ -8,6 +8,7 @@ #include "src/ctype/isalpha_l.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" #include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" @@ -15,7 +16,9 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isalpha_l, (int c, locale_t)) { - return static_cast(internal::isalpha(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::isalpha(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isdigit.cpp b/libc/src/ctype/isdigit.cpp index 1f711943861f8..43553c794a2f3 100644 --- a/libc/src/ctype/isdigit.cpp +++ b/libc/src/ctype/isdigit.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isdigit.h" + +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" #include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" @@ -14,7 +16,9 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isdigit, (int c)) { - return static_cast(internal::isdigit(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::isdigit(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isdigit_l.cpp b/libc/src/ctype/isdigit_l.cpp index ca981362bfe83..40b5618906dac 100644 --- a/libc/src/ctype/isdigit_l.cpp +++ b/libc/src/ctype/isdigit_l.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isdigit_l.h" + +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" #include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" @@ -14,7 +16,9 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isdigit_l, (int c, locale_t)) { - return static_cast(internal::isdigit(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::isdigit(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isgraph.cpp b/libc/src/ctype/isgraph.cpp index 74bb2e75d138e..b9308ecb7367c 100644 --- a/libc/src/ctype/isgraph.cpp +++ b/libc/src/ctype/isgraph.cpp @@ -8,6 +8,7 @@ #include "src/ctype/isgraph.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" #include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" @@ -15,7 +16,9 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isgraph, (int c)) { - return static_cast(internal::isgraph(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::isgraph(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isgraph_l.cpp b/libc/src/ctype/isgraph_l.cpp index cbef6df148aed..dddcb9be4f80c 100644 --- a/libc/src/ctype/isgraph_l.cpp +++ b/libc/src/ctype/isgraph_l.cpp @@ -8,6 +8,7 @@ #include "src/ctype/isgraph_l.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" #include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" @@ -15,7 +16,9 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isgraph_l, (int c, locale_t)) { - return static_cast(internal::isgraph(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::isgraph(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/islower.cpp b/libc/src/ctype/islower.cpp index 831aad32d3a22..920bfc1cc1a59 100644 --- a/libc/src/ctype/islower.cpp +++ b/libc/src/ctype/islower.cpp @@ -7,15 +7,18 @@ //===----------------------------------------------------------------------===// #include "src/ctype/islower.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, islower, (int c)) { - return static_cast(internal::islower(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::islower(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/islower_l.cpp b/libc/src/ctype/islower_l.cpp index b9be6acc81c99..da97026dc59a7 100644 --- a/libc/src/ctype/islower_l.cpp +++ b/libc/src/ctype/islower_l.cpp @@ -7,15 +7,18 @@ //===----------------------------------------------------------------------===// #include "src/ctype/islower_l.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, islower_l, (int c, locale_t)) { - return static_cast(internal::islower(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::islower(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/ispunct.cpp b/libc/src/ctype/ispunct.cpp index 0635294220b9c..4950036e9b81f 100644 --- a/libc/src/ctype/ispunct.cpp +++ b/libc/src/ctype/ispunct.cpp @@ -8,6 +8,7 @@ #include "src/ctype/ispunct.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" #include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" @@ -15,7 +16,9 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, ispunct, (int c)) { - const unsigned ch = static_cast(c); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + const char ch = static_cast(c); return static_cast(!internal::isalnum(ch) && internal::isgraph(ch)); } diff --git a/libc/src/ctype/ispunct_l.cpp b/libc/src/ctype/ispunct_l.cpp index e825fbe2001b0..79cd47b6a214d 100644 --- a/libc/src/ctype/ispunct_l.cpp +++ b/libc/src/ctype/ispunct_l.cpp @@ -8,6 +8,7 @@ #include "src/ctype/ispunct_l.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" #include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" @@ -15,7 +16,9 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, ispunct_l, (int c, locale_t)) { - const unsigned ch = static_cast(c); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + const char ch = static_cast(c); return static_cast(!internal::isalnum(ch) && internal::isgraph(ch)); } diff --git a/libc/src/ctype/isspace.cpp b/libc/src/ctype/isspace.cpp index 005bf460fc103..998dbf28f51d0 100644 --- a/libc/src/ctype/isspace.cpp +++ b/libc/src/ctype/isspace.cpp @@ -7,15 +7,18 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isspace.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isspace, (int c)) { - return static_cast(internal::isspace(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::isspace(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isspace_l.cpp b/libc/src/ctype/isspace_l.cpp index 5c46dd6805126..e40765326b35e 100644 --- a/libc/src/ctype/isspace_l.cpp +++ b/libc/src/ctype/isspace_l.cpp @@ -7,15 +7,18 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isspace_l.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isspace_l, (int c, locale_t)) { - return static_cast(internal::isspace(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::isspace(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isupper.cpp b/libc/src/ctype/isupper.cpp index 965fa336b28b4..c5c3dbd5d7d4a 100644 --- a/libc/src/ctype/isupper.cpp +++ b/libc/src/ctype/isupper.cpp @@ -7,15 +7,18 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isupper.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isupper, (int c)) { - return static_cast(internal::isupper(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::isupper(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isupper_l.cpp b/libc/src/ctype/isupper_l.cpp index 358990261d603..44ed9dab90a16 100644 --- a/libc/src/ctype/isupper_l.cpp +++ b/libc/src/ctype/isupper_l.cpp @@ -7,15 +7,18 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isupper_l.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isupper_l, (int c, locale_t)) { - return static_cast(internal::isupper(static_cast(c))); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + return static_cast(internal::isupper(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/isxdigit.cpp b/libc/src/ctype/isxdigit.cpp index 81f645c6f49fc..1b2e71769b3f8 100644 --- a/libc/src/ctype/isxdigit.cpp +++ b/libc/src/ctype/isxdigit.cpp @@ -7,15 +7,18 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isxdigit.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isxdigit, (int c)) { - const unsigned ch = static_cast(c); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + const char ch = static_cast(c); return static_cast(internal::isalnum(ch) && internal::b36_char_to_int(ch) < 16); } diff --git a/libc/src/ctype/isxdigit_l.cpp b/libc/src/ctype/isxdigit_l.cpp index eddfd20a2da3b..e6150473b0043 100644 --- a/libc/src/ctype/isxdigit_l.cpp +++ b/libc/src/ctype/isxdigit_l.cpp @@ -7,15 +7,18 @@ //===----------------------------------------------------------------------===// #include "src/ctype/isxdigit_l.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, isxdigit_l, (int c, locale_t)) { - const unsigned ch = static_cast(c); + if (c < 0 || c > cpp::numeric_limits::max()) + return 0; + const char ch = static_cast(c); return static_cast(internal::isalnum(ch) && internal::b36_char_to_int(ch) < 16); } diff --git a/libc/src/ctype/tolower.cpp b/libc/src/ctype/tolower.cpp index 3ecad7bc5d5d5..b45c5f2688a61 100644 --- a/libc/src/ctype/tolower.cpp +++ b/libc/src/ctype/tolower.cpp @@ -7,13 +7,20 @@ //===----------------------------------------------------------------------===// #include "src/ctype/tolower.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { -LLVM_LIBC_FUNCTION(int, tolower, (int c)) { return internal::tolower(c); } +LLVM_LIBC_FUNCTION(int, tolower, (int c)) { + if (c < cpp::numeric_limits::min() || + c > cpp::numeric_limits::max()) { + return c; + } + return static_cast(internal::tolower(static_cast(c))); +} } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/tolower_l.cpp b/libc/src/ctype/tolower_l.cpp index 7ccf31617e592..049e46aea13c0 100644 --- a/libc/src/ctype/tolower_l.cpp +++ b/libc/src/ctype/tolower_l.cpp @@ -7,15 +7,20 @@ //===----------------------------------------------------------------------===// #include "src/ctype/tolower_l.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, tolower_l, (int c, locale_t)) { - return internal::tolower(c); + if (c < cpp::numeric_limits::min() || + c > cpp::numeric_limits::max()) { + return c; + } + return static_cast(internal::tolower(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/toupper.cpp b/libc/src/ctype/toupper.cpp index 1e1e8fc400711..0e387238ce3b6 100644 --- a/libc/src/ctype/toupper.cpp +++ b/libc/src/ctype/toupper.cpp @@ -7,13 +7,20 @@ //===----------------------------------------------------------------------===// #include "src/ctype/toupper.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { -LLVM_LIBC_FUNCTION(int, toupper, (int c)) { return internal::toupper(c); } +LLVM_LIBC_FUNCTION(int, toupper, (int c)) { + if (c < cpp::numeric_limits::min() || + c > cpp::numeric_limits::max()) { + return c; + } + return static_cast(internal::toupper(static_cast(c))); +} } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/ctype/toupper_l.cpp b/libc/src/ctype/toupper_l.cpp index a435ca1ab5d41..d1dff262c9377 100644 --- a/libc/src/ctype/toupper_l.cpp +++ b/libc/src/ctype/toupper_l.cpp @@ -7,15 +7,20 @@ //===----------------------------------------------------------------------===// #include "src/ctype/toupper_l.h" -#include "src/__support/ctype_utils.h" +#include "src/__support/CPP/limits.h" #include "src/__support/common.h" +#include "src/__support/ctype_utils.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, toupper_l, (int c, locale_t)) { - return internal::toupper(c); + if (c < cpp::numeric_limits::min() || + c > cpp::numeric_limits::max()) { + return c; + } + return static_cast(internal::toupper(static_cast(c))); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdio/printf_core/float_dec_converter_limited.h b/libc/src/stdio/printf_core/float_dec_converter_limited.h index 9cdc13573d320..0f85d0a8d26b4 100644 --- a/libc/src/stdio/printf_core/float_dec_converter_limited.h +++ b/libc/src/stdio/printf_core/float_dec_converter_limited.h @@ -363,8 +363,8 @@ DigitsOutput decimal_digits(DigitsInput input, int precision, bool e_mode) { // we made it from and doing the decimal conversion all over again.) for (size_t i = output.ndigits; i-- > 0;) { if (output.digits[i] != '9') { - output.digits[i] = static_cast(internal::int_to_b36_char( - internal::b36_char_to_int(output.digits[i]) + 1)); + output.digits[i] = internal::int_to_b36_char( + internal::b36_char_to_int(output.digits[i]) + 1); break; } else { output.digits[i] = '0'; diff --git a/libc/src/stdio/printf_core/float_hex_converter.h b/libc/src/stdio/printf_core/float_hex_converter.h index 16592e7bac932..9b57f1d803e74 100644 --- a/libc/src/stdio/printf_core/float_hex_converter.h +++ b/libc/src/stdio/printf_core/float_hex_converter.h @@ -137,9 +137,9 @@ LIBC_INLINE int convert_float_hex_exp(Writer *writer, size_t first_non_zero = 1; for (; mant_cur > 0; --mant_cur, mantissa >>= 4) { char mant_mod_16 = static_cast(mantissa % 16); - char new_digit = static_cast(internal::int_to_b36_char(mant_mod_16)); + char new_digit = internal::int_to_b36_char(mant_mod_16); if (internal::isupper(to_conv.conv_name)) - new_digit = static_cast(internal::toupper(new_digit)); + new_digit = internal::toupper(new_digit); mant_buffer[mant_cur - 1] = new_digit; if (new_digit != '0' && first_non_zero < mant_cur) first_non_zero = mant_cur; @@ -167,8 +167,7 @@ LIBC_INLINE int convert_float_hex_exp(Writer *writer, size_t exp_cur = EXP_LEN; for (; exponent > 0; --exp_cur, exponent /= 10) { - exp_buffer[exp_cur - 1] = - static_cast(internal::int_to_b36_char(exponent % 10)); + exp_buffer[exp_cur - 1] = internal::int_to_b36_char(exponent % 10); } if (exp_cur == EXP_LEN) { // if nothing else was written, write a 0. exp_buffer[EXP_LEN - 1] = '0'; diff --git a/libc/src/stdlib/l64a.cpp b/libc/src/stdlib/l64a.cpp index d59e65e7dc4c2..d8fe8ef86bf7d 100644 --- a/libc/src/stdlib/l64a.cpp +++ b/libc/src/stdlib/l64a.cpp @@ -32,15 +32,13 @@ constexpr static char b64_int_to_char(uint32_t num) { if (num == 1) return '/'; if (num < 38) - return static_cast( - internal::toupper(internal::int_to_b36_char(num - 2))); + return internal::toupper(internal::int_to_b36_char(num - 2)); // this tolower is technically unnecessary, but it provides safety if we // change the default behavior of int_to_b36_char. Also the compiler // completely elides it so there's no performance penalty, see: // https://godbolt.org/z/o5ennv7fc - return static_cast( - internal::tolower(internal::int_to_b36_char(num - 2 - 26))); + return internal::tolower(internal::int_to_b36_char(num - 2 - 26)); } // This function takes a long and converts the low 32 bits of it into at most 6 diff --git a/libc/src/string/strcasestr.cpp b/libc/src/string/strcasestr.cpp index de8e4bec7fe0b..575d6bed16d11 100644 --- a/libc/src/string/strcasestr.cpp +++ b/libc/src/string/strcasestr.cpp @@ -21,8 +21,8 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(char *, strcasestr, (const char *haystack, const char *needle)) { auto case_cmp = [](char a, char b) { - return LIBC_NAMESPACE::internal::tolower(a) - - LIBC_NAMESPACE::internal::tolower(b); + return static_cast(LIBC_NAMESPACE::internal::tolower(a)) - + static_cast(LIBC_NAMESPACE::internal::tolower(b)); }; LIBC_CRASH_ON_NULLPTR(haystack); diff --git a/libc/src/strings/strcasecmp.cpp b/libc/src/strings/strcasecmp.cpp index 4bbe2909df1e2..4518647deabe4 100644 --- a/libc/src/strings/strcasecmp.cpp +++ b/libc/src/strings/strcasecmp.cpp @@ -17,8 +17,8 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, strcasecmp, (const char *left, const char *right)) { auto case_cmp = [](char a, char b) { - return LIBC_NAMESPACE::internal::tolower(a) - - LIBC_NAMESPACE::internal::tolower(b); + return static_cast(LIBC_NAMESPACE::internal::tolower(a)) - + static_cast(LIBC_NAMESPACE::internal::tolower(b)); }; return inline_strcmp(left, right, case_cmp); } diff --git a/libc/src/strings/strcasecmp_l.cpp b/libc/src/strings/strcasecmp_l.cpp index 95117cb27a564..d77f95637a396 100644 --- a/libc/src/strings/strcasecmp_l.cpp +++ b/libc/src/strings/strcasecmp_l.cpp @@ -18,8 +18,8 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, strcasecmp_l, (const char *left, const char *right, locale_t)) { auto case_cmp = [](char a, char b) { - return LIBC_NAMESPACE::internal::tolower(a) - - LIBC_NAMESPACE::internal::tolower(b); + return static_cast(LIBC_NAMESPACE::internal::tolower(a)) - + static_cast(LIBC_NAMESPACE::internal::tolower(b)); }; return inline_strcmp(left, right, case_cmp); } diff --git a/libc/src/strings/strncasecmp.cpp b/libc/src/strings/strncasecmp.cpp index 9c2f0ab131269..a5926495a3e22 100644 --- a/libc/src/strings/strncasecmp.cpp +++ b/libc/src/strings/strncasecmp.cpp @@ -18,8 +18,8 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, strncasecmp, (const char *left, const char *right, size_t n)) { auto case_cmp = [](char a, char b) { - return LIBC_NAMESPACE::internal::tolower(a) - - LIBC_NAMESPACE::internal::tolower(b); + return static_cast(LIBC_NAMESPACE::internal::tolower(a)) - + static_cast(LIBC_NAMESPACE::internal::tolower(b)); }; return inline_strncmp(left, right, n, case_cmp); } diff --git a/libc/src/strings/strncasecmp_l.cpp b/libc/src/strings/strncasecmp_l.cpp index 91ac7e5e89107..a828f609fd9e8 100644 --- a/libc/src/strings/strncasecmp_l.cpp +++ b/libc/src/strings/strncasecmp_l.cpp @@ -18,8 +18,8 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, strncasecmp_l, (const char *left, const char *right, size_t n, locale_t)) { auto case_cmp = [](char a, char b) { - return LIBC_NAMESPACE::internal::tolower(a) - - LIBC_NAMESPACE::internal::tolower(b); + return static_cast(LIBC_NAMESPACE::internal::tolower(a)) - + static_cast(LIBC_NAMESPACE::internal::tolower(b)); }; return inline_strncmp(left, right, n, case_cmp); } diff --git a/libc/test/UnitTest/MemoryMatcher.cpp b/libc/test/UnitTest/MemoryMatcher.cpp index 6e375768e9333..405f226798f7a 100644 --- a/libc/test/UnitTest/MemoryMatcher.cpp +++ b/libc/test/UnitTest/MemoryMatcher.cpp @@ -41,8 +41,8 @@ bool MemoryMatcher::match(MemoryView actualValue) { static void display(char C) { const auto print = [](unsigned char i) { - tlog << static_cast(LIBC_NAMESPACE::internal::toupper( - LIBC_NAMESPACE::internal::int_to_b36_char(i))); + tlog << LIBC_NAMESPACE::internal::toupper( + LIBC_NAMESPACE::internal::int_to_b36_char(i)); }; print(static_cast(C) / 16); print(static_cast(C) & 15); diff --git a/libc/test/src/ctype/islower_test.cpp b/libc/test/src/ctype/islower_test.cpp index f877171abb9a3..e4e5f5cefd954 100644 --- a/libc/test/src/ctype/islower_test.cpp +++ b/libc/test/src/ctype/islower_test.cpp @@ -40,7 +40,7 @@ TEST(LlvmLibcIsLower, SimpleTest) { } TEST(LlvmLibcIsLower, DefaultLocale) { - // Loops through all characters, verifying that numbers and letters + // Loops through all characters, verifying that only lowercase letters // return non-zero integer and everything else returns a zero. for (int ch = -255; ch < 255; ++ch) { if (in_span(ch, LOWER_ARRAY)) diff --git a/libc/test/src/stdlib/StrtolTest.h b/libc/test/src/stdlib/StrtolTest.h index 03f0a6539c785..3a7da1fa85ac7 100644 --- a/libc/test/src/stdlib/StrtolTest.h +++ b/libc/test/src/stdlib/StrtolTest.h @@ -177,8 +177,8 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::ErrnoCheckingTest { char small_string[4] = {'\0', '\0', '\0', '\0'}; for (int base = 2; base <= 36; ++base) { for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = static_cast( - LIBC_NAMESPACE::internal::int_to_b36_char(first_digit)); + small_string[0] = + LIBC_NAMESPACE::internal::int_to_b36_char(first_digit); if (first_digit < base) { ASSERT_EQ(func(small_string, nullptr, base), static_cast(first_digit)); @@ -192,11 +192,11 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::ErrnoCheckingTest { for (int base = 2; base <= 36; ++base) { for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = static_cast( - LIBC_NAMESPACE::internal::int_to_b36_char(first_digit)); + small_string[0] = + LIBC_NAMESPACE::internal::int_to_b36_char(first_digit); for (int second_digit = 0; second_digit <= 36; ++second_digit) { - small_string[1] = static_cast( - LIBC_NAMESPACE::internal::int_to_b36_char(second_digit)); + small_string[1] = + LIBC_NAMESPACE::internal::int_to_b36_char(second_digit); if (first_digit < base && second_digit < base) { ASSERT_EQ( func(small_string, nullptr, base), @@ -216,14 +216,14 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::ErrnoCheckingTest { for (int base = 2; base <= 36; ++base) { for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = static_cast( - LIBC_NAMESPACE::internal::int_to_b36_char(first_digit)); + small_string[0] = + LIBC_NAMESPACE::internal::int_to_b36_char(first_digit); for (int second_digit = 0; second_digit <= 36; ++second_digit) { - small_string[1] = static_cast( - LIBC_NAMESPACE::internal::int_to_b36_char(second_digit)); + small_string[1] = + LIBC_NAMESPACE::internal::int_to_b36_char(second_digit); for (int third_digit = 0; third_digit <= limit; ++third_digit) { - small_string[2] = static_cast( - LIBC_NAMESPACE::internal::int_to_b36_char(third_digit)); + small_string[2] = + LIBC_NAMESPACE::internal::int_to_b36_char(third_digit); if (first_digit < base && second_digit < base && third_digit < base) { diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 5a1e0b53b021c..fde68d1b910f4 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -1859,6 +1859,7 @@ libc_function( hdrs = ["src/ctype/isalnum.h"], deps = [ ":__support_common", + ":__support_cpp_limits", ":__support_ctype_utils", ], ) @@ -1869,6 +1870,7 @@ libc_function( hdrs = ["src/ctype/isalpha.h"], deps = [ ":__support_common", + ":__support_cpp_limits", ":__support_ctype_utils", ], ) @@ -1909,6 +1911,7 @@ libc_function( hdrs = ["src/ctype/isdigit.h"], deps = [ ":__support_common", + ":__support_cpp_limits", ":__support_ctype_utils", ], ) @@ -1919,6 +1922,7 @@ libc_function( hdrs = ["src/ctype/isgraph.h"], deps = [ ":__support_common", + ":__support_cpp_limits", ":__support_ctype_utils", ], ) @@ -1929,6 +1933,7 @@ libc_function( hdrs = ["src/ctype/islower.h"], deps = [ ":__support_common", + ":__support_cpp_limits", ":__support_ctype_utils", ], ) @@ -1949,6 +1954,7 @@ libc_function( hdrs = ["src/ctype/ispunct.h"], deps = [ ":__support_common", + ":__support_cpp_limits", ":__support_ctype_utils", ], ) @@ -1959,6 +1965,7 @@ libc_function( hdrs = ["src/ctype/isspace.h"], deps = [ ":__support_common", + ":__support_cpp_limits", ":__support_ctype_utils", ], ) @@ -1969,6 +1976,7 @@ libc_function( hdrs = ["src/ctype/isupper.h"], deps = [ ":__support_common", + ":__support_cpp_limits", ":__support_ctype_utils", ], ) @@ -1979,6 +1987,7 @@ libc_function( hdrs = ["src/ctype/isxdigit.h"], deps = [ ":__support_common", + ":__support_cpp_limits", ":__support_ctype_utils", ], ) @@ -1999,6 +2008,7 @@ libc_function( hdrs = ["src/ctype/tolower.h"], deps = [ ":__support_common", + ":__support_cpp_limits", ":__support_ctype_utils", ], ) @@ -2009,6 +2019,7 @@ libc_function( hdrs = ["src/ctype/toupper.h"], deps = [ ":__support_common", + ":__support_cpp_limits", ":__support_ctype_utils", ], )