aboutsummaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/src/string/string_utils.h18
-rw-r--r--libc/test/src/stdlib/CMakeLists.txt1
-rw-r--r--libc/test/src/stdlib/StrfromTest.h4
-rw-r--r--libc/test/src/string/memchr_test.cpp5
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;