summaryrefslogtreecommitdiff
path: root/libc/include/bits/fortify/string.h
diff options
context:
space:
mode:
Diffstat (limited to 'libc/include/bits/fortify/string.h')
-rw-r--r--libc/include/bits/fortify/string.h61
1 files changed, 33 insertions, 28 deletions
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
index 14bb1335b..1e129868c 100644
--- a/libc/include/bits/fortify/string.h
+++ b/libc/include/bits/fortify/string.h
@@ -44,17 +44,25 @@ extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
__BIONIC_FORTIFY_INLINE
void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
__overloadable
- __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < copy_amount,
+ __clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount),
"'memcpy' called with size bigger than buffer") {
- return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
+ size_t bos_dst = __bos0(dst);
+ if (__bos_trivially_not_lt(bos_dst, copy_amount)) {
+ return __builtin_memcpy(dst, src, copy_amount);
+ }
+ return __builtin___memcpy_chk(dst, src, copy_amount, bos_dst);
}
__BIONIC_FORTIFY_INLINE
void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
__overloadable
- __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < len,
+ __clang_error_if(__bos_unevaluated_lt(__bos0(dst), len),
"'memmove' called with size bigger than buffer") {
- return __builtin___memmove_chk(dst, src, len, __bos0(dst));
+ size_t bos_dst = __bos0(dst);
+ if (__bos_trivially_not_lt(bos_dst, len)) {
+ return __builtin_memmove(dst, src, len);
+ }
+ return __builtin___memmove_chk(dst, src, len, bos_dst);
}
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
@@ -62,10 +70,13 @@ void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
__BIONIC_FORTIFY_INLINE
char* stpcpy(char* const dst __pass_object_size, const char* src)
__overloadable
- __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos(dst) <= __builtin_strlen(src),
+ __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
"'stpcpy' called with string bigger than buffer") {
- return __builtin___stpcpy_chk(dst, src, __bos(dst));
+ size_t bos_dst = __bos(dst);
+ if (__bos_trivially_not_le(bos_dst, __builtin_strlen(src))) {
+ return __builtin_stpcpy(dst, src);
+ }
+ return __builtin___stpcpy_chk(dst, src, bos_dst);
}
#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
@@ -73,10 +84,13 @@ char* stpcpy(char* const dst __pass_object_size, const char* src)
__BIONIC_FORTIFY_INLINE
char* strcpy(char* const dst __pass_object_size, const char* src)
__overloadable
- __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos(dst) <= __builtin_strlen(src),
+ __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
"'strcpy' called with string bigger than buffer") {
- return __builtin___strcpy_chk(dst, src, __bos(dst));
+ size_t bos_dst = __bos(dst);
+ if (__bos_trivially_not_le(bos_dst, __builtin_strlen(src))) {
+ return __builtin_strcpy(dst, src);
+ }
+ return __builtin___strcpy_chk(dst, src, bos_dst);
}
__BIONIC_FORTIFY_INLINE
@@ -92,11 +106,15 @@ char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __o
__BIONIC_FORTIFY_INLINE
void* memset(void* const s __pass_object_size0, int c, size_t n)
__overloadable
- __clang_error_if(__bos0(s) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(s) < n,
+ __clang_error_if(__bos_unevaluated_lt(__bos0(s), n),
"'memset' called with size bigger than buffer")
/* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
__clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
- return __builtin___memset_chk(s, c, n, __bos0(s));
+ size_t bos = __bos0(s);
+ if (__bos_trivially_not_lt(bos, n)) {
+ return __builtin_memset(s, c, n);
+ }
+ return __builtin___memset_chk(s, c, n, bos);
}
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
@@ -105,7 +123,7 @@ __BIONIC_FORTIFY_INLINE
void* memchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
size_t bos = __bos(s);
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ if (__bos_trivially_ge(bos, n)) {
return __builtin_memchr(s, c, n);
}
@@ -116,7 +134,7 @@ __BIONIC_FORTIFY_INLINE
void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) __overloadable {
size_t bos = __bos(s);
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ if (__bos_trivially_ge(bos, n)) {
return __memrchr_real(s, c, n);
}
@@ -177,24 +195,11 @@ size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size)
return __strlcat_chk(dst, src, size, bos);
}
-/*
- * If we can evaluate the size of s at compile-time, just call __builtin_strlen
- * on it directly. This makes it way easier for compilers to fold things like
- * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
- * because it's large.
- */
-__BIONIC_FORTIFY_INLINE
-size_t strlen(const char* const s __pass_object_size)
- __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
- "enabled if s is a known good string.") {
- return __builtin_strlen(s);
-}
-
__BIONIC_FORTIFY_INLINE
size_t strlen(const char* const s __pass_object_size0) __overloadable {
size_t bos = __bos0(s);
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ if (__bos_trivially_gt(bos, __builtin_strlen(s))) {
return __builtin_strlen(s);
}