Retire GCC FORTIFY.
NDK r18 (which removes GCC) is about to ship. We don't need this any more. The immediate motivation for removing this right now is that the test fails whenever we add Clang-only flags to the build system. While we're here, clean up <stdatomic.h> too. Bug: https://issuetracker.google.com/74404306 Test: ran tests Change-Id: Iaad5d634d1ba76f0b6f19ad32cc27b2533771a4a
This commit is contained in:
parent
94ab04c17a
commit
067bdc9546
17 changed files with 37 additions and 1070 deletions
|
@ -44,7 +44,6 @@ int __openat_real(int, const char*, int, ...) __RENAME(openat);
|
|||
#define __open_useless_modes_warning "has superfluous mode bits; missing O_CREAT?"
|
||||
/* O_TMPFILE shares bits with O_DIRECTORY. */
|
||||
#define __open_modes_useful(flags) (((flags) & O_CREAT) || ((flags) & O_TMPFILE) == O_TMPFILE)
|
||||
#if defined(__clang__)
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
|
||||
__BIONIC_ERROR_FUNCTION_VISIBILITY
|
||||
|
@ -93,52 +92,6 @@ int openat(int dirfd, const char* const __pass_object_size pathname, int flags,
|
|||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
|
||||
|
||||
#else /* defined(__clang__) */
|
||||
__errordecl(__creat_missing_mode, __open_too_few_args_error);
|
||||
__errordecl(__creat_too_many_args, __open_too_many_args_error);
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
|
||||
__BIONIC_FORTIFY_VARIADIC
|
||||
int open(const char* pathname, int flags, ...) {
|
||||
if (__builtin_constant_p(flags)) {
|
||||
if (__open_modes_useful(flags) && __builtin_va_arg_pack_len() == 0) {
|
||||
__creat_missing_mode(); /* Compile time error. */
|
||||
}
|
||||
}
|
||||
|
||||
if (__builtin_va_arg_pack_len() > 1) {
|
||||
__creat_too_many_args(); /* Compile time error. */
|
||||
}
|
||||
|
||||
if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
|
||||
return __open_2(pathname, flags);
|
||||
}
|
||||
|
||||
return __open_real(pathname, flags, __builtin_va_arg_pack());
|
||||
}
|
||||
|
||||
__BIONIC_FORTIFY_VARIADIC
|
||||
int openat(int dirfd, const char* pathname, int flags, ...) {
|
||||
if (__builtin_constant_p(flags)) {
|
||||
if (__open_modes_useful(flags) && __builtin_va_arg_pack_len() == 0) {
|
||||
__creat_missing_mode(); /* Compile time error. */
|
||||
}
|
||||
}
|
||||
|
||||
if (__builtin_va_arg_pack_len() > 1) {
|
||||
__creat_too_many_args(); /* Compile time error. */
|
||||
}
|
||||
|
||||
if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
|
||||
return __openat_2(dirfd, pathname, flags);
|
||||
}
|
||||
|
||||
return __openat_real(dirfd, pathname, flags, __builtin_va_arg_pack());
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
|
||||
|
||||
#endif /* defined(__clang__) */
|
||||
|
||||
#undef __open_too_many_args_error
|
||||
#undef __open_too_few_args_error
|
||||
#undef __open_useless_modes_warning
|
||||
|
|
|
@ -36,7 +36,7 @@ int __ppoll64_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset64
|
|||
|
||||
#if defined(__BIONIC_FORTIFY)
|
||||
#if __ANDROID_API__ >= __ANDROID_API_M__
|
||||
#if defined(__clang__)
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
int poll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, int timeout)
|
||||
__overloadable
|
||||
|
@ -81,39 +81,5 @@ int ppoll64(struct pollfd* const fds __pass_object_size, nfds_t fd_count, const
|
|||
}
|
||||
#endif
|
||||
|
||||
#else /* !defined(__clang__) */
|
||||
int __poll_real(struct pollfd*, nfds_t, int) __RENAME(poll);
|
||||
__errordecl(__poll_too_small_error, "poll: pollfd array smaller than fd count");
|
||||
|
||||
int __ppoll_real(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*) __RENAME(ppoll)
|
||||
__INTRODUCED_IN(21);
|
||||
__errordecl(__ppoll_too_small_error, "ppoll: pollfd array smaller than fd count");
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
int poll(struct pollfd* fds, nfds_t fd_count, int timeout) {
|
||||
if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
if (!__builtin_constant_p(fd_count)) {
|
||||
return __poll_chk(fds, fd_count, timeout, __bos(fds));
|
||||
} else if (__bos(fds) / sizeof(*fds) < fd_count) {
|
||||
__poll_too_small_error();
|
||||
}
|
||||
}
|
||||
return __poll_real(fds, fd_count, timeout);
|
||||
}
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
int ppoll(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout,
|
||||
const sigset_t* mask) {
|
||||
if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
if (!__builtin_constant_p(fd_count)) {
|
||||
return __ppoll_chk(fds, fd_count, timeout, mask, __bos(fds));
|
||||
} else if (__bos(fds) / sizeof(*fds) < fd_count) {
|
||||
__ppoll_too_small_error();
|
||||
}
|
||||
}
|
||||
return __ppoll_real(fds, fd_count, timeout, mask);
|
||||
}
|
||||
|
||||
#endif /* defined(__clang__) */
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
|
||||
#endif /* defined(__BIONIC_FORTIFY) */
|
||||
|
|
|
@ -39,7 +39,7 @@ ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*,
|
|||
|
||||
#define __recvfrom_bad_size "'recvfrom' called with size bigger than buffer"
|
||||
#define __sendto_bad_size "'sendto' called with size bigger than buffer"
|
||||
#if defined(__clang__)
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_N__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len, int flags, struct sockaddr* src_addr, socklen_t* addr_len)
|
||||
|
@ -86,69 +86,6 @@ ssize_t send(int socket, const void* const buf __pass_object_size0, size_t len,
|
|||
return sendto(socket, buf, len, flags, NULL, 0);
|
||||
}
|
||||
|
||||
#else /* defined(__clang__) */
|
||||
ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);
|
||||
__errordecl(__recvfrom_error, __recvfrom_bad_size);
|
||||
|
||||
extern ssize_t __sendto_real(int, const void*, size_t, int, const struct sockaddr*, socklen_t)
|
||||
__RENAME(sendto);
|
||||
__errordecl(__sendto_error, __sendto_bad_size);
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_N__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t recvfrom(int fd, void* buf, size_t len, int flags,
|
||||
struct sockaddr* src_addr, socklen_t* addr_len) {
|
||||
size_t bos = __bos0(buf);
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(len) && (len <= bos)) {
|
||||
return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(len) && (len > bos)) {
|
||||
__recvfrom_error();
|
||||
}
|
||||
|
||||
return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_N_MR1__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t sendto(int fd, const void* buf, size_t len, int flags,
|
||||
const struct sockaddr* dest_addr, socklen_t addr_len) {
|
||||
size_t bos = __bos0(buf);
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __sendto_real(fd, buf, len, flags, dest_addr, addr_len);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(len) && (len <= bos)) {
|
||||
return __sendto_real(fd, buf, len, flags, dest_addr, addr_len);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(len) && (len > bos)) {
|
||||
__sendto_error();
|
||||
}
|
||||
|
||||
return __sendto_chk(fd, buf, len, bos, flags, dest_addr, addr_len);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t recv(int socket, void* buf, size_t len, int flags) {
|
||||
return recvfrom(socket, buf, len, flags, NULL, 0);
|
||||
}
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t send(int socket, const void* buf, size_t len, int flags) {
|
||||
return sendto(socket, buf, len, flags, NULL, 0);
|
||||
}
|
||||
#endif /* defined(__clang__) */
|
||||
|
||||
#undef __recvfrom_bad_size
|
||||
#undef __sendto_bad_size
|
||||
#endif /* __BIONIC_FORTIFY */
|
||||
|
|
|
@ -35,8 +35,6 @@ mode_t __umask_chk(mode_t) __INTRODUCED_IN(18);
|
|||
#if defined(__BIONIC_FORTIFY)
|
||||
#define __umask_invalid_mode_str "'umask' called with invalid mode"
|
||||
|
||||
#if defined(__clang__)
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
|
||||
/* Abuse enable_if to make this an overload of umask. */
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
|
@ -48,24 +46,6 @@ mode_t umask(mode_t mode)
|
|||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
|
||||
|
||||
#else /* defined(__clang__) */
|
||||
__errordecl(__umask_invalid_mode, __umask_invalid_mode_str);
|
||||
extern mode_t __umask_real(mode_t) __RENAME(umask);
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
mode_t umask(mode_t mode) {
|
||||
if (__builtin_constant_p(mode)) {
|
||||
if ((mode & 0777) != mode) {
|
||||
__umask_invalid_mode();
|
||||
}
|
||||
return __umask_real(mode);
|
||||
}
|
||||
return __umask_chk(mode);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
|
||||
|
||||
#endif /* defined(__clang__) */
|
||||
#undef __umask_invalid_mode_str
|
||||
|
||||
#endif /* defined(__BIONIC_FORTIFY) */
|
||||
|
|
|
@ -49,7 +49,6 @@ int vsprintf(char* const __pass_object_size dest, const char* format, va_list ap
|
|||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
|
||||
|
||||
#if defined(__clang__)
|
||||
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
|
||||
/*
|
||||
* Simple case: `format` can't have format specifiers, so we can just compare
|
||||
|
@ -141,114 +140,4 @@ char* fgets(char* const __pass_object_size dest, int size, FILE* stream)
|
|||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
|
||||
|
||||
#else /* defined(__clang__) */
|
||||
|
||||
size_t __fread_real(void*, size_t, size_t, FILE*) __RENAME(fread);
|
||||
__errordecl(__fread_too_big_error, "fread called with size * count bigger than buffer");
|
||||
__errordecl(__fread_overflow, "fread called with overflowing size * count");
|
||||
|
||||
char* __fgets_real(char*, int, FILE*) __RENAME(fgets);
|
||||
__errordecl(__fgets_too_big_error, "fgets called with size bigger than buffer");
|
||||
__errordecl(__fgets_too_small_error, "fgets called with size less than zero");
|
||||
|
||||
size_t __fwrite_real(const void*, size_t, size_t, FILE*) __RENAME(fwrite);
|
||||
__errordecl(__fwrite_too_big_error, "fwrite called with size * count bigger than buffer");
|
||||
__errordecl(__fwrite_overflow, "fwrite called with overflowing size * count");
|
||||
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
|
||||
__BIONIC_FORTIFY_VARIADIC __printflike(3, 4)
|
||||
int snprintf(char* dest, size_t size, const char* format, ...) {
|
||||
return __builtin___snprintf_chk(dest, size, 0, __bos(dest), format, __builtin_va_arg_pack());
|
||||
}
|
||||
|
||||
__BIONIC_FORTIFY_VARIADIC __printflike(2, 3)
|
||||
int sprintf(char* dest, const char* format, ...) {
|
||||
return __builtin___sprintf_chk(dest, 0, __bos(dest), format, __builtin_va_arg_pack());
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_N__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
size_t fread(void* buf, size_t size, size_t count, FILE* stream) {
|
||||
size_t bos = __bos0(buf);
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __fread_real(buf, size, count, stream);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
|
||||
size_t total;
|
||||
if (__size_mul_overflow(size, count, &total)) {
|
||||
__fread_overflow();
|
||||
}
|
||||
|
||||
if (total > bos) {
|
||||
__fread_too_big_error();
|
||||
}
|
||||
|
||||
return __fread_real(buf, size, count, stream);
|
||||
}
|
||||
|
||||
return __fread_chk(buf, size, count, stream, bos);
|
||||
}
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
size_t fwrite(const void* buf, size_t size, size_t count, FILE* stream) {
|
||||
size_t bos = __bos0(buf);
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __fwrite_real(buf, size, count, stream);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
|
||||
size_t total;
|
||||
if (__size_mul_overflow(size, count, &total)) {
|
||||
__fwrite_overflow();
|
||||
}
|
||||
|
||||
if (total > bos) {
|
||||
__fwrite_too_big_error();
|
||||
}
|
||||
|
||||
return __fwrite_real(buf, size, count, stream);
|
||||
}
|
||||
|
||||
return __fwrite_chk(buf, size, count, stream, bos);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
char *fgets(char* dest, int size, FILE* stream) {
|
||||
size_t bos = __bos(dest);
|
||||
|
||||
// Compiler can prove, at compile time, that the passed in size
|
||||
// is always negative. Force a compiler error.
|
||||
if (__builtin_constant_p(size) && (size < 0)) {
|
||||
__fgets_too_small_error();
|
||||
}
|
||||
|
||||
// Compiler doesn't know destination size. Don't call __fgets_chk
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __fgets_real(dest, size, stream);
|
||||
}
|
||||
|
||||
// Compiler can prove, at compile time, that the passed in size
|
||||
// is always <= the actual object size. Don't call __fgets_chk
|
||||
if (__builtin_constant_p(size) && (size <= (int) bos)) {
|
||||
return __fgets_real(dest, size, stream);
|
||||
}
|
||||
|
||||
// Compiler can prove, at compile time, that the passed in size
|
||||
// is always > the actual object size. Force a compiler error.
|
||||
if (__builtin_constant_p(size) && (size > (int) bos)) {
|
||||
__fgets_too_big_error();
|
||||
}
|
||||
|
||||
return __fgets_chk(dest, size, stream, bos);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
|
||||
|
||||
#endif /* defined(__clang__) */
|
||||
#endif /* defined(__BIONIC_FORTIFY) */
|
||||
|
|
|
@ -37,31 +37,12 @@
|
|||
/* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */
|
||||
#define __PATH_MAX 4096
|
||||
|
||||
#if defined(__clang__)
|
||||
char* realpath(const char* path, char* resolved)
|
||||
__clang_error_if(__bos(resolved) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
|
||||
__bos(resolved) < __PATH_MAX, __realpath_buf_too_small_str)
|
||||
__clang_error_if(!path, "'realpath': NULL path is never correct; flipped arguments?");
|
||||
/* No need for a definition; the only issues we can catch are at compile-time. */
|
||||
|
||||
#else /* defined(__clang__) */
|
||||
|
||||
char* __realpath_real(const char*, char*) __RENAME(realpath);
|
||||
__errordecl(__realpath_size_error, __realpath_buf_too_small_str);
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
char* realpath(const char* path, char* resolved) {
|
||||
size_t bos = __bos(resolved);
|
||||
|
||||
if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < __PATH_MAX) {
|
||||
__realpath_size_error();
|
||||
}
|
||||
|
||||
return __realpath_real(path, resolved);
|
||||
}
|
||||
|
||||
#endif /* defined(__clang__) */
|
||||
|
||||
#undef __PATH_MAX
|
||||
#undef __realpath_buf_too_small_str
|
||||
#endif /* defined(__BIONIC_FORTIFY) */
|
||||
|
|
|
@ -40,8 +40,6 @@ size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
|
|||
#if defined(__BIONIC_FORTIFY)
|
||||
extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
|
||||
|
||||
// These can share their implementation between gcc and clang with minimal
|
||||
// trickery...
|
||||
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
|
||||
|
@ -102,9 +100,6 @@ void* memset(void* const s __pass_object_size0, int c, size_t n)
|
|||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
|
||||
|
||||
|
||||
#if defined(__clang__)
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_M__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
void* memchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
|
||||
|
@ -231,192 +226,6 @@ char* strrchr(const char* const s __pass_object_size, int c) __overloadable {
|
|||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
|
||||
|
||||
#else // defined(__clang__)
|
||||
extern char* __strncpy_real(char*, const char*, size_t) __RENAME(strncpy);
|
||||
extern size_t __strlcpy_real(char*, const char*, size_t)
|
||||
__RENAME(strlcpy);
|
||||
extern size_t __strlcat_real(char*, const char*, size_t)
|
||||
__RENAME(strlcat);
|
||||
|
||||
__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
|
||||
__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_M__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
void* memchr(const void* s __pass_object_size, int c, size_t n) {
|
||||
size_t bos = __bos(s);
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __builtin_memchr(s, c, n);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(n) && (n > bos)) {
|
||||
__memchr_buf_size_error();
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(n) && (n <= bos)) {
|
||||
return __builtin_memchr(s, c, n);
|
||||
}
|
||||
|
||||
return __memchr_chk(s, c, n, bos);
|
||||
}
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
void* __memrchr_fortify(const void* s, int c, size_t n) {
|
||||
size_t bos = __bos(s);
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __memrchr_real(s, c, n);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(n) && (n > bos)) {
|
||||
__memrchr_buf_size_error();
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(n) && (n <= bos)) {
|
||||
return __memrchr_real(s, c, n);
|
||||
}
|
||||
|
||||
return __memrchr_chk(s, c, n, bos);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_L__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
char* stpncpy(char* dst, const char* src, size_t n) {
|
||||
size_t bos_dst = __bos(dst);
|
||||
size_t bos_src = __bos(src);
|
||||
|
||||
if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __builtin___stpncpy_chk(dst, src, n, bos_dst);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(n) && (n <= bos_src)) {
|
||||
return __builtin___stpncpy_chk(dst, src, n, bos_dst);
|
||||
}
|
||||
|
||||
size_t slen = __builtin_strlen(src);
|
||||
if (__builtin_constant_p(slen)) {
|
||||
return __builtin___stpncpy_chk(dst, src, n, bos_dst);
|
||||
}
|
||||
|
||||
return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
|
||||
}
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
char* strncpy(char* dst, const char* src, size_t n) {
|
||||
size_t bos_dst = __bos(dst);
|
||||
size_t bos_src = __bos(src);
|
||||
|
||||
if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __strncpy_real(dst, src, n);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(n) && (n <= bos_src)) {
|
||||
return __builtin___strncpy_chk(dst, src, n, bos_dst);
|
||||
}
|
||||
|
||||
size_t slen = __builtin_strlen(src);
|
||||
if (__builtin_constant_p(slen)) {
|
||||
return __builtin___strncpy_chk(dst, src, n, bos_dst);
|
||||
}
|
||||
|
||||
return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
size_t strlcpy(char* dst __pass_object_size, const char* src, size_t size) {
|
||||
size_t bos = __bos(dst);
|
||||
|
||||
// Compiler doesn't know destination size. Don't call __strlcpy_chk
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __strlcpy_real(dst, src, size);
|
||||
}
|
||||
|
||||
// Compiler can prove, at compile time, that the passed in size
|
||||
// is always <= the actual object size. Don't call __strlcpy_chk
|
||||
if (__builtin_constant_p(size) && (size <= bos)) {
|
||||
return __strlcpy_real(dst, src, size);
|
||||
}
|
||||
|
||||
return __strlcpy_chk(dst, src, size, bos);
|
||||
}
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
size_t strlcat(char* dst, const char* src, size_t size) {
|
||||
size_t bos = __bos(dst);
|
||||
|
||||
// Compiler doesn't know destination size. Don't call __strlcat_chk
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __strlcat_real(dst, src, size);
|
||||
}
|
||||
|
||||
// Compiler can prove, at compile time, that the passed in size
|
||||
// is always <= the actual object size. Don't call __strlcat_chk
|
||||
if (__builtin_constant_p(size) && (size <= bos)) {
|
||||
return __strlcat_real(dst, src, size);
|
||||
}
|
||||
|
||||
return __strlcat_chk(dst, src, size, bos);
|
||||
}
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
size_t strlen(const char* s) __overloadable {
|
||||
size_t bos = __bos(s);
|
||||
|
||||
// Compiler doesn't know destination size. Don't call __strlen_chk
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __builtin_strlen(s);
|
||||
}
|
||||
|
||||
size_t slen = __builtin_strlen(s);
|
||||
if (__builtin_constant_p(slen)) {
|
||||
return slen;
|
||||
}
|
||||
|
||||
return __strlen_chk(s, bos);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
char* strchr(const char* s, int c) {
|
||||
size_t bos = __bos(s);
|
||||
|
||||
// Compiler doesn't know destination size. Don't call __strchr_chk
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __builtin_strchr(s, c);
|
||||
}
|
||||
|
||||
size_t slen = __builtin_strlen(s);
|
||||
if (__builtin_constant_p(slen) && (slen < bos)) {
|
||||
return __builtin_strchr(s, c);
|
||||
}
|
||||
|
||||
return __strchr_chk(s, c, bos);
|
||||
}
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
char* strrchr(const char* s, int c) {
|
||||
size_t bos = __bos(s);
|
||||
|
||||
// Compiler doesn't know destination size. Don't call __strrchr_chk
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __builtin_strrchr(s, c);
|
||||
}
|
||||
|
||||
size_t slen = __builtin_strlen(s);
|
||||
if (__builtin_constant_p(slen) && (slen < bos)) {
|
||||
return __builtin_strrchr(s, c);
|
||||
}
|
||||
|
||||
return __strrchr_chk(s, c, bos);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
|
||||
#endif /* defined(__clang__) */
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_M__
|
||||
#if defined(__cplusplus)
|
||||
extern "C++" {
|
||||
|
|
|
@ -59,7 +59,6 @@ ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTROD
|
|||
#define __PWRITE_PREFIX(x) __pwrite_ ## x
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
#define __error_if_overflows_ssizet(what, fn) \
|
||||
__clang_error_if((what) > SSIZE_MAX, "in call to '" #fn "', '" #what "' must be <= SSIZE_MAX")
|
||||
|
||||
|
@ -207,243 +206,6 @@ ssize_t readlinkat(int dirfd, const char* path, char* const __pass_object_size b
|
|||
#undef __enable_if_no_overflow_ssizet
|
||||
#undef __error_if_overflows_objectsize
|
||||
#undef __error_if_overflows_ssizet
|
||||
#else /* defined(__clang__) */
|
||||
|
||||
char* __getcwd_real(char*, size_t) __RENAME(getcwd);
|
||||
ssize_t __read_real(int, void*, size_t) __RENAME(read);
|
||||
ssize_t __write_real(int, const void*, size_t) __RENAME(write);
|
||||
ssize_t __readlink_real(const char*, char*, size_t) __RENAME(readlink);
|
||||
ssize_t __readlinkat_real(int dirfd, const char*, char*, size_t) __RENAME(readlinkat);
|
||||
|
||||
__errordecl(__getcwd_dest_size_error, "getcwd called with size bigger than destination");
|
||||
__errordecl(__pread_dest_size_error, "pread called with size bigger than destination");
|
||||
__errordecl(__pread_count_toobig_error, "pread called with count > SSIZE_MAX");
|
||||
__errordecl(__pread64_dest_size_error, "pread64 called with size bigger than destination");
|
||||
__errordecl(__pread64_count_toobig_error, "pread64 called with count > SSIZE_MAX");
|
||||
__errordecl(__pwrite_dest_size_error, "pwrite called with size bigger than destination");
|
||||
__errordecl(__pwrite_count_toobig_error, "pwrite called with count > SSIZE_MAX");
|
||||
__errordecl(__pwrite64_dest_size_error, "pwrite64 called with size bigger than destination");
|
||||
__errordecl(__pwrite64_count_toobig_error, "pwrite64 called with count > SSIZE_MAX");
|
||||
__errordecl(__read_dest_size_error, "read called with size bigger than destination");
|
||||
__errordecl(__read_count_toobig_error, "read called with count > SSIZE_MAX");
|
||||
__errordecl(__write_dest_size_error, "write called with size bigger than destination");
|
||||
__errordecl(__write_count_toobig_error, "write called with count > SSIZE_MAX");
|
||||
__errordecl(__readlink_dest_size_error, "readlink called with size bigger than destination");
|
||||
__errordecl(__readlink_size_toobig_error, "readlink called with size > SSIZE_MAX");
|
||||
__errordecl(__readlinkat_dest_size_error, "readlinkat called with size bigger than destination");
|
||||
__errordecl(__readlinkat_size_toobig_error, "readlinkat called with size > SSIZE_MAX");
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_N__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
char* getcwd(char* buf, size_t size) __overloadable {
|
||||
size_t bos = __bos(buf);
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __getcwd_real(buf, size);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(size) && (size > bos)) {
|
||||
__getcwd_dest_size_error();
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(size) && (size <= bos)) {
|
||||
return __getcwd_real(buf, size);
|
||||
}
|
||||
|
||||
return __getcwd_chk(buf, size, bos);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_M__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
|
||||
size_t bos = __bos0(buf);
|
||||
|
||||
if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
|
||||
__PREAD_PREFIX(count_toobig_error)();
|
||||
}
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __PREAD_PREFIX(real)(fd, buf, count, offset);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(count) && (count > bos)) {
|
||||
__PREAD_PREFIX(dest_size_error)();
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(count) && (count <= bos)) {
|
||||
return __PREAD_PREFIX(real)(fd, buf, count, offset);
|
||||
}
|
||||
|
||||
return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
|
||||
}
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) {
|
||||
size_t bos = __bos0(buf);
|
||||
|
||||
if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
|
||||
__pread64_count_toobig_error();
|
||||
}
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __pread64_real(fd, buf, count, offset);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(count) && (count > bos)) {
|
||||
__pread64_dest_size_error();
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(count) && (count <= bos)) {
|
||||
return __pread64_real(fd, buf, count, offset);
|
||||
}
|
||||
|
||||
return __pread64_chk(fd, buf, count, offset, bos);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_N__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) {
|
||||
size_t bos = __bos0(buf);
|
||||
|
||||
if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
|
||||
__PWRITE_PREFIX(count_toobig_error)();
|
||||
}
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __PWRITE_PREFIX(real)(fd, buf, count, offset);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(count) && (count > bos)) {
|
||||
__PWRITE_PREFIX(dest_size_error)();
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(count) && (count <= bos)) {
|
||||
return __PWRITE_PREFIX(real)(fd, buf, count, offset);
|
||||
}
|
||||
|
||||
return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
|
||||
}
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset) {
|
||||
size_t bos = __bos0(buf);
|
||||
|
||||
if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
|
||||
__pwrite64_count_toobig_error();
|
||||
}
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __pwrite64_real(fd, buf, count, offset);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(count) && (count > bos)) {
|
||||
__pwrite64_dest_size_error();
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(count) && (count <= bos)) {
|
||||
return __pwrite64_real(fd, buf, count, offset);
|
||||
}
|
||||
|
||||
return __pwrite64_chk(fd, buf, count, offset, bos);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_L__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t read(int fd, void* buf, size_t count) {
|
||||
size_t bos = __bos0(buf);
|
||||
|
||||
if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
|
||||
__read_count_toobig_error();
|
||||
}
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __read_real(fd, buf, count);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(count) && (count > bos)) {
|
||||
__read_dest_size_error();
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(count) && (count <= bos)) {
|
||||
return __read_real(fd, buf, count);
|
||||
}
|
||||
|
||||
return __read_chk(fd, buf, count, bos);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_N__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t write(int fd, const void* buf, size_t count) {
|
||||
size_t bos = __bos0(buf);
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __write_real(fd, buf, count);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(count) && (count > bos)) {
|
||||
__write_dest_size_error();
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(count) && (count <= bos)) {
|
||||
return __write_real(fd, buf, count);
|
||||
}
|
||||
|
||||
return __write_chk(fd, buf, count, bos);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_M__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t readlink(const char* path, char* buf, size_t size) {
|
||||
size_t bos = __bos(buf);
|
||||
|
||||
if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
|
||||
__readlink_size_toobig_error();
|
||||
}
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __readlink_real(path, buf, size);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(size) && (size > bos)) {
|
||||
__readlink_dest_size_error();
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(size) && (size <= bos)) {
|
||||
return __readlink_real(path, buf, size);
|
||||
}
|
||||
|
||||
return __readlink_chk(path, buf, size, bos);
|
||||
}
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size) {
|
||||
size_t bos = __bos(buf);
|
||||
|
||||
if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
|
||||
__readlinkat_size_toobig_error();
|
||||
}
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __readlinkat_real(dirfd, path, buf, size);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(size) && (size > bos)) {
|
||||
__readlinkat_dest_size_error();
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(size) && (size <= bos)) {
|
||||
return __readlinkat_real(dirfd, path, buf, size);
|
||||
}
|
||||
|
||||
return __readlinkat_chk(dirfd, path, buf, size, bos);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
|
||||
#endif /* defined(__clang__) */
|
||||
#undef __PREAD_PREFIX
|
||||
#undef __PWRITE_PREFIX
|
||||
#endif /* defined(__BIONIC_FORTIFY) */
|
||||
|
|
|
@ -51,8 +51,7 @@ int ioctl(int __fd, int __request, ...);
|
|||
* FIXME: __has_extension is more or less a clang version check. Remove it when
|
||||
* we don't need to support old clang code.
|
||||
*/
|
||||
#if defined(__clang__) && __has_extension(overloadable_unmarked) && \
|
||||
!defined(BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD)
|
||||
#if __has_extension(overloadable_unmarked) && !defined(BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD)
|
||||
/* enable_if(1) just exists to break overloading ties. */
|
||||
int ioctl(int __fd, unsigned __request, ...) __overloadable __enable_if(1, "") __RENAME(ioctl);
|
||||
#endif
|
||||
|
|
|
@ -44,15 +44,9 @@ _Static_assert(__generic(_Complex_I, float _Complex, 1, 0),
|
|||
#define I _Complex_I
|
||||
|
||||
#if __STDC_VERSION__ >= 201112L
|
||||
#ifdef __clang__
|
||||
#define CMPLX(x, y) ((double complex){ x, y })
|
||||
#define CMPLXF(x, y) ((float complex){ x, y })
|
||||
#define CMPLXL(x, y) ((long double complex){ x, y })
|
||||
#else
|
||||
#define CMPLX(x, y) __builtin_complex((double)(x), (double)(y))
|
||||
#define CMPLXF(x, y) __builtin_complex((float)(x), (float)(y))
|
||||
#define CMPLXL(x, y) __builtin_complex((long double)(x), (long double)(y))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
|
||||
__BEGIN_DECLS
|
||||
|
||||
// Remove the workaround once b/37423073 is fixed.
|
||||
#if defined(__clang__) && !__has_attribute(alloc_size)
|
||||
// Remove this workaround once b/37423073 is fixed.
|
||||
#if !__has_attribute(alloc_size)
|
||||
#define __BIONIC_ALLOC_SIZE(...)
|
||||
#else
|
||||
#define __BIONIC_ALLOC_SIZE(...) __attribute__((__alloc_size__(__VA_ARGS__)))
|
||||
|
|
|
@ -33,11 +33,7 @@
|
|||
#include <sys/cdefs.h>
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L && defined(_USING_LIBCXX)
|
||||
# ifdef __clang__
|
||||
# if __has_feature(cxx_atomic)
|
||||
# define _STDATOMIC_HAVE_ATOMIC
|
||||
# endif
|
||||
# else /* gcc */
|
||||
# if __has_feature(cxx_atomic)
|
||||
# define _STDATOMIC_HAVE_ATOMIC
|
||||
# endif
|
||||
#endif
|
||||
|
@ -150,20 +146,6 @@ using std::atomic_uintmax_t;
|
|||
# include <uchar.h> /* For char16_t and char32_t. */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __clang__
|
||||
# if __has_extension(c_atomic) || __has_extension(cxx_atomic)
|
||||
# define __CLANG_ATOMICS
|
||||
# else
|
||||
# error "stdatomic.h does not support your compiler"
|
||||
# endif
|
||||
# if __has_builtin(__sync_swap)
|
||||
# define __HAS_BUILTIN_SYNC_SWAP
|
||||
# endif
|
||||
#else
|
||||
# define __GNUC_ATOMICS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 7.17.1 Atomic lock-free macros.
|
||||
*/
|
||||
|
@ -203,13 +185,8 @@ using std::atomic_uintmax_t;
|
|||
* 7.17.2 Initialization.
|
||||
*/
|
||||
|
||||
#if defined(__CLANG_ATOMICS)
|
||||
#define ATOMIC_VAR_INIT(value) (value)
|
||||
#define atomic_init(obj, value) __c11_atomic_init(obj, value)
|
||||
#else
|
||||
#define ATOMIC_VAR_INIT(value) { .__val = (value) }
|
||||
#define atomic_init(obj, value) ((void)((obj)->__val = (value)))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Clang and recent GCC both provide predefined macros for the memory
|
||||
|
@ -258,63 +235,24 @@ typedef enum {
|
|||
* 7.17.4 Fences.
|
||||
*/
|
||||
|
||||
static __inline void
|
||||
atomic_thread_fence(memory_order __order __attribute__((unused)))
|
||||
{
|
||||
|
||||
#ifdef __CLANG_ATOMICS
|
||||
static __inline void atomic_thread_fence(memory_order __order __attribute__((unused))) {
|
||||
__c11_atomic_thread_fence(__order);
|
||||
#elif defined(__GNUC_ATOMICS)
|
||||
__atomic_thread_fence(__order);
|
||||
#else
|
||||
__sync_synchronize();
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline void
|
||||
atomic_signal_fence(memory_order __order __attribute__((unused)))
|
||||
{
|
||||
|
||||
#ifdef __CLANG_ATOMICS
|
||||
static __inline void atomic_signal_fence(memory_order __order __attribute__((unused))) {
|
||||
__c11_atomic_signal_fence(__order);
|
||||
#elif defined(__GNUC_ATOMICS)
|
||||
__atomic_signal_fence(__order);
|
||||
#else
|
||||
__asm volatile ("" ::: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* 7.17.5 Lock-free property.
|
||||
*/
|
||||
|
||||
#if defined(_KERNEL)
|
||||
/* Atomics in kernelspace are always lock-free. */
|
||||
#define atomic_is_lock_free(obj) \
|
||||
((void)(obj), (_Bool)1)
|
||||
#elif defined(__CLANG_ATOMICS)
|
||||
#define atomic_is_lock_free(obj) \
|
||||
__c11_atomic_is_lock_free(sizeof(*(obj)))
|
||||
#elif defined(__GNUC_ATOMICS)
|
||||
#define atomic_is_lock_free(obj) \
|
||||
__atomic_is_lock_free(sizeof((obj)->__val), &(obj)->__val)
|
||||
#else
|
||||
#define atomic_is_lock_free(obj) \
|
||||
((void)(obj), sizeof((obj)->__val) <= sizeof(void *))
|
||||
#endif
|
||||
#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj)))
|
||||
|
||||
/*
|
||||
* 7.17.6 Atomic integer types.
|
||||
*/
|
||||
|
||||
#ifndef __CLANG_ATOMICS
|
||||
/*
|
||||
* No native support for _Atomic(). Place object in structure to prevent
|
||||
* most forms of direct non-atomic access.
|
||||
*/
|
||||
#define _Atomic(T) struct { T volatile __val; }
|
||||
#endif
|
||||
|
||||
typedef _Atomic(bool) atomic_bool;
|
||||
typedef _Atomic(char) atomic_char;
|
||||
typedef _Atomic(signed char) atomic_schar;
|
||||
|
@ -363,7 +301,6 @@ typedef _Atomic(uintmax_t) atomic_uintmax_t;
|
|||
* Compiler-specific operations.
|
||||
*/
|
||||
|
||||
#if defined(__CLANG_ATOMICS)
|
||||
#define atomic_compare_exchange_strong_explicit(object, expected, \
|
||||
desired, success, failure) \
|
||||
__c11_atomic_compare_exchange_strong(object, expected, desired, \
|
||||
|
@ -388,91 +325,11 @@ typedef _Atomic(uintmax_t) atomic_uintmax_t;
|
|||
__c11_atomic_load(object, order)
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
__c11_atomic_store(object, desired, order)
|
||||
#elif defined(__GNUC_ATOMICS)
|
||||
#define atomic_compare_exchange_strong_explicit(object, expected, \
|
||||
desired, success, failure) \
|
||||
__atomic_compare_exchange_n(&(object)->__val, expected, \
|
||||
desired, 0, success, failure)
|
||||
#define atomic_compare_exchange_weak_explicit(object, expected, \
|
||||
desired, success, failure) \
|
||||
__atomic_compare_exchange_n(&(object)->__val, expected, \
|
||||
desired, 1, success, failure)
|
||||
#define atomic_exchange_explicit(object, desired, order) \
|
||||
__atomic_exchange_n(&(object)->__val, desired, order)
|
||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
||||
__atomic_fetch_add(&(object)->__val, operand, order)
|
||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
||||
__atomic_fetch_and(&(object)->__val, operand, order)
|
||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
||||
__atomic_fetch_or(&(object)->__val, operand, order)
|
||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
||||
__atomic_fetch_sub(&(object)->__val, operand, order)
|
||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
||||
__atomic_fetch_xor(&(object)->__val, operand, order)
|
||||
#define atomic_load_explicit(object, order) \
|
||||
__atomic_load_n(&(object)->__val, order)
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
__atomic_store_n(&(object)->__val, desired, order)
|
||||
#else
|
||||
#define __atomic_apply_stride(object, operand) \
|
||||
(((__typeof__((object)->__val))0) + (operand))
|
||||
#define atomic_compare_exchange_strong_explicit(object, expected, \
|
||||
desired, success, failure) __extension__ ({ \
|
||||
__typeof__(expected) __ep = (expected); \
|
||||
__typeof__(*__ep) __e = *__ep; \
|
||||
(void)(success); (void)(failure); \
|
||||
(bool)((*__ep = __sync_val_compare_and_swap(&(object)->__val, \
|
||||
__e, desired)) == __e); \
|
||||
})
|
||||
#define atomic_compare_exchange_weak_explicit(object, expected, \
|
||||
desired, success, failure) \
|
||||
atomic_compare_exchange_strong_explicit(object, expected, \
|
||||
desired, success, failure)
|
||||
#ifdef __HAS_BUILTIN_SYNC_SWAP
|
||||
/* Clang provides a full-barrier atomic exchange - use it if available. */
|
||||
#define atomic_exchange_explicit(object, desired, order) \
|
||||
((void)(order), __sync_swap(&(object)->__val, desired))
|
||||
#else
|
||||
/*
|
||||
* __sync_lock_test_and_set() is only an acquire barrier in theory (although in
|
||||
* practice it is usually a full barrier) so we need an explicit barrier before
|
||||
* it.
|
||||
*/
|
||||
#define atomic_exchange_explicit(object, desired, order) \
|
||||
__extension__ ({ \
|
||||
__typeof__(object) __o = (object); \
|
||||
__typeof__(desired) __d = (desired); \
|
||||
(void)(order); \
|
||||
__sync_synchronize(); \
|
||||
__sync_lock_test_and_set(&(__o)->__val, __d); \
|
||||
})
|
||||
#endif
|
||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
||||
((void)(order), __sync_fetch_and_add(&(object)->__val, \
|
||||
__atomic_apply_stride(object, operand)))
|
||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
||||
((void)(order), __sync_fetch_and_and(&(object)->__val, operand))
|
||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
||||
((void)(order), __sync_fetch_and_or(&(object)->__val, operand))
|
||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
||||
((void)(order), __sync_fetch_and_sub(&(object)->__val, \
|
||||
__atomic_apply_stride(object, operand)))
|
||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
||||
((void)(order), __sync_fetch_and_xor(&(object)->__val, operand))
|
||||
#define atomic_load_explicit(object, order) \
|
||||
((void)(order), __sync_fetch_and_add(&(object)->__val, 0))
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
((void)atomic_exchange_explicit(object, desired, order))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convenience functions.
|
||||
*
|
||||
* Don't provide these in kernel space. In kernel space, we should be
|
||||
* disciplined enough to always provide explicit barriers.
|
||||
*/
|
||||
|
||||
#ifndef _KERNEL
|
||||
#define atomic_compare_exchange_strong(object, expected, desired) \
|
||||
atomic_compare_exchange_strong_explicit(object, expected, \
|
||||
desired, memory_order_seq_cst, memory_order_seq_cst)
|
||||
|
@ -495,7 +352,6 @@ __extension__ ({ \
|
|||
atomic_load_explicit(object, memory_order_seq_cst)
|
||||
#define atomic_store(object, desired) \
|
||||
atomic_store_explicit(object, desired, memory_order_seq_cst)
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
/*
|
||||
* 7.17.8 Atomic flag type and operations.
|
||||
|
@ -510,36 +366,21 @@ typedef struct {
|
|||
|
||||
#define ATOMIC_FLAG_INIT { ATOMIC_VAR_INIT(false) }
|
||||
|
||||
static __inline bool
|
||||
atomic_flag_test_and_set_explicit(volatile atomic_flag *__object,
|
||||
memory_order __order)
|
||||
{
|
||||
static __inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag *__object, memory_order __order) {
|
||||
return (atomic_exchange_explicit(&__object->__flag, 1, __order));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
atomic_flag_clear_explicit(volatile atomic_flag *__object, memory_order __order)
|
||||
{
|
||||
|
||||
static __inline void atomic_flag_clear_explicit(volatile atomic_flag *__object, memory_order __order) {
|
||||
atomic_store_explicit(&__object->__flag, 0, __order);
|
||||
}
|
||||
|
||||
#ifndef _KERNEL
|
||||
static __inline bool
|
||||
atomic_flag_test_and_set(volatile atomic_flag *__object)
|
||||
{
|
||||
|
||||
return (atomic_flag_test_and_set_explicit(__object,
|
||||
memory_order_seq_cst));
|
||||
static __inline bool atomic_flag_test_and_set(volatile atomic_flag *__object) {
|
||||
return (atomic_flag_test_and_set_explicit(__object, memory_order_seq_cst));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
atomic_flag_clear(volatile atomic_flag *__object)
|
||||
{
|
||||
|
||||
static __inline void atomic_flag_clear(volatile atomic_flag *__object) {
|
||||
atomic_flag_clear_explicit(__object, memory_order_seq_cst);
|
||||
}
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
#endif /* <atomic> unavailable */
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ char* basename(const char* __path) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
|
|||
#endif
|
||||
|
||||
/* Const-correct overloads. Placed after FORTIFY so we call those functions, if possible. */
|
||||
#if defined(__cplusplus) && defined(__clang__)
|
||||
#if defined(__cplusplus)
|
||||
/*
|
||||
* Use two enable_ifs so these overloads don't conflict with + are preferred over libcxx's. This can
|
||||
* be reduced to 1 after libcxx recognizes that we have const-correct overloads.
|
||||
|
|
|
@ -155,25 +155,12 @@
|
|||
|
||||
#define __wur __attribute__((__warn_unused_result__))
|
||||
|
||||
#ifdef __clang__
|
||||
# define __errorattr(msg) __attribute__((unavailable(msg)))
|
||||
# define __warnattr(msg) __attribute__((deprecated(msg)))
|
||||
# define __warnattr_real(msg) __attribute__((deprecated(msg)))
|
||||
# define __enable_if(cond, msg) __attribute__((enable_if(cond, msg)))
|
||||
# define __clang_error_if(cond, msg) __attribute__((diagnose_if(cond, msg, "error")))
|
||||
# define __clang_warning_if(cond, msg) __attribute__((diagnose_if(cond, msg, "warning")))
|
||||
#else
|
||||
# define __errorattr(msg) __attribute__((__error__(msg)))
|
||||
# define __warnattr(msg) __attribute__((__warning__(msg)))
|
||||
# define __warnattr_real __warnattr
|
||||
/* enable_if doesn't exist on other compilers; give an error if it's used. */
|
||||
/* diagnose_if doesn't exist either, but it's often tagged on non-clang-specific functions */
|
||||
# define __clang_error_if(cond, msg)
|
||||
# define __clang_warning_if(cond, msg)
|
||||
|
||||
/* errordecls really don't work as well in clang as they do in GCC. */
|
||||
# define __errordecl(name, msg) extern void name(void) __errorattr(msg)
|
||||
#endif
|
||||
#define __errorattr(msg) __attribute__((unavailable(msg)))
|
||||
#define __warnattr(msg) __attribute__((deprecated(msg)))
|
||||
#define __warnattr_real(msg) __attribute__((deprecated(msg)))
|
||||
#define __enable_if(cond, msg) __attribute__((enable_if(cond, msg)))
|
||||
#define __clang_error_if(cond, msg) __attribute__((diagnose_if(cond, msg, "error")))
|
||||
#define __clang_warning_if(cond, msg) __attribute__((diagnose_if(cond, msg, "warning")))
|
||||
|
||||
#if defined(ANDROID_STRICT)
|
||||
/*
|
||||
|
@ -274,17 +261,13 @@
|
|||
#define __BIONIC_FORTIFY_UNKNOWN_SIZE ((size_t) -1)
|
||||
|
||||
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
|
||||
# if defined(__clang__)
|
||||
/*
|
||||
* FORTIFY's _chk functions effectively disable ASAN's stdlib interceptors.
|
||||
* Additionally, the static analyzer/clang-tidy try to pattern match some
|
||||
* standard library functions, and FORTIFY sometimes interferes with this. So,
|
||||
* we turn FORTIFY off in both cases.
|
||||
*/
|
||||
# if !__has_feature(address_sanitizer) && !defined(__clang_analyzer__)
|
||||
# define __BIONIC_FORTIFY 1
|
||||
# endif
|
||||
# elif defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
|
||||
# if !__has_feature(address_sanitizer) && !defined(__clang_analyzer__)
|
||||
# define __BIONIC_FORTIFY 1
|
||||
# endif
|
||||
#endif
|
||||
|
@ -306,40 +289,27 @@
|
|||
|
||||
#if defined(__BIONIC_FORTIFY)
|
||||
# define __bos0(s) __bosn((s), 0)
|
||||
# if defined(__clang__)
|
||||
# define __pass_object_size_n(n) __attribute__((pass_object_size(n)))
|
||||
# define __pass_object_size_n(n) __attribute__((pass_object_size(n)))
|
||||
/*
|
||||
* FORTIFY'ed functions all have either enable_if or pass_object_size, which
|
||||
* makes taking their address impossible. Saying (&read)(foo, bar, baz); will
|
||||
* therefore call the unFORTIFYed version of read.
|
||||
*/
|
||||
# define __call_bypassing_fortify(fn) (&fn)
|
||||
# define __call_bypassing_fortify(fn) (&fn)
|
||||
/*
|
||||
* Because clang-FORTIFY uses overloads, we can't mark functions as `extern
|
||||
* inline` without making them available externally.
|
||||
*/
|
||||
# define __BIONIC_FORTIFY_INLINE static __inline__ __always_inline
|
||||
# define __BIONIC_FORTIFY_INLINE static __inline__ __always_inline
|
||||
/*
|
||||
* We should use __BIONIC_FORTIFY_VARIADIC instead of __BIONIC_FORTIFY_INLINE
|
||||
* for variadic functions because compilers cannot inline them.
|
||||
* The __always_inline attribute is useless, misleading, and could trigger
|
||||
* clang compiler bug to incorrectly inline variadic functions.
|
||||
*/
|
||||
# define __BIONIC_FORTIFY_VARIADIC static __inline__
|
||||
# define __BIONIC_FORTIFY_VARIADIC static __inline__
|
||||
/* Error functions don't have bodies, so they can just be static. */
|
||||
# define __BIONIC_ERROR_FUNCTION_VISIBILITY static
|
||||
# else
|
||||
/*
|
||||
* Where they can, GCC and clang-style FORTIFY share implementations.
|
||||
* So, make these nops in GCC.
|
||||
*/
|
||||
# define __pass_object_size_n(n)
|
||||
# define __call_bypassing_fortify(fn) (fn)
|
||||
/* __BIONIC_FORTIFY_NONSTATIC_INLINE is pointless in GCC's FORTIFY */
|
||||
# define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline)) __attribute__((__artificial__))
|
||||
/* __always_inline is probably okay and ignored by gcc in __BIONIC_FORTIFY_VARIADIC */
|
||||
# define __BIONIC_FORTIFY_VARIADIC __BIONIC_FORTIFY_INLINE
|
||||
# endif
|
||||
# define __BIONIC_ERROR_FUNCTION_VISIBILITY static
|
||||
#else
|
||||
/* Further increase sharing for some inline functions */
|
||||
# define __pass_object_size_n(n)
|
||||
|
@ -351,11 +321,7 @@
|
|||
# define __BIONIC_INCLUDE_FORTIFY_HEADERS 1
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
# define __overloadable __attribute__((overloadable))
|
||||
#else
|
||||
# define __overloadable
|
||||
#endif
|
||||
#define __overloadable __attribute__((overloadable))
|
||||
|
||||
/* Used to tag non-static symbols that are private and never exposed by the shared library. */
|
||||
#define __LIBC_HIDDEN__ __attribute__((visibility("hidden")))
|
||||
|
@ -388,7 +354,6 @@ int __size_mul_overflow(__SIZE_TYPE__ a, __SIZE_TYPE__ b, __SIZE_TYPE__ *result)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
/*
|
||||
* Used when we need to check for overflow when multiplying x and y. This
|
||||
* should only be used where __size_mul_overflow can not work, because it makes
|
||||
|
@ -397,6 +362,5 @@ int __size_mul_overflow(__SIZE_TYPE__ a, __SIZE_TYPE__ b, __SIZE_TYPE__ *result)
|
|||
* __size_mul_overflow.
|
||||
*/
|
||||
#define __unsafe_check_mul_overflow(x, y) ((__SIZE_TYPE__)-1 / (x) < (y))
|
||||
#endif
|
||||
|
||||
#endif /* !_SYS_CDEFS_H_ */
|
||||
|
|
|
@ -56,14 +56,7 @@ __BEGIN_DECLS
|
|||
* preserve the old behavior for GCC and emit a useful diagnostic.
|
||||
*/
|
||||
#if defined(__USE_FILE_OFFSET64)
|
||||
void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset)
|
||||
# if !defined(__clang__) && __ANDROID_API__ < __ANDROID_API_L__
|
||||
__attribute__((error("mmap is not available with _FILE_OFFSET_BITS=64 when using GCC until "
|
||||
"android-21. Either raise your minSdkVersion, disable "
|
||||
"_FILE_OFFSET_BITS=64, or switch to Clang.")));
|
||||
# else
|
||||
__RENAME(mmap64);
|
||||
# endif
|
||||
void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset) __RENAME(mmap64);
|
||||
#else
|
||||
void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset);
|
||||
#endif
|
||||
|
|
|
@ -62,25 +62,6 @@ ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x
|
|||
# Some of these are intentionally using = instead of := since we need access to
|
||||
# some variables not initialtized until we're in the build system.
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := \
|
||||
$(LOCAL_PATH)/Android.mk \
|
||||
$(LOCAL_PATH)/file-check-cxx \
|
||||
| $(HOST_OUT_EXECUTABLES)/FileCheck$(HOST_EXECUTABLE_SUFFIX) \
|
||||
|
||||
LOCAL_CXX = $(LOCAL_PATH)/file-check-cxx \
|
||||
$(HOST_OUT_EXECUTABLES)/FileCheck \
|
||||
$($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_CXX) \
|
||||
GCC \
|
||||
|
||||
LOCAL_CLANG := false
|
||||
LOCAL_MODULE := bionic-compile-time-tests-g++
|
||||
LOCAL_CPPFLAGS := -Wall -Werror
|
||||
# Disable color diagnostics so the warnings output matches the source
|
||||
LOCAL_CPPFLAGS += -fdiagnostics-color=never
|
||||
LOCAL_SRC_FILES := fortify_filecheck_diagnostics_test.cpp
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := \
|
||||
$(LOCAL_PATH)/Android.mk \
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
* bionic/tests/file-check-cxx out/host/linux-x86/bin/FileCheck \
|
||||
* prebuilts/clang/host/linux-x86/clang-4053586/bin/clang++ CLANG -I bionic/tests -I ...
|
||||
*
|
||||
* If you delete everything before clang++ and delete "CLANG" (or "GCC" if gcc is failing), then
|
||||
* you'll end up with:
|
||||
* If you delete everything before clang++ and delete "CLANG", then you'll end up with:
|
||||
*
|
||||
* prebuilts/clang/host/linux-x86/clang-4053586/bin/clang++ -I bionic/tests -I ...
|
||||
*
|
||||
|
@ -48,13 +47,10 @@ void test_sprintf() {
|
|||
char buf[4];
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to int __builtin___sprintf_chk(char*, int, {{(long )?}}unsigned int, const char*, ...) will always overflow destination buffer
|
||||
// CLANG: error: call to unavailable function 'sprintf': format string will always overflow destination buffer
|
||||
sprintf(buf, "foobar"); // NOLINT(runtime/printf)
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to int __builtin___sprintf_chk(char*, int, {{(long )?}}unsigned int, const char*, ...) will always overflow destination buffer
|
||||
// clang should emit a warning, but doesn't
|
||||
// TODO: clang should emit a warning, but doesn't
|
||||
sprintf(buf, "%s", "foobar"); // NOLINT(runtime/printf)
|
||||
}
|
||||
|
||||
|
@ -62,31 +58,22 @@ void test_snprintf() {
|
|||
char buf[4];
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to int __builtin___snprintf_chk(char*, {{(long )?}}unsigned int, int, {{(long )?}}unsigned int, const char*, ...) will always overflow destination buffer
|
||||
// CLANG: error: call to unavailable function 'snprintf': format string will always overflow destination buffer
|
||||
snprintf(buf, 5, "foobar"); // NOLINT(runtime/printf)
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to int __builtin___snprintf_chk(char*, {{(long )?}}unsigned int, int, {{(long )?}}unsigned int, const char*, ...) will always overflow destination buffer
|
||||
// clang should emit a warning, but doesn't
|
||||
// TODO: clang should emit a warning, but doesn't
|
||||
snprintf(buf, 5, "%s", "foobar"); // NOLINT(runtime/printf)
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to int __builtin___snprintf_chk(char*, {{(long )?}}unsigned int, int, {{(long )?}}unsigned int, const char*, ...) will always overflow destination buffer
|
||||
// clang should emit a warning, but doesn't
|
||||
// TODO: clang should emit a warning, but doesn't
|
||||
snprintf(buf, 5, " %s ", "foobar"); // NOLINT(runtime/printf)
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to int __builtin___snprintf_chk(char*, {{(long )?}}unsigned int, int, {{(long )?}}unsigned int, const char*, ...) will always overflow destination buffer
|
||||
// clang should emit a warning, but doesn't
|
||||
// TODO: clang should emit a warning, but doesn't
|
||||
snprintf(buf, 5, "%d", 100000); // NOLINT(runtime/printf)
|
||||
}
|
||||
|
||||
void test_memcpy() {
|
||||
char buf[4];
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to void* __builtin___memcpy_chk(void*, const void*, {{(long )?}}unsigned int, {{(long )?}}unsigned int) will always overflow destination buffer
|
||||
// CLANG: error: 'memcpy' called with size bigger than buffer
|
||||
memcpy(buf, "foobar", sizeof("foobar") + 100);
|
||||
}
|
||||
|
@ -94,8 +81,6 @@ void test_memcpy() {
|
|||
void test_memmove() {
|
||||
char buf[4];
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to void* __builtin___memmove_chk(void*, const void*, {{(long )?}}unsigned int, {{(long )?}}unsigned int) will always overflow destination buffer
|
||||
// CLANG: error: 'memmove' called with size bigger than buffer
|
||||
memmove(buf, "foobar", sizeof("foobar"));
|
||||
}
|
||||
|
@ -103,8 +88,6 @@ void test_memmove() {
|
|||
void test_memset() {
|
||||
char buf[4];
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to void* __builtin___memset_chk(void*, int, {{(long )?}}unsigned int, {{(long )?}}unsigned int) will always overflow destination buffer
|
||||
// CLANG: error: 'memset' called with size bigger than buffer
|
||||
memset(buf, 0, 6);
|
||||
}
|
||||
|
@ -112,13 +95,9 @@ void test_memset() {
|
|||
void test_strcpy() {
|
||||
char buf[4];
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to {{(char\* __builtin___strcpy_chk\(char\*, const char\*, unsigned int\))|(void\* __builtin___memcpy_chk\(void\*, const void\*, (long )?unsigned int, (long )?unsigned int\))}} will always overflow destination buffer
|
||||
// CLANG: error: 'strcpy' called with string bigger than buffer
|
||||
strcpy(buf, "foobar"); // NOLINT(runtime/printf)
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to {{(char\* __builtin___strcpy_chk\(char\*, const char\*, unsigned int\))|(void\* __builtin___memcpy_chk\(void\*, const void\*, (long )?unsigned int, (long )?unsigned int\))}} will always overflow destination buffer
|
||||
// CLANG: error: 'strcpy' called with string bigger than buffer
|
||||
strcpy(buf, "quux");
|
||||
}
|
||||
|
@ -126,13 +105,9 @@ void test_strcpy() {
|
|||
void test_stpcpy() {
|
||||
char buf[4];
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to char* __builtin___stpcpy_chk(char*, const char*, {{(long )?}}unsigned int) will always overflow destination buffer
|
||||
// CLANG: error: 'stpcpy' called with string bigger than buffer
|
||||
stpcpy(buf, "foobar");
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to char* __builtin___stpcpy_chk(char*, const char*, {{(long )?}}unsigned int) will always overflow destination buffer
|
||||
// CLANG: error: 'stpcpy' called with string bigger than buffer
|
||||
stpcpy(buf, "quux");
|
||||
}
|
||||
|
@ -140,28 +115,21 @@ void test_stpcpy() {
|
|||
void test_strncpy() {
|
||||
char buf[4];
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to char* __builtin___strncpy_chk(char*, const char*, {{(long )?}}unsigned int, {{(long )?}}unsigned int) will always overflow destination buffer
|
||||
// clang should emit a warning, but doesn't
|
||||
// TODO: clang should emit a warning, but doesn't
|
||||
strncpy(buf, "foobar", sizeof("foobar"));
|
||||
}
|
||||
|
||||
void test_strcat() {
|
||||
char buf[4] = "";
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to {{(char\* __builtin___strcat_chk\(char\*, const char\*, unsigned int\))|(void\* __builtin___memcpy_chk\(void\*, const void\*, (long )?unsigned int, (long )?unsigned int\))}} will always overflow destination buffer
|
||||
// clang should emit a warning, but doesn't
|
||||
// TODO: clang should emit a warning, but doesn't
|
||||
strcat(buf, "foobar"); // NOLINT(runtime/printf)
|
||||
}
|
||||
|
||||
void test_strncat() {
|
||||
char buf[4] = "";
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to {{(char\* __builtin___strcat_chk\(char\*, const char\*, unsigned int\))|(void\* __builtin___memcpy_chk\(void\*, const void\*, (long )?unsigned int, (long )?unsigned int\))}} will always overflow destination buffer
|
||||
// gcc output warning with __builtin___strcat_chk for __builtin___strncat_chk.
|
||||
// clang should emit a warning, but doesn't
|
||||
// TODO: clang should emit a warning, but doesn't
|
||||
strncat(buf, "foobar", sizeof("foobar"));
|
||||
}
|
||||
|
||||
|
@ -170,8 +138,6 @@ void test_vsprintf(const char* fmt, ...) {
|
|||
char buf[4];
|
||||
va_start(va, fmt);
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to int __builtin___vsprintf_chk(char*, int, {{(long )?}}unsigned int, const char*, {{(__va_list)|(void\*)|(char\*)|(__va_list_tag\*)}}) will always overflow destination buffer
|
||||
// clang should emit a warning, but doesn't
|
||||
vsprintf(buf, "foobar", va);
|
||||
va_end(va);
|
||||
|
@ -182,8 +148,6 @@ void test_vsnprintf(const char* fmt, ...) {
|
|||
char buf[4];
|
||||
va_start(va, fmt);
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: warning: call to int __builtin___vsnprintf_chk(char*, {{(long )?}}unsigned int, int, {{(long )?}}unsigned int, const char*, {{(__va_list)|(void\*)|(char\*)|(__va_list_tag\*)}}) will always overflow destination buffer
|
||||
// clang should emit a warning, but doesn't
|
||||
vsnprintf(buf, 5, "foobar", va); // NOLINT(runtime/printf)
|
||||
|
||||
|
@ -193,13 +157,9 @@ void test_vsnprintf(const char* fmt, ...) {
|
|||
void test_fgets() {
|
||||
char buf[4];
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__fgets_too_small_error' declared with attribute error: fgets called with size less than zero
|
||||
// CLANG: error: in call to 'fgets', size should not be negative
|
||||
fgets(buf, -1, stdin);
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__fgets_too_big_error' declared with attribute error: fgets called with size bigger than buffer
|
||||
// CLANG: error: in call to 'fgets', size is larger than the destination buffer
|
||||
fgets(buf, 6, stdin);
|
||||
}
|
||||
|
@ -208,8 +168,6 @@ void test_recvfrom() {
|
|||
char buf[4];
|
||||
sockaddr_in addr;
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__recvfrom_error' declared with attribute error: 'recvfrom' called with size bigger than buffer
|
||||
// CLANG: error: 'recvfrom' called with size bigger than buffer
|
||||
recvfrom(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), NULL);
|
||||
}
|
||||
|
@ -217,43 +175,31 @@ void test_recvfrom() {
|
|||
void test_recv() {
|
||||
char buf[4] = {0};
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__recvfrom_error' declared with attribute error: 'recvfrom' called with size bigger than buffer
|
||||
// CLANG: error: 'recv' called with size bigger than buffer
|
||||
recv(0, buf, 6, 0);
|
||||
}
|
||||
|
||||
void test_umask() {
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__umask_invalid_mode' declared with attribute error: 'umask' called with invalid mode
|
||||
// CLANG: error: 'umask' called with invalid mode
|
||||
umask(01777);
|
||||
}
|
||||
|
||||
void test_read() {
|
||||
char buf[4];
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__read_dest_size_error' declared with attribute error: read called with size bigger than destination
|
||||
// CLANG: error: in call to 'read', 'count' bytes overflows the given object
|
||||
read(0, buf, 6);
|
||||
}
|
||||
|
||||
void test_open() {
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__creat_missing_mode' declared with attribute error: called with O_CREAT or O_TMPFILE, but missing mode
|
||||
// CLANG: error: 'open' called with O_CREAT or O_TMPFILE, but missing mode
|
||||
open("/dev/null", O_CREAT);
|
||||
|
||||
// GCC: error: call to '__creat_missing_mode' declared with attribute error: called with O_CREAT or O_TMPFILE, but missing mode
|
||||
// CLANG: error: 'open' called with O_CREAT or O_TMPFILE, but missing mode
|
||||
open("/dev/null", O_TMPFILE);
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__creat_too_many_args' declared with attribute error: too many arguments
|
||||
// CLANG: error: call to unavailable function 'open': too many arguments
|
||||
open("/dev/null", O_CREAT, 0, 0);
|
||||
|
||||
// GCC: error: call to '__creat_too_many_args' declared with attribute error: too many arguments
|
||||
// CLANG: error: call to unavailable function 'open': too many arguments
|
||||
open("/dev/null", O_TMPFILE, 0, 0);
|
||||
|
||||
|
@ -266,8 +212,6 @@ void test_open() {
|
|||
|
||||
void test_poll() {
|
||||
pollfd fds[1];
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__poll_too_small_error' declared with attribute error: poll: pollfd array smaller than fd count
|
||||
// CLANG: error: in call to 'poll', fd_count is larger than the given buffer
|
||||
poll(fds, 2, 0);
|
||||
}
|
||||
|
@ -275,8 +219,6 @@ void test_poll() {
|
|||
void test_ppoll() {
|
||||
pollfd fds[1];
|
||||
timespec timeout;
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__ppoll_too_small_error' declared with attribute error: ppoll: pollfd array smaller than fd count
|
||||
// CLANG: error: in call to 'ppoll', fd_count is larger than the given buffer
|
||||
ppoll(fds, 2, &timeout, nullptr);
|
||||
}
|
||||
|
@ -291,8 +233,6 @@ void test_ppoll64() {
|
|||
|
||||
void test_fread_overflow() {
|
||||
char buf[4];
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__fread_overflow' declared with attribute error: fread called with overflowing size * count
|
||||
// CLANG: error: in call to 'fread', size * count overflows
|
||||
fread(buf, 2, (size_t)-1, stdin);
|
||||
}
|
||||
|
@ -300,16 +240,12 @@ void test_fread_overflow() {
|
|||
void test_fread_too_big() {
|
||||
char buf[4];
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__fread_too_big_error' declared with attribute error: fread called with size * count bigger than buffer
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// CLANG: error: in call to 'fread', size * count is too large for the given buffer
|
||||
fread(buf, 1, 5, stdin);
|
||||
}
|
||||
|
||||
void test_fwrite_overflow() {
|
||||
char buf[4] = {0};
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__fwrite_overflow' declared with attribute error: fwrite called with overflowing size * count
|
||||
// CLANG: error: in call to 'fwrite', size * count overflows
|
||||
fwrite(buf, 2, (size_t)-1, stdout);
|
||||
}
|
||||
|
@ -317,48 +253,36 @@ void test_fwrite_overflow() {
|
|||
void test_fwrite_too_big() {
|
||||
char buf[4] = {0};
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__fwrite_too_big_error' declared with attribute error: fwrite called with size * count bigger than buffer
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// CLANG: error: in call to 'fwrite', size * count is too large for the given buffer
|
||||
fwrite(buf, 1, 5, stdout);
|
||||
}
|
||||
|
||||
void test_getcwd() {
|
||||
char buf[4];
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__getcwd_dest_size_error' declared with attribute error: getcwd called with size bigger than destination
|
||||
// CLANG: error: in call to 'getcwd', 'size' bytes overflows the given object
|
||||
getcwd(buf, 5);
|
||||
}
|
||||
|
||||
void test_pwrite64_size() {
|
||||
char buf[4] = {0};
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__pwrite64_dest_size_error' declared with attribute error: pwrite64 called with size bigger than destination
|
||||
// CLANG: error: in call to 'pwrite64', 'count' bytes overflows the given object
|
||||
pwrite64(STDOUT_FILENO, buf, 5, 0);
|
||||
}
|
||||
|
||||
void test_pwrite64_too_big_malloc() {
|
||||
void *buf = calloc(atoi("5"), 1);
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__pwrite64_count_toobig_error' declared with attribute error: pwrite64 called with count > SSIZE_MAX
|
||||
// clang should emit a warning, but probably never will.
|
||||
pwrite64(STDOUT_FILENO, buf, SIZE_MAX, 0);
|
||||
}
|
||||
|
||||
void test_pwrite64_too_big() {
|
||||
char buf[4] = {0};
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__pwrite64_count_toobig_error' declared with attribute error: pwrite64 called with count > SSIZE_MAX
|
||||
// CLANG: error: in call to 'pwrite64', 'count' must be <= SSIZE_MAX
|
||||
pwrite64(STDOUT_FILENO, buf, SIZE_MAX, 0);
|
||||
}
|
||||
|
||||
void test_write_size() {
|
||||
char buf[4] = {0};
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__write_dest_size_error' declared with attribute error: write called with size bigger than destination
|
||||
// CLANG: error: in call to 'write', 'count' bytes overflows the given object
|
||||
write(STDOUT_FILENO, buf, 5);
|
||||
}
|
||||
|
@ -374,8 +298,6 @@ void test_sendto() {
|
|||
char buf[4] = {0};
|
||||
sockaddr_in addr;
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__sendto_error' declared with attribute error: 'sendto' called with size bigger than buffer
|
||||
// CLANG: error: 'sendto' called with size bigger than buffer
|
||||
sendto(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), sizeof(sockaddr_in));
|
||||
}
|
||||
|
@ -383,8 +305,6 @@ void test_sendto() {
|
|||
void test_send() {
|
||||
char buf[4] = {0};
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__sendto_error' declared with attribute error: 'sendto' called with size bigger than buffer
|
||||
// CLANG: error: 'send' called with size bigger than buffer
|
||||
send(0, buf, 6, 0);
|
||||
}
|
||||
|
@ -392,8 +312,6 @@ void test_send() {
|
|||
void test_realpath() {
|
||||
char buf[4] = {0};
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// GCC: error: call to '__realpath_size_error' declared with attribute error: 'realpath' output parameter must be NULL or a pointer to a buffer with >= PATH_MAX bytes
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// CLANG: error: 'realpath' output parameter must be NULL or a pointer to a buffer with >= PATH_MAX bytes
|
||||
realpath(".", buf);
|
||||
|
||||
|
|
Loading…
Reference in a new issue