diff --git a/libc/src/__support/common.h b/libc/src/__support/common.h index 53a63fc2e9173..b5cd66ae52ca9 100644 --- a/libc/src/__support/common.h +++ b/libc/src/__support/common.h @@ -24,9 +24,9 @@ LLVM_LIBC_FUNCTION_ATTR decltype(__llvm_libc::name) \ __##name##_impl__ __asm__(#name); \ decltype(__llvm_libc::name) name [[gnu::alias(#name)]]; \ - type __##name##_impl__ arglist + type __##name##_impl__ arglist noexcept #else -#define LLVM_LIBC_FUNCTION(type, name, arglist) type name arglist +#define LLVM_LIBC_FUNCTION(type, name, arglist) type name arglist noexcept #endif namespace __llvm_libc { diff --git a/libc/src/string/aarch64/memcmp.cpp b/libc/src/string/aarch64/memcmp.cpp index 503c239e122b7..e19371e3acae2 100644 --- a/libc/src/string/aarch64/memcmp.cpp +++ b/libc/src/string/aarch64/memcmp.cpp @@ -14,20 +14,21 @@ namespace __llvm_libc { namespace aarch64 { -static int memcmp_impl(const char *lhs, const char *rhs, size_t count) { +static int memcmp_impl(const char *lhs, const char *rhs, + size_t count) noexcept { if (count == 0) return 0; if (count == 1) return ThreeWayCompare<_1>(lhs, rhs); - else if (count == 2) + if (count == 2) return ThreeWayCompare<_2>(lhs, rhs); - else if (count == 3) + if (count == 3) return ThreeWayCompare<_3>(lhs, rhs); - else if (count < 8) + if (count < 8) return ThreeWayCompare>(lhs, rhs, count); - else if (count < 16) + if (count < 16) return ThreeWayCompare>(lhs, rhs, count); - else if (count < 128) { + if (count < 128) { if (Equals<_16>(lhs, rhs)) { if (count < 32) return ThreeWayCompare>(lhs, rhs, count); @@ -51,9 +52,8 @@ static int memcmp_impl(const char *lhs, const char *rhs, size_t count) { LLVM_LIBC_FUNCTION(int, memcmp, (const void *lhs, const void *rhs, size_t count)) { - const char *_lhs = reinterpret_cast(lhs); - const char *_rhs = reinterpret_cast(rhs); - return aarch64::memcmp_impl(_lhs, _rhs, count); + return aarch64::memcmp_impl(reinterpret_cast(lhs), + reinterpret_cast(rhs), count); } } // namespace __llvm_libc diff --git a/libc/src/string/aarch64/memcpy.cpp b/libc/src/string/aarch64/memcpy.cpp index 1a1fbbc026a73..8af4f06d0151c 100644 --- a/libc/src/string/aarch64/memcpy.cpp +++ b/libc/src/string/aarch64/memcpy.cpp @@ -42,7 +42,7 @@ using _64 = Repeated; // with little change on the code side. // This implementation has been tuned for Neoverse-N1. static void memcpy_aarch64(char *__restrict dst, const char *__restrict src, - size_t count) { + size_t count) noexcept { if (count == 0) return; if (count == 1) diff --git a/libc/src/string/bzero.h b/libc/src/string/bzero.h index 064800bad29b5..ccb55d0431076 100644 --- a/libc/src/string/bzero.h +++ b/libc/src/string/bzero.h @@ -13,7 +13,7 @@ namespace __llvm_libc { -void bzero(void *ptr, size_t count); +void bzero(void *ptr, size_t count) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/memchr.cpp b/libc/src/string/memchr.cpp index 02b4016398414..a2a537680920d 100644 --- a/libc/src/string/memchr.cpp +++ b/libc/src/string/memchr.cpp @@ -17,7 +17,8 @@ namespace __llvm_libc { // TODO: Look at performance benefits of comparing words. LLVM_LIBC_FUNCTION(void *, memchr, (const void *src, int c, size_t n)) { return internal::find_first_character( - reinterpret_cast(src), c, n); + reinterpret_cast(src), + static_cast(c), n); } } // namespace __llvm_libc diff --git a/libc/src/string/memchr.h b/libc/src/string/memchr.h index 369475305236d..98246cb4ea032 100644 --- a/libc/src/string/memchr.h +++ b/libc/src/string/memchr.h @@ -13,7 +13,7 @@ namespace __llvm_libc { -void *memchr(const void *src, int c, size_t n); +void *memchr(const void *src, int c, size_t n) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/memcmp.h b/libc/src/string/memcmp.h index 1d79df5d45918..c90725f151084 100644 --- a/libc/src/string/memcmp.h +++ b/libc/src/string/memcmp.h @@ -13,7 +13,7 @@ namespace __llvm_libc { -int memcmp(const void *lhs, const void *rhs, size_t count); +int memcmp(const void *lhs, const void *rhs, size_t count) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/memcpy.cpp b/libc/src/string/memcpy.cpp index 5e70e00db1b91..329b8d4971245 100644 --- a/libc/src/string/memcpy.cpp +++ b/libc/src/string/memcpy.cpp @@ -31,7 +31,7 @@ namespace __llvm_libc { // - As compilers and processors get better, the generated code is improved // with little change on the code side. static void memcpy_impl(char *__restrict dst, const char *__restrict src, - size_t count) { + size_t count) noexcept { // Use scalar strategies (_1, _2, _3 ...) using namespace __llvm_libc::scalar; diff --git a/libc/src/string/memcpy.h b/libc/src/string/memcpy.h index f643f1de6294e..82c32984983a5 100644 --- a/libc/src/string/memcpy.h +++ b/libc/src/string/memcpy.h @@ -13,7 +13,7 @@ namespace __llvm_libc { -void *memcpy(void *__restrict, const void *__restrict, size_t); +void *memcpy(void *__restrict, const void *__restrict, size_t) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/memmove.cpp b/libc/src/string/memmove.cpp index ebbe4643e7da6..0a05b838a7352 100644 --- a/libc/src/string/memmove.cpp +++ b/libc/src/string/memmove.cpp @@ -15,22 +15,24 @@ namespace __llvm_libc { -static inline void move_byte_forward(char *dest_m, const char *src_m, - size_t count) { - for (size_t offset = 0; count; --count, ++offset) +static inline void move_byte_forward(unsigned char *dest_m, + const unsigned char *src_m, + size_t count) noexcept { + for (size_t offset = 0; offset != count; ++offset) dest_m[offset] = src_m[offset]; } -static inline void move_byte_backward(char *dest_m, const char *src_m, - size_t count) { - for (size_t offset = count - 1; count; --count, --offset) - dest_m[offset] = src_m[offset]; +static inline void move_byte_backward(unsigned char *dest_m, + const unsigned char *src_m, + size_t count) noexcept { + for (size_t offset = count; offset != 0; --offset) + dest_m[offset - 1] = src_m[offset - 1]; } LLVM_LIBC_FUNCTION(void *, memmove, (void *dest, const void *src, size_t count)) { - char *dest_c = reinterpret_cast(dest); - const char *src_c = reinterpret_cast(src); + unsigned char *dest_c = reinterpret_cast(dest); + const unsigned char *src_c = reinterpret_cast(src); // If the distance between src_c and dest_c is equal to or greater // than count (integerAbs(src_c - dest_c) >= count), they would not overlap. @@ -58,7 +60,7 @@ LLVM_LIBC_FUNCTION(void *, memmove, // TODO: Optimize `move_byte_xxx(...)` functions. if (dest_c < src_c) move_byte_forward(dest_c, src_c, count); - if (dest_c > src_c) + else if (dest_c > src_c) move_byte_backward(dest_c, src_c, count); return dest; } diff --git a/libc/src/string/memmove.h b/libc/src/string/memmove.h index 6d24a59a23c25..3204e617080db 100644 --- a/libc/src/string/memmove.h +++ b/libc/src/string/memmove.h @@ -13,7 +13,7 @@ namespace __llvm_libc { -void *memmove(void *dest, const void *src, size_t count); +void *memmove(void *dest, const void *src, size_t count) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/memory_utils/elements.h b/libc/src/string/memory_utils/elements.h index 48fb0084d610f..f8686de1f4102 100644 --- a/libc/src/string/memory_utils/elements.h +++ b/libc/src/string/memory_utils/elements.h @@ -26,44 +26,46 @@ namespace __llvm_libc { // Fixed-size copies from 'src' to 'dst'. template -void Copy(char *__restrict dst, const char *__restrict src) { +void Copy(char *__restrict dst, const char *__restrict src) noexcept { Element::Copy(dst, src); } // Runtime-size copies from 'src' to 'dst'. template -void Copy(char *__restrict dst, const char *__restrict src, size_t size) { +void Copy(char *__restrict dst, const char *__restrict src, + size_t size) noexcept { Element::Copy(dst, src, size); } // Fixed-size equality between 'lhs' and 'rhs'. -template bool Equals(const char *lhs, const char *rhs) { +template +bool Equals(const char *lhs, const char *rhs) noexcept { return Element::Equals(lhs, rhs); } // Runtime-size equality between 'lhs' and 'rhs'. template -bool Equals(const char *lhs, const char *rhs, size_t size) { +bool Equals(const char *lhs, const char *rhs, size_t size) noexcept { return Element::Equals(lhs, rhs, size); } // Fixed-size three-way comparison between 'lhs' and 'rhs'. template -int ThreeWayCompare(const char *lhs, const char *rhs) { +int ThreeWayCompare(const char *lhs, const char *rhs) noexcept { return Element::ThreeWayCompare(lhs, rhs); } // Runtime-size three-way comparison between 'lhs' and 'rhs'. template -int ThreeWayCompare(const char *lhs, const char *rhs, size_t size) { +int ThreeWayCompare(const char *lhs, const char *rhs, size_t size) noexcept { return Element::ThreeWayCompare(lhs, rhs, size); } // Fixed-size initialization. template -void SplatSet(char *dst, const unsigned char value) { +void SplatSet(char *dst, const unsigned char value) noexcept { Element::SplatSet(dst, value); } // Runtime-size initialization. template -void SplatSet(char *dst, const unsigned char value, size_t size) { +void SplatSet(char *dst, const unsigned char value, size_t size) noexcept { Element::SplatSet(dst, value, size); } @@ -76,14 +78,14 @@ void SplatSet(char *dst, const unsigned char value, size_t size) { template struct Repeated { static constexpr size_t kSize = ElementCount * Element::kSize; - static void Copy(char *__restrict dst, const char *__restrict src) { + static void Copy(char *__restrict dst, const char *__restrict src) noexcept { for (size_t i = 0; i < ElementCount; ++i) { const size_t offset = i * Element::kSize; Element::Copy(dst + offset, src + offset); } } - static bool Equals(const char *lhs, const char *rhs) { + static bool Equals(const char *lhs, const char *rhs) noexcept { for (size_t i = 0; i < ElementCount; ++i) { const size_t offset = i * Element::kSize; if (!Element::Equals(lhs + offset, rhs + offset)) @@ -92,18 +94,17 @@ template struct Repeated { return true; } - static int ThreeWayCompare(const char *lhs, const char *rhs) { + static int ThreeWayCompare(const char *lhs, const char *rhs) noexcept { for (size_t i = 0; i < ElementCount; ++i) { const size_t offset = i * Element::kSize; // We make the assumption that 'Equals' si cheaper than 'ThreeWayCompare'. - if (Element::Equals(lhs + offset, rhs + offset)) - continue; - return Element::ThreeWayCompare(lhs + offset, rhs + offset); + if (!Element::Equals(lhs + offset, rhs + offset)) + return Element::ThreeWayCompare(lhs + offset, rhs + offset); } return 0; } - static void SplatSet(char *dst, const unsigned char value) { + static void SplatSet(char *dst, const unsigned char value) noexcept { for (size_t i = 0; i < ElementCount; ++i) { const size_t offset = i * Element::kSize; Element::SplatSet(dst + offset, value); @@ -119,25 +120,25 @@ template struct Chained; template struct Chained { static constexpr size_t kSize = Head::kSize + Chained::kSize; - static void Copy(char *__restrict dst, const char *__restrict src) { + static void Copy(char *__restrict dst, const char *__restrict src) noexcept { Chained::Copy(dst + Head::kSize, src + Head::kSize); __llvm_libc::Copy(dst, src); } - static bool Equals(const char *lhs, const char *rhs) { + static bool Equals(const char *lhs, const char *rhs) noexcept { if (!__llvm_libc::Equals(lhs, rhs)) return false; return Chained::Equals(lhs + Head::kSize, rhs + Head::kSize); } - static int ThreeWayCompare(const char *lhs, const char *rhs) { - if (__llvm_libc::Equals(lhs, rhs)) - return Chained::ThreeWayCompare(lhs + Head::kSize, - rhs + Head::kSize); - return __llvm_libc::ThreeWayCompare(lhs, rhs); + static int ThreeWayCompare(const char *lhs, const char *rhs) noexcept { + if (!__llvm_libc::Equals(lhs, rhs)) + return __llvm_libc::ThreeWayCompare(lhs, rhs); + return Chained::ThreeWayCompare(lhs + Head::kSize, + rhs + Head::kSize); } - static void SplatSet(char *dst, const unsigned char value) { + static void SplatSet(char *dst, const unsigned char value) noexcept { Chained::SplatSet(dst + Head::kSize, value); __llvm_libc::SplatSet(dst, value); } @@ -168,23 +169,25 @@ template <> struct Chained<> { // Precondition: `size >= T::kSize`. template struct Tail { static void Copy(char *__restrict dst, const char *__restrict src, - size_t size) { + size_t size) noexcept { return T::Copy(dst + offset(size), src + offset(size)); } - static bool Equals(const char *lhs, const char *rhs, size_t size) { + static bool Equals(const char *lhs, const char *rhs, size_t size) noexcept { return T::Equals(lhs + offset(size), rhs + offset(size)); } - static int ThreeWayCompare(const char *lhs, const char *rhs, size_t size) { + static int ThreeWayCompare(const char *lhs, const char *rhs, + size_t size) noexcept { return T::ThreeWayCompare(lhs + offset(size), rhs + offset(size)); } - static void SplatSet(char *dst, const unsigned char value, size_t size) { + static void SplatSet(char *dst, const unsigned char value, + size_t size) noexcept { return T::SplatSet(dst + offset(size), value); } - static size_t offset(size_t size) { return size - T::kSize; } + static size_t offset(size_t size) noexcept { return size - T::kSize; } }; // Perform the operation on the first and last 'T::kSize' bytes of the buffer. @@ -199,24 +202,26 @@ template struct Tail { // Precondition: `size >= T::kSize && size <= 2 x T::kSize`. template struct HeadTail { static void Copy(char *__restrict dst, const char *__restrict src, - size_t size) { + size_t size) noexcept { T::Copy(dst, src); Tail::Copy(dst, src, size); } - static bool Equals(const char *lhs, const char *rhs, size_t size) { + static bool Equals(const char *lhs, const char *rhs, size_t size) noexcept { if (!T::Equals(lhs, rhs)) return false; return Tail::Equals(lhs, rhs, size); } - static int ThreeWayCompare(const char *lhs, const char *rhs, size_t size) { + static int ThreeWayCompare(const char *lhs, const char *rhs, + size_t size) noexcept { if (!T::Equals(lhs, rhs)) return T::ThreeWayCompare(lhs, rhs); return Tail::ThreeWayCompare(lhs, rhs, size); } - static void SplatSet(char *dst, const unsigned char value, size_t size) { + static void SplatSet(char *dst, const unsigned char value, + size_t size) noexcept { T::SplatSet(dst, value); Tail::SplatSet(dst, value, size); } @@ -356,7 +361,7 @@ namespace builtin { template struct Builtin { static constexpr size_t kSize = Size; - static void Copy(char *__restrict dst, const char *__restrict src) { + static void Copy(char *__restrict dst, const char *__restrict src) noexcept { #if LLVM_LIBC_HAVE_MEMORY_SANITIZER || LLVM_LIBC_HAVE_ADDRESS_SANITIZER ForLoopCopy(dst, src); #elif __has_builtin(__builtin_memcpy_inline) @@ -376,15 +381,15 @@ template struct Builtin { #define LLVM_LIBC_MEMCMP __builtin_memcmp #endif - static bool Equals(const char *lhs, const char *rhs) { + static bool Equals(const char *lhs, const char *rhs) noexcept { return LLVM_LIBC_MEMCMP(lhs, rhs, kSize) == 0; } - static int ThreeWayCompare(const char *lhs, const char *rhs) { + static int ThreeWayCompare(const char *lhs, const char *rhs) noexcept { return LLVM_LIBC_MEMCMP(lhs, rhs, kSize); } - static void SplatSet(char *dst, const unsigned char value) { + static void SplatSet(char *dst, const unsigned char value) noexcept { __builtin_memset(dst, value, kSize); } @@ -392,7 +397,8 @@ template struct Builtin { // Copies `kSize` bytes from `src` to `dst` using a for loop. // This code requires the use of `-fno-buitin-memcpy` to prevent the compiler // from turning the for-loop back into `__builtin_memcpy`. - static void ForLoopCopy(char *__restrict dst, const char *__restrict src) { + static void ForLoopCopy(char *__restrict dst, + const char *__restrict src) noexcept { for (size_t i = 0; i < kSize; ++i) dst[i] = src[i]; } @@ -418,58 +424,62 @@ namespace scalar { template struct Scalar { static constexpr size_t kSize = sizeof(T); - static void Copy(char *__restrict dst, const char *__restrict src) { + static void Copy(char *__restrict dst, const char *__restrict src) noexcept { Store(dst, Load(src)); } - static bool Equals(const char *lhs, const char *rhs) { + static bool Equals(const char *lhs, const char *rhs) noexcept { return Load(lhs) == Load(rhs); } - static int ThreeWayCompare(const char *lhs, const char *rhs) { + static int ThreeWayCompare(const char *lhs, const char *rhs) noexcept { return ScalarThreeWayCompare(Load(lhs), Load(rhs)); } - static void SplatSet(char *dst, const unsigned char value) { + static void SplatSet(char *dst, const unsigned char value) noexcept { Store(dst, GetSplattedValue(value)); } - static int ScalarThreeWayCompare(T a, T b); + static int ScalarThreeWayCompare(T a, T b) noexcept; private: - static T Load(const char *ptr) { + static T Load(const char *ptr) noexcept { T value; builtin::Builtin::Copy(reinterpret_cast(&value), ptr); return value; } - static void Store(char *ptr, T value) { + static void Store(char *ptr, T value) noexcept { builtin::Builtin::Copy(ptr, reinterpret_cast(&value)); } - static T GetSplattedValue(const unsigned char value) { + static T GetSplattedValue(const unsigned char value) noexcept { return T(~0) / T(0xFF) * T(value); } }; template <> -inline int Scalar::ScalarThreeWayCompare(uint8_t a, uint8_t b) { +inline int Scalar::ScalarThreeWayCompare(uint8_t a, + uint8_t b) noexcept { const int16_t la = Endian::ToBigEndian(a); const int16_t lb = Endian::ToBigEndian(b); return la - lb; } template <> -inline int Scalar::ScalarThreeWayCompare(uint16_t a, uint16_t b) { +inline int Scalar::ScalarThreeWayCompare(uint16_t a, + uint16_t b) noexcept { const int32_t la = Endian::ToBigEndian(a); const int32_t lb = Endian::ToBigEndian(b); return la - lb; } template <> -inline int Scalar::ScalarThreeWayCompare(uint32_t a, uint32_t b) { +inline int Scalar::ScalarThreeWayCompare(uint32_t a, + uint32_t b) noexcept { const uint32_t la = Endian::ToBigEndian(a); const uint32_t lb = Endian::ToBigEndian(b); return la > lb ? 1 : la < lb ? -1 : 0; } template <> -inline int Scalar::ScalarThreeWayCompare(uint64_t a, uint64_t b) { +inline int Scalar::ScalarThreeWayCompare(uint64_t a, + uint64_t b) noexcept { const uint64_t la = Endian::ToBigEndian(a); const uint64_t lb = Endian::ToBigEndian(b); return la > lb ? 1 : la < lb ? -1 : 0; diff --git a/libc/src/string/memory_utils/memset_utils.h b/libc/src/string/memory_utils/memset_utils.h index be1048a9be03b..679dbec7ef02c 100644 --- a/libc/src/string/memory_utils/memset_utils.h +++ b/libc/src/string/memory_utils/memset_utils.h @@ -48,7 +48,7 @@ namespace __llvm_libc { // may waste up to 31 Bytes. Benchmarks showed that SetAlignedBlocks<64> was not // superior for sizes that mattered. inline static void GeneralPurposeMemset(char *dst, unsigned char value, - size_t count) { + size_t count) noexcept { #if defined(__i386__) || defined(__x86_64__) using namespace ::__llvm_libc::x86; #else diff --git a/libc/src/string/memory_utils/utils.h b/libc/src/string/memory_utils/utils.h index d6047e1c482fe..84bd8f5b6e44d 100644 --- a/libc/src/string/memory_utils/utils.h +++ b/libc/src/string/memory_utils/utils.h @@ -72,11 +72,12 @@ template intptr_t offset_to_next_aligned(const void *ptr) { } // Returns the offset from `ptr` to the next cache line. -static inline intptr_t offset_to_next_cache_line(const void *ptr) { +static inline intptr_t offset_to_next_cache_line(const void *ptr) noexcept { return offset_to_next_aligned(ptr); } -template static T *assume_aligned(T *ptr) { +template +static T *assume_aligned(T *ptr) noexcept { return reinterpret_cast(__builtin_assume_aligned(ptr, alignment)); } diff --git a/libc/src/string/memrchr.cpp b/libc/src/string/memrchr.cpp index b010b8ad87c5f..da5baa47f4f9d 100644 --- a/libc/src/string/memrchr.cpp +++ b/libc/src/string/memrchr.cpp @@ -14,11 +14,10 @@ namespace __llvm_libc { LLVM_LIBC_FUNCTION(void *, memrchr, (const void *src, int c, size_t n)) { const unsigned char *str = reinterpret_cast(src); - const unsigned char ch = c; + const unsigned char ch = static_cast(c); for (; n != 0; --n) { - const unsigned char *s = str + n - 1; - if (*s == ch) - return const_cast(s); + if (*(--str) == ch) + return const_cast(str); } return nullptr; } diff --git a/libc/src/string/memrchr.h b/libc/src/string/memrchr.h index 8f43577e331fe..802bcc2c77dc6 100644 --- a/libc/src/string/memrchr.h +++ b/libc/src/string/memrchr.h @@ -13,7 +13,7 @@ namespace __llvm_libc { -void *memrchr(const void *src, int c, size_t n); +void *memrchr(const void *src, int c, size_t n) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/memset.h b/libc/src/string/memset.h index e38eb7d78a976..b4c7a8a81a6bb 100644 --- a/libc/src/string/memset.h +++ b/libc/src/string/memset.h @@ -13,7 +13,7 @@ namespace __llvm_libc { -void *memset(void *ptr, int value, size_t count); +void *memset(void *ptr, int value, size_t count) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/strcat.h b/libc/src/string/strcat.h index 20e966c675df1..331d02bab9da9 100644 --- a/libc/src/string/strcat.h +++ b/libc/src/string/strcat.h @@ -13,7 +13,7 @@ namespace __llvm_libc { -char *strcat(char *__restrict dest, const char *__restrict src); +char *strcat(char *__restrict dest, const char *__restrict src) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/strchr.cpp b/libc/src/string/strchr.cpp index 6288b64b74628..836f243d87593 100644 --- a/libc/src/string/strchr.cpp +++ b/libc/src/string/strchr.cpp @@ -14,12 +14,12 @@ namespace __llvm_libc { // TODO: Look at performance benefits of comparing words. LLVM_LIBC_FUNCTION(char *, strchr, (const char *src, int c)) { - unsigned char *str = - const_cast(reinterpret_cast(src)); - const unsigned char ch = c; - for (; *str && *str != ch; ++str) - ; - return *str == ch ? reinterpret_cast(str) : nullptr; + const char ch = static_cast(c); + for (; *src != ch; ++src) + if (*src == '\0') + return nullptr; + + return const_cast(src); } } // namespace __llvm_libc diff --git a/libc/src/string/strchr.h b/libc/src/string/strchr.h index 6f106afaf695c..ec6a044104e60 100644 --- a/libc/src/string/strchr.h +++ b/libc/src/string/strchr.h @@ -11,7 +11,7 @@ namespace __llvm_libc { -char *strchr(const char *src, int c); +char *strchr(const char *src, int c) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/strcmp.h b/libc/src/string/strcmp.h index a45f2d5ba8e5d..5eccce4c28305 100644 --- a/libc/src/string/strcmp.h +++ b/libc/src/string/strcmp.h @@ -11,7 +11,7 @@ namespace __llvm_libc { -int strcmp(const char *left, const char *right); +int strcmp(const char *left, const char *right) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/strcpy.h b/libc/src/string/strcpy.h index 2d2af21c70449..d8e28149682bf 100644 --- a/libc/src/string/strcpy.h +++ b/libc/src/string/strcpy.h @@ -13,7 +13,7 @@ namespace __llvm_libc { -char *strcpy(char *__restrict dest, const char *__restrict src); +char *strcpy(char *__restrict dest, const char *__restrict src) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/strcspn.h b/libc/src/string/strcspn.h index 9674f4b6359b0..bfd5e5fc50050 100644 --- a/libc/src/string/strcspn.h +++ b/libc/src/string/strcspn.h @@ -13,7 +13,7 @@ namespace __llvm_libc { -size_t strcspn(const char *src, const char *segment); +size_t strcspn(const char *src, const char *segment) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/string_utils.h b/libc/src/string/string_utils.h index dfb2c8af45279..eba4976ce4fb8 100644 --- a/libc/src/string/string_utils.h +++ b/libc/src/string/string_utils.h @@ -17,31 +17,33 @@ namespace internal { // Returns the length of a string, denoted by the first occurrence // of a null terminator. -static inline size_t string_length(const char *src) { - size_t length; - for (length = 0; *src; ++src, ++length) +static inline size_t string_length(const char *src) noexcept { + const char *const initial = src; + for (; *src != '\0'; ++src) ; - return length; + return src - initial; } // Returns the first occurrence of 'ch' within the first 'n' characters of // 'src'. If 'ch' is not found, returns nullptr. static inline void *find_first_character(const unsigned char *src, - unsigned char ch, size_t n) { - for (; n && *src != ch; --n, ++src) - ; - return n ? const_cast(src) : nullptr; + unsigned char ch, size_t n) noexcept { + for (; n != 0; --n, ++src) + if (*src == ch) + return const_cast(src); + return nullptr; } // Returns the maximum length span that contains only characters not found in // 'segment'. If no characters are found, returns the length of 'src'. -static inline size_t complementary_span(const char *src, const char *segment) { - const char *initial = src; +static inline size_t complementary_span(const char *src, + const char *segment) noexcept { + const char *const initial = src; cpp::Bitset<256> bitset; - for (; *segment; ++segment) + for (; *segment != '\0'; ++segment) bitset.set(*segment); - for (; *src && !bitset.test(*src); ++src) + for (; *src != '\0' && !bitset.test(*src); ++src) ; return src - initial; } @@ -57,24 +59,23 @@ static inline size_t complementary_span(const char *src, const char *segment) { // terminating character is reached, returns a nullptr. static inline char *string_token(char *__restrict src, const char *__restrict delimiter_string, - char **__restrict saveptr) { + char **__restrict saveptr) noexcept { cpp::Bitset<256> delimiter_set; - for (; *delimiter_string; ++delimiter_string) + for (; *delimiter_string != '\0'; ++delimiter_string) delimiter_set.set(*delimiter_string); src = src ? src : *saveptr; - for (; *src && delimiter_set.test(*src); ++src) + for (; *src != '\0' && delimiter_set.test(*src); ++src) ; - if (!*src) { + if (*src == '\0') { *saveptr = src; return nullptr; } char *token = src; - for (; *src && !delimiter_set.test(*src); ++src) + for (; *src != '\0' && !delimiter_set.test(*src); ++src) ; - if (*src) { - *src = '\0'; - ++src; + if (*src != '\0') { + *src++ = '\0'; } *saveptr = src; return token; diff --git a/libc/src/string/strlen.h b/libc/src/string/strlen.h index b3ad03f612d0a..0a5ba82b391b9 100644 --- a/libc/src/string/strlen.h +++ b/libc/src/string/strlen.h @@ -13,7 +13,7 @@ namespace __llvm_libc { -size_t strlen(const char *src); +size_t strlen(const char *src) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/strncpy.h b/libc/src/string/strncpy.h index c419df990cd78..0b9cc5d1c3740 100644 --- a/libc/src/string/strncpy.h +++ b/libc/src/string/strncpy.h @@ -13,7 +13,8 @@ namespace __llvm_libc { -char *strncpy(char *__restrict dest, const char *__restrict src, size_t n); +char *strncpy(char *__restrict dest, const char *__restrict src, + size_t n) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/strnlen.h b/libc/src/string/strnlen.h index 2d2ee9703d83d..62d5671472764 100644 --- a/libc/src/string/strnlen.h +++ b/libc/src/string/strnlen.h @@ -13,7 +13,7 @@ namespace __llvm_libc { -size_t strnlen(const char *src, size_t n); +size_t strnlen(const char *src, size_t n) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/strpbrk.h b/libc/src/string/strpbrk.h index 823cd35e9e30e..428ad587f221c 100644 --- a/libc/src/string/strpbrk.h +++ b/libc/src/string/strpbrk.h @@ -11,7 +11,7 @@ namespace __llvm_libc { -char *strpbrk(const char *src, const char *breakset); +char *strpbrk(const char *src, const char *breakset) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/strrchr.cpp b/libc/src/string/strrchr.cpp index 33a638bacd862..21c640772c1f7 100644 --- a/libc/src/string/strrchr.cpp +++ b/libc/src/string/strrchr.cpp @@ -13,12 +13,12 @@ namespace __llvm_libc { LLVM_LIBC_FUNCTION(char *, strrchr, (const char *src, int c)) { - const char ch = c; + const char ch = static_cast(c); char *last_occurrence = nullptr; do { if (*src == ch) last_occurrence = const_cast(src); - } while (*src++); + } while (*src++ != '\0'); return last_occurrence; } diff --git a/libc/src/string/strrchr.h b/libc/src/string/strrchr.h index 7b85929b290b7..f2e9a1558416b 100644 --- a/libc/src/string/strrchr.h +++ b/libc/src/string/strrchr.h @@ -11,7 +11,7 @@ namespace __llvm_libc { -char *strrchr(const char *src, int c); +char *strrchr(const char *src, int c) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/strspn.h b/libc/src/string/strspn.h index 92321d10df93e..3f1cd78064f65 100644 --- a/libc/src/string/strspn.h +++ b/libc/src/string/strspn.h @@ -13,7 +13,7 @@ namespace __llvm_libc { -size_t strspn(const char *src, const char *segment); +size_t strspn(const char *src, const char *segment) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/strstr.h b/libc/src/string/strstr.h index 463ffb7494c9e..68991e36f7118 100644 --- a/libc/src/string/strstr.h +++ b/libc/src/string/strstr.h @@ -11,7 +11,7 @@ namespace __llvm_libc { -char *strstr(const char *haystack, const char *needle); +char *strstr(const char *haystack, const char *needle) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/strtok.h b/libc/src/string/strtok.h index 33ac68184a331..2847c3e311dfb 100644 --- a/libc/src/string/strtok.h +++ b/libc/src/string/strtok.h @@ -11,7 +11,8 @@ namespace __llvm_libc { -char *strtok(char *__restrict src, const char *__restrict delimiter_string); +char *strtok(char *__restrict src, + const char *__restrict delimiter_string) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/strtok_r.h b/libc/src/string/strtok_r.h index f1aff3e3176a0..a747eb8910f4d 100644 --- a/libc/src/string/strtok_r.h +++ b/libc/src/string/strtok_r.h @@ -12,7 +12,7 @@ namespace __llvm_libc { char *strtok_r(char *__restrict src, const char *__restrict delimiter_string, - char **__restrict saveptr); + char **__restrict saveptr) noexcept; } // namespace __llvm_libc diff --git a/libc/src/string/x86_64/memcpy.cpp b/libc/src/string/x86_64/memcpy.cpp index 7f6e5b64b3a74..2508d66d6cef2 100644 --- a/libc/src/string/x86_64/memcpy.cpp +++ b/libc/src/string/x86_64/memcpy.cpp @@ -63,7 +63,7 @@ static void CopyRepMovsb(char *__restrict dst, const char *__restrict src, // - As compilers and processors get better, the generated code is improved // with little change on the code side. static void memcpy_x86(char *__restrict dst, const char *__restrict src, - size_t count) { + size_t count) noexcept { // Use x86 strategies (_1, _2, _3 ...) using namespace __llvm_libc::x86;