diff options
Diffstat (limited to 'libc')
| -rw-r--r-- | libc/src/string/string_utils.h | 18 | ||||
| -rw-r--r-- | libc/test/src/stdlib/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | libc/test/src/stdlib/StrfromTest.h | 4 | ||||
| -rw-r--r-- | libc/test/src/string/memchr_test.cpp | 5 |
4 files changed, 19 insertions, 9 deletions
diff --git a/libc/src/string/string_utils.h b/libc/src/string/string_utils.h index 7feef56..cbce62e 100644 --- a/libc/src/string/string_utils.h +++ b/libc/src/string/string_utils.h @@ -127,8 +127,8 @@ find_first_character_wide_read(const unsigned char *src, unsigned char ch, size_t cur = 0; // Step 1: read 1 byte at a time to align to block size - for (; reinterpret_cast<uintptr_t>(char_ptr) % sizeof(Word) != 0 && cur < n; - ++char_ptr, ++cur) { + for (; cur < n && reinterpret_cast<uintptr_t>(char_ptr) % sizeof(Word) != 0; + ++cur, ++char_ptr) { if (*char_ptr == ch) return const_cast<unsigned char *>(char_ptr); } @@ -136,18 +136,18 @@ find_first_character_wide_read(const unsigned char *src, unsigned char ch, const Word ch_mask = repeat_byte<Word>(ch); // Step 2: read blocks - for (const Word *block_ptr = reinterpret_cast<const Word *>(char_ptr); - !has_zeroes<Word>((*block_ptr) ^ ch_mask) && cur < n; - ++block_ptr, cur += sizeof(Word)) { - char_ptr = reinterpret_cast<const unsigned char *>(block_ptr); - } + const Word *block_ptr = reinterpret_cast<const Word *>(char_ptr); + for (; cur < n && !has_zeroes<Word>((*block_ptr) ^ ch_mask); + cur += sizeof(Word), ++block_ptr) + ; + char_ptr = reinterpret_cast<const unsigned char *>(block_ptr); // Step 3: find the match in the block - for (; *char_ptr != ch && cur < n; ++char_ptr, ++cur) { + for (; cur < n && *char_ptr != ch; ++cur, ++char_ptr) { ; } - if (*char_ptr != ch || cur >= n) + if (cur >= n || *char_ptr != ch) return static_cast<void *>(nullptr); return const_cast<unsigned char *>(char_ptr); diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt index 0eb373c..42e8faa 100644 --- a/libc/test/src/stdlib/CMakeLists.txt +++ b/libc/test/src/stdlib/CMakeLists.txt @@ -187,6 +187,7 @@ add_header_library( DEPENDS libc.src.__support.CPP.type_traits libc.src.__support.FPUtil.fp_bits + libc.src.__support.macros.properties.architectures ) add_libc_test( diff --git a/libc/test/src/stdlib/StrfromTest.h b/libc/test/src/stdlib/StrfromTest.h index fd2e0f12..3dacfca 100644 --- a/libc/test/src/stdlib/StrfromTest.h +++ b/libc/test/src/stdlib/StrfromTest.h @@ -8,6 +8,7 @@ #include "src/__support/CPP/type_traits.h" #include "src/__support/FPUtil/FPBits.h" +#include "src/__support/macros/properties/architectures.h" #include "test/UnitTest/ErrnoCheckingTest.h" #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" @@ -484,7 +485,9 @@ public: ASSERT_STREQ_LEN(written, buff, "-NAN"); } + // https://github.com/llvm/llvm-project/issues/166795 void charsWrittenOverflow(FunctionT func) { +#ifndef LIBC_TARGET_ARCH_IS_RISCV32 char buff[100]; // Trigger an overflow in the return value of strfrom by writing more than // INT_MAX bytes. @@ -492,6 +495,7 @@ public: EXPECT_LT(result, 0); ASSERT_ERRNO_FAILURE(); +#endif } }; diff --git a/libc/test/src/string/memchr_test.cpp b/libc/test/src/string/memchr_test.cpp index ede8411..a92c5fe 100644 --- a/libc/test/src/string/memchr_test.cpp +++ b/libc/test/src/string/memchr_test.cpp @@ -21,6 +21,11 @@ const char *call_memchr(const void *src, int c, size_t size) { return reinterpret_cast<const char *>(LIBC_NAMESPACE::memchr(src, c, size)); } +TEST(LlvmLibcMemChrTest, WideReadMultiIteration) { + const char *src = "abcdefghijklmnopqrst$\n"; + ASSERT_STREQ(call_memchr(src, '$', 22), "$\n"); +} + TEST(LlvmLibcMemChrTest, FindsCharacterAfterNullTerminator) { // memchr should continue searching after a null terminator. const size_t size = 5; |
