[libc] clean up ctype negative handling

The ctype functions will sometimes be passed negative numbers, such as
EOF. Some of the previous implementations didn't handle these properly.
Additionally, the tests did not check any negative numbers. These
problems have been fixed.

This patch fixes https://github.com/llvm/llvm-project/issues/62000

Reviewed By: lntue

Differential Revision: https://reviews.llvm.org/D147813
This commit is contained in:
Michael Jones 2023-04-07 14:02:39 -07:00
parent 711b70d77e
commit 26f1770e53
19 changed files with 36 additions and 37 deletions

View File

@ -15,8 +15,7 @@ namespace __llvm_libc {
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
LLVM_LIBC_FUNCTION(int, isblank, (int c)) {
const unsigned char ch = static_cast<unsigned char>(c);
return static_cast<int>(ch == ' ' || ch == '\t');
return static_cast<int>(c == ' ' || c == '\t');
}
} // namespace __llvm_libc

View File

@ -15,7 +15,7 @@ namespace __llvm_libc {
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
LLVM_LIBC_FUNCTION(int, iscntrl, (int c)) {
const unsigned char ch = static_cast<unsigned char>(c);
const unsigned ch = static_cast<unsigned>(c);
return static_cast<int>(ch < 0x20 || ch == 0x7f);
}

View File

@ -1,7 +1,7 @@
add_libc_testsuite(libc_ctype_unittests)
add_libc_unittest(
isalnum
isalnum_test
SUITE
libc_ctype_unittests
SRCS
@ -11,7 +11,7 @@ add_libc_unittest(
)
add_libc_unittest(
isalpha
isalpha_test
SUITE
libc_ctype_unittests
SRCS
@ -21,7 +21,7 @@ add_libc_unittest(
)
add_libc_unittest(
isascii
isascii_test
SUITE
libc_ctype_unittests
SRCS
@ -31,7 +31,7 @@ add_libc_unittest(
)
add_libc_unittest(
isblank
isblank_test
SUITE
libc_ctype_unittests
SRCS
@ -41,7 +41,7 @@ add_libc_unittest(
)
add_libc_unittest(
iscntrl
iscntrl_test
SUITE
libc_ctype_unittests
SRCS
@ -51,7 +51,7 @@ add_libc_unittest(
)
add_libc_unittest(
isdigit
isdigit_test
SUITE
libc_ctype_unittests
SRCS
@ -61,7 +61,7 @@ add_libc_unittest(
)
add_libc_unittest(
isgraph
isgraph_test
SUITE
libc_ctype_unittests
SRCS
@ -71,7 +71,7 @@ add_libc_unittest(
)
add_libc_unittest(
islower
islower_test
SUITE
libc_ctype_unittests
SRCS
@ -81,7 +81,7 @@ add_libc_unittest(
)
add_libc_unittest(
isprint
isprint_test
SUITE
libc_ctype_unittests
SRCS
@ -91,7 +91,7 @@ add_libc_unittest(
)
add_libc_unittest(
ispunct
ispunct_test
SUITE
libc_ctype_unittests
SRCS
@ -101,7 +101,7 @@ add_libc_unittest(
)
add_libc_unittest(
isspace
isspace_test
SUITE
libc_ctype_unittests
SRCS
@ -111,7 +111,7 @@ add_libc_unittest(
)
add_libc_unittest(
isupper
isupper_test
SUITE
libc_ctype_unittests
SRCS
@ -121,7 +121,7 @@ add_libc_unittest(
)
add_libc_unittest(
isxdigit
isxdigit_test
SUITE
libc_ctype_unittests
SRCS
@ -131,7 +131,7 @@ add_libc_unittest(
)
add_libc_unittest(
toascii
toascii_test
SUITE
libc_ctype_unittests
SRCS
@ -141,7 +141,7 @@ add_libc_unittest(
)
add_libc_unittest(
tolower
tolower_test
SUITE
libc_ctype_unittests
SRCS
@ -151,7 +151,7 @@ add_libc_unittest(
)
add_libc_unittest(
toupper
toupper_test
SUITE
libc_ctype_unittests
SRCS

View File

@ -13,7 +13,7 @@
TEST(LlvmLibcIsAlNum, DefaultLocale) {
// Loops through all characters, verifying that numbers and letters
// return non-zero integer and everything else returns a zero.
for (int c = 0; c < 255; ++c) {
for (int c = -255; c < 255; ++c) {
if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') ||
('0' <= c && c <= '9'))
EXPECT_NE(__llvm_libc::isalnum(c), 0);

View File

@ -13,7 +13,7 @@
TEST(LlvmLibcIsAlpha, DefaultLocale) {
// Loops through all characters, verifying that letters return a
// non-zero integer and everything else returns zero.
for (int ch = 0; ch < 255; ++ch) {
for (int ch = -255; ch < 255; ++ch) {
if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z'))
EXPECT_NE(__llvm_libc::isalpha(ch), 0);
else

View File

@ -14,8 +14,8 @@ TEST(LlvmLibcIsAscii, DefaultLocale) {
// Loops through all characters, verifying that ascii characters
// (which are all 7 bit unsigned integers)
// return a non-zero integer and everything else returns zero.
for (int ch = 0; ch < 255; ++ch) {
if (ch <= 0x7f)
for (int ch = -255; ch < 255; ++ch) {
if (0 <= ch && ch <= 0x7f)
EXPECT_NE(__llvm_libc::isascii(ch), 0);
else
EXPECT_EQ(__llvm_libc::isascii(ch), 0);

View File

@ -12,7 +12,7 @@
TEST(LlvmLibcIsBlank, DefaultLocale) {
// Loops through all characters, verifying that space and horizontal tab
// return a non-zero integer and everything else returns zero.
for (int ch = 0; ch < 255; ++ch) {
for (int ch = -255; ch < 255; ++ch) {
if (ch == ' ' || ch == '\t')
EXPECT_NE(__llvm_libc::isblank(ch), 0);
else

View File

@ -12,7 +12,7 @@
TEST(LlvmLibcIsCntrl, DefaultLocale) {
// Loops through all characters, verifying that control characters
// return a non-zero integer, all others return zero.
for (int ch = 0; ch < 255; ++ch) {
for (int ch = -255; ch < 255; ++ch) {
if ((0 <= ch && ch <= 0x1f /*US*/) || ch == 0x7f /*DEL*/)
EXPECT_NE(__llvm_libc::iscntrl(ch), 0);
else

View File

@ -13,7 +13,7 @@
TEST(LlvmLibcIsDigit, DefaultLocale) {
// Loops through all characters, verifying that numbers return a
// non-zero integer and everything else returns zero.
for (int ch = 0; ch < 255; ++ch) {
for (int ch = -255; ch < 255; ++ch) {
if ('0' <= ch && ch <= '9')
EXPECT_NE(__llvm_libc::isdigit(ch), 0);
else

View File

@ -12,7 +12,7 @@
TEST(LlvmLibcIsGraph, DefaultLocale) {
// Loops through all characters, verifying that graphical characters
// return a non-zero integer, everything else returns zero.
for (int ch = 0; ch < 255; ++ch) {
for (int ch = -255; ch < 255; ++ch) {
if ('!' <= ch && ch <= '~') // A-Z, a-z, 0-9, punctuation.
EXPECT_NE(__llvm_libc::isgraph(ch), 0);
else

View File

@ -12,7 +12,7 @@
TEST(LlvmLibcIsLower, DefaultLocale) {
// Loops through all characters, verifying that lowercase letters
// return a non-zero integer and everything else returns zero.
for (int ch = 0; ch < 255; ++ch) {
for (int ch = -255; ch < 255; ++ch) {
if ('a' <= ch && ch <= 'z')
EXPECT_NE(__llvm_libc::islower(ch), 0);
else

View File

@ -10,7 +10,7 @@
#include "test/UnitTest/Test.h"
TEST(LlvmLibcIsPrint, DefaultLocale) {
for (int ch = 0; ch < 255; ++ch) {
for (int ch = -255; ch < 255; ++ch) {
if (' ' <= ch && ch <= '~') // A-Z, a-z, 0-9, punctuation, space.
EXPECT_NE(__llvm_libc::isprint(ch), 0);
else

View File

@ -25,7 +25,7 @@ static inline int is_punctuation_character(int c) {
TEST(LlvmLibcIsPunct, DefaultLocale) {
// Loops through all characters, verifying that punctuation characters
// return a non-zero integer, and everything else returns zero.
for (int ch = 0; ch < 255; ++ch) {
for (int ch = -255; ch < 255; ++ch) {
if (is_punctuation_character(ch))
EXPECT_NE(__llvm_libc::ispunct(ch), 0);
else

View File

@ -19,7 +19,7 @@ TEST(LlvmLibcIsSpace, DefaultLocale) {
// 0x0b | vertical tab
// 0x0d | carriage return
// 0x20 | space
for (int ch = 0; ch < 255; ++ch) {
for (int ch = -255; ch < 255; ++ch) {
if (ch == 0x20 || (0x09 <= ch && ch <= 0x0d))
EXPECT_NE(__llvm_libc::isspace(ch), 0);
else

View File

@ -12,7 +12,7 @@
TEST(LlvmLibcIsUpper, DefaultLocale) {
// Loops through all characters, verifying that uppercase letters
// return a non-zero integer and everything else returns zero.
for (int ch = 0; ch < 255; ++ch) {
for (int ch = -255; ch < 255; ++ch) {
if ('A' <= ch && ch <= 'Z')
EXPECT_NE(__llvm_libc::isupper(ch), 0);
else

View File

@ -10,7 +10,7 @@
#include "test/UnitTest/Test.h"
TEST(LlvmLibcIsXDigit, DefaultLocale) {
for (int ch = 0; ch < 255; ++ch) {
for (int ch = -255; ch < 255; ++ch) {
if (('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f') ||
('A' <= ch && ch <= 'F'))
EXPECT_NE(__llvm_libc::isxdigit(ch), 0);

View File

@ -15,8 +15,8 @@ TEST(LlvmLibcToAscii, DefaultLocale) {
// (which are all 7 bit unsigned integers)
// return themself, and that all other characters return themself
// mod 128 (which is equivalent to & 0x7f)
for (int ch = 0; ch < 255; ++ch) {
if (ch <= 0x7f)
for (int ch = -255; ch < 255; ++ch) {
if (0 <= ch && ch <= 0x7f)
EXPECT_EQ(__llvm_libc::toascii(ch), ch);
else
EXPECT_EQ(__llvm_libc::toascii(ch), ch & 0x7f);

View File

@ -10,7 +10,7 @@
#include "test/UnitTest/Test.h"
TEST(LlvmLibcToLower, DefaultLocale) {
for (int ch = 0; ch < 255; ++ch) {
for (int ch = -255; ch < 255; ++ch) {
// This follows pattern 'A' + 32 = 'a'.
if ('A' <= ch && ch <= 'Z')
EXPECT_EQ(__llvm_libc::tolower(ch), ch + 32);

View File

@ -10,7 +10,7 @@
#include "test/UnitTest/Test.h"
TEST(LlvmLibcToUpper, DefaultLocale) {
for (int ch = 0; ch < 255; ++ch) {
for (int ch = -255; ch < 255; ++ch) {
// This follows pattern 'a' - 32 = 'A'.
if ('a' <= ch && ch <= 'z')
EXPECT_EQ(__llvm_libc::toupper(ch), ch - 32);