[libc] clean up ctype negative handling
authorMichael Jones <michaelrj@google.com>
Fri, 7 Apr 2023 21:02:39 +0000 (14:02 -0700)
committerMichael Jones <michaelrj@google.com>
Mon, 10 Apr 2023 17:00:22 +0000 (10:00 -0700)
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

19 files changed:
libc/src/ctype/isblank.cpp
libc/src/ctype/iscntrl.cpp
libc/test/src/ctype/CMakeLists.txt
libc/test/src/ctype/isalnum_test.cpp
libc/test/src/ctype/isalpha_test.cpp
libc/test/src/ctype/isascii_test.cpp
libc/test/src/ctype/isblank_test.cpp
libc/test/src/ctype/iscntrl_test.cpp
libc/test/src/ctype/isdigit_test.cpp
libc/test/src/ctype/isgraph_test.cpp
libc/test/src/ctype/islower_test.cpp
libc/test/src/ctype/isprint_test.cpp
libc/test/src/ctype/ispunct_test.cpp
libc/test/src/ctype/isspace_test.cpp
libc/test/src/ctype/isupper_test.cpp
libc/test/src/ctype/isxdigit_test.cpp
libc/test/src/ctype/toascii_test.cpp
libc/test/src/ctype/tolower_test.cpp
libc/test/src/ctype/toupper_test.cpp

index eed838c..438eff7 100644 (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
index 6c471a5..b203e4e 100644 (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);
 }
 
index 83ae6be..eadec22 100644 (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
index 1cf5e6f..d44263a 100644 (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);
index 3fccaf6..916aae3 100644 (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
index ba45050..80b0b1c 100644 (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);
index 85ea038..f34e0cb 100644 (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
index 9398ad0..89b0c9a 100644 (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
index ae73418..fd49475 100644 (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
index 51e376c..7c3ed36 100644 (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
index 81d213e..c399cc4 100644 (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
index 4fed40b..d7278fa 100644 (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
index dddba47..3b82e19 100644 (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
index 9bfac1c..9777bb2 100644 (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
index 0d0ff1e..5407c76 100644 (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
index 64a0e05..b98d3bd 100644 (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);
index 88f862a..d5dde8c 100644 (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);
index dc184c8..2c2b7d9 100644 (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);
index 402c742..d0879d4 100644 (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);