Merge "Revert "Remove workarounds for the llvm sanitizers.""
diff --git a/docs/status.md b/docs/status.md
index 20a1309..5d2603a 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -36,13 +36,17 @@
* `<monetary.h>`. See
[discussion](https://github.com/android/ndk/issues/1182).
* `<wordexp.h>`
+ * Locales. Although bionic contains the various `_l()` functions, the only
+ locale supported is a UTF-8 C/POSIX locale. Most of the POSIX APIs are
+ insufficient to support the wide range of languages used by Android users,
+ and apps should use icu4c (or do their i18n work in Java) instead.
+ * Robust mutexes. See
+ [discussion](https://github.com/android/ndk/issues/1181).
* Thread cancellation (`pthread_cancel`). Unlikely to ever be implemented
because of the difficulty and cost of implementing it, and the difficulty
of using it correctly. See
[This is why we can't have safe cancellation points](https://lwn.net/Articles/683118/)
for more about thread cancellation.
- * Robust mutexes. See
- [discussion](https://github.com/android/ndk/issues/1181).
Run `./libc/tools/check-symbols-glibc.py` in bionic/ for the current
list of POSIX functions implemented by glibc but not by bionic.
diff --git a/libc/Android.bp b/libc/Android.bp
index 82fc0bc..cd53906 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -782,7 +782,6 @@
arch: {
arm: {
cflags: [
- "-DHAVE_ASSEMBLER___MEMCPY_CHK",
"-DRENAME___STRCAT_CHK",
"-DRENAME___STRCPY_CHK",
],
@@ -809,7 +808,6 @@
],
},
arm64: {
- cflags: ["-DHAVE_ASSEMBLER___MEMCPY_CHK"],
srcs: [
"arch-arm64/string/__memcpy_chk.S",
"arch-arm64/string/__memset_chk.S",
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index 4317a56..73cf973 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -489,8 +489,9 @@
return strcpy(dst, src);
}
-#if !defined(HAVE_ASSEMBLER___MEMCPY_CHK)
+#if !defined(__arm__) && !defined(__aarch64__)
// Runtime implementation of __memcpy_chk (used directly by compiler, not in headers).
+// arm32 and arm64 have assembler implementations, and don't need this C fallback.
extern "C" void* __memcpy_chk(void* dst, const void* src, size_t count, size_t dst_len) {
__check_count("memcpy", "count", count);
__check_buffer_access("memcpy", "write into", count, dst_len);
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 4aa27f9..06ed3f4 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -49,82 +49,82 @@
__noreturn void _Exit(int) __RENAME(_exit);
#endif
-int atexit(void (*__fn)(void));
+int atexit(void (* _Nonnull __fn)(void));
-int at_quick_exit(void (*__fn)(void)) __INTRODUCED_IN(21);
+int at_quick_exit(void (* _Nonnull __fn)(void)) __INTRODUCED_IN(21);
void quick_exit(int __status) __noreturn __INTRODUCED_IN(21);
-char* getenv(const char* __name);
-int putenv(char* __assignment);
-int setenv(const char* __name, const char* __value, int __overwrite);
-int unsetenv(const char* __name);
+char* _Nullable getenv(const char* _Nonnull __name);
+int putenv(char* _Nonnull __assignment);
+int setenv(const char* _Nonnull __name, const char* _Nonnull __value, int __overwrite);
+int unsetenv(const char* _Nonnull __name);
int clearenv(void);
-char* mkdtemp(char* __template);
-char* mktemp(char* __template) __attribute__((deprecated("mktemp is unsafe, use mkstemp or tmpfile instead")));
+char* _Nullable mkdtemp(char* _Nonnull __template);
+char* _Nullable mktemp(char* _Nonnull __template) __attribute__((deprecated("mktemp is unsafe, use mkstemp or tmpfile instead")));
-int mkostemp64(char* __template, int __flags) __INTRODUCED_IN(23);
-int mkostemp(char* __template, int __flags) __INTRODUCED_IN(23);
-int mkostemps64(char* __template, int __suffix_length, int __flags) __INTRODUCED_IN(23);
-int mkostemps(char* __template, int __suffix_length, int __flags) __INTRODUCED_IN(23);
-int mkstemp64(char* __template) __INTRODUCED_IN(21);
-int mkstemp(char* __template);
-int mkstemps64(char* __template, int __flags) __INTRODUCED_IN(23);
-int mkstemps(char* __template, int __flags);
+int mkostemp64(char* _Nonnull __template, int __flags) __INTRODUCED_IN(23);
+int mkostemp(char* _Nonnull __template, int __flags) __INTRODUCED_IN(23);
+int mkostemps64(char* _Nonnull __template, int __suffix_length, int __flags) __INTRODUCED_IN(23);
+int mkostemps(char* _Nonnull __template, int __suffix_length, int __flags) __INTRODUCED_IN(23);
+int mkstemp64(char* _Nonnull __template) __INTRODUCED_IN(21);
+int mkstemp(char* _Nonnull __template);
+int mkstemps64(char* _Nonnull __template, int __flags) __INTRODUCED_IN(23);
+int mkstemps(char* _Nonnull __template, int __flags);
-long strtol(const char* __s, char** __end_ptr, int __base);
-long long strtoll(const char* __s, char** __end_ptr, int __base);
-unsigned long strtoul(const char* __s, char** __end_ptr, int __base);
-unsigned long long strtoull(const char* __s, char** __end_ptr, int __base);
+long strtol(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base);
+long long strtoll(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base);
+unsigned long strtoul(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base);
+unsigned long long strtoull(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base);
-int posix_memalign(void** __memptr, size_t __alignment, size_t __size) __INTRODUCED_IN(17);
+int posix_memalign(void* _Nullable * _Nullable __memptr, size_t __alignment, size_t __size) __INTRODUCED_IN(17);
-void* aligned_alloc(size_t __alignment, size_t __size) __INTRODUCED_IN(28);
+void* _Nullable aligned_alloc(size_t __alignment, size_t __size) __INTRODUCED_IN(28);
-double strtod(const char* __s, char** __end_ptr);
-long double strtold(const char* __s, char** __end_ptr) __RENAME_LDBL(strtod, 3, 21);
+double strtod(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr);
+long double strtold(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr) __RENAME_LDBL(strtod, 3, 21);
-unsigned long strtoul_l(const char* __s, char** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(26);
+unsigned long strtoul_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(26);
-int atoi(const char* __s) __attribute_pure__;
-long atol(const char* __s) __attribute_pure__;
-long long atoll(const char* __s) __attribute_pure__;
+int atoi(const char* _Nonnull __s) __attribute_pure__;
+long atol(const char* _Nonnull __s) __attribute_pure__;
+long long atoll(const char* _Nonnull __s) __attribute_pure__;
-__wur char* realpath(const char* __path, char* __resolved);
-int system(const char* __command);
+__wur char* _Nullable realpath(const char* _Nonnull __path, char* _Nullable __resolved);
+int system(const char* _Nonnull __command);
-void* bsearch(const void* __key, const void* __base, size_t __nmemb, size_t __size, int (*__comparator)(const void* __lhs, const void* __rhs));
+void* _Nullable bsearch(const void* _Nonnull __key, const void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull __lhs, const void* _Nonnull __rhs));
-void qsort(void* __base, size_t __nmemb, size_t __size, int (*__comparator)(const void* __lhs, const void* __rhs));
+void qsort(void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull __lhs, const void* _Nonnull __rhs));
uint32_t arc4random(void);
uint32_t arc4random_uniform(uint32_t __upper_bound);
-void arc4random_buf(void* __buf, size_t __n);
+void arc4random_buf(void* _Nonnull __buf, size_t __n);
#define RAND_MAX 0x7fffffff
-int rand_r(unsigned int* __seed_ptr) __INTRODUCED_IN(21);
+int rand_r(unsigned int* _Nonnull __seed_ptr) __INTRODUCED_IN(21);
double drand48(void);
-double erand48(unsigned short __xsubi[3]);
-long jrand48(unsigned short __xsubi[3]);
-void lcong48(unsigned short __param[7]) __INTRODUCED_IN(23);
+double erand48(unsigned short __xsubi[_Nonnull 3]);
+long jrand48(unsigned short __xsubi[_Nonnull 3]);
+void lcong48(unsigned short __param[_Nonnull 7]) __INTRODUCED_IN(23);
long lrand48(void);
long mrand48(void);
-long nrand48(unsigned short __xsubi[3]);
-unsigned short* seed48(unsigned short __seed16v[3]);
+long nrand48(unsigned short __xsubi[_Nonnull 3]);
+unsigned short* _Nonnull seed48(unsigned short __seed16v[_Nonnull 3]);
void srand48(long __seed);
-char* initstate(unsigned int __seed, char* __state, size_t __n) __INTRODUCED_IN(21);
-char* setstate(char* __state) __INTRODUCED_IN(21);
+char* _Nullable initstate(unsigned int __seed, char* _Nonnull __state, size_t __n) __INTRODUCED_IN(21);
+char* _Nullable setstate(char* _Nonnull __state) __INTRODUCED_IN(21);
int getpt(void);
int posix_openpt(int __flags) __INTRODUCED_IN(21);
-char* ptsname(int __fd);
-int ptsname_r(int __fd, char* __buf, size_t __n);
+char* _Nullable ptsname(int __fd);
+int ptsname_r(int __fd, char* _Nonnull __buf, size_t __n);
int unlockpt(int __fd);
-int getsubopt(char** __option, char* const* __tokens, char** __value_ptr) __INTRODUCED_IN(26);
+int getsubopt(char* _Nonnull * _Nonnull __option, char* _Nonnull const* _Nonnull __tokens, char* _Nullable * _Nonnull __value_ptr) __INTRODUCED_IN(26);
typedef struct {
int quot;
@@ -154,18 +154,18 @@
*
* Returns the number of samples written to `__averages` (at most 3), and returns -1 on failure.
*/
-int getloadavg(double __averages[], int __n) __INTRODUCED_IN(29);
+int getloadavg(double __averages[_Nonnull], int __n) __INTRODUCED_IN(29);
/* BSD compatibility. */
-const char* getprogname(void) __INTRODUCED_IN(21);
-void setprogname(const char* __name) __INTRODUCED_IN(21);
+const char* _Nullable getprogname(void) __INTRODUCED_IN(21);
+void setprogname(const char* _Nonnull __name) __INTRODUCED_IN(21);
-int mblen(const char* __s, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(26);
-size_t mbstowcs(wchar_t* __dst, const char* __src, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
-int mbtowc(wchar_t* __wc_ptr, const char* __s, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
-int wctomb(char* __dst, wchar_t __wc) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
+int mblen(const char* _Nullable __s, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(26);
+size_t mbstowcs(wchar_t* _Nullable __dst, const char* _Nullable __src, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
+int mbtowc(wchar_t* _Nullable __wc_ptr, const char* _Nullable __s, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
+int wctomb(char* _Nullable __dst, wchar_t __wc) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
-size_t wcstombs(char* __dst, const wchar_t* __src, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
+size_t wcstombs(char* _Nullable __dst, const wchar_t* _Nullable __src, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
#if __ANDROID_API__ >= 21
size_t __ctype_get_mb_cur_max(void) __INTRODUCED_IN(21);
@@ -192,25 +192,25 @@
#endif
#if __ANDROID_API__ >= 21
-float strtof(const char* __s, char** __end_ptr) __INTRODUCED_IN(21);
-double atof(const char* __s) __attribute_pure__ __INTRODUCED_IN(21);
+float strtof(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr) __INTRODUCED_IN(21);
+double atof(const char* _Nonnull __s) __attribute_pure__ __INTRODUCED_IN(21);
int rand(void) __INTRODUCED_IN(21);
void srand(unsigned int __seed) __INTRODUCED_IN(21);
long random(void) __INTRODUCED_IN(21);
void srandom(unsigned int __seed) __INTRODUCED_IN(21);
int grantpt(int __fd) __INTRODUCED_IN(21);
-long long strtoll_l(const char* __s, char** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(21);
-unsigned long long strtoull_l(const char* __s, char** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(21);
-long double strtold_l(const char* __s, char** __end_ptr, locale_t __l) __INTRODUCED_IN(21);
+long long strtoll_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(21);
+unsigned long long strtoull_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(21);
+long double strtold_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) __INTRODUCED_IN(21);
#else
// Implemented as static inlines before 21.
#endif
#if __ANDROID_API__ >= 26
-double strtod_l(const char* __s, char** __end_ptr, locale_t __l) __INTRODUCED_IN(26);
-float strtof_l(const char* __s, char** __end_ptr, locale_t __l) __INTRODUCED_IN(26);
-long strtol_l(const char* __s, char** __end_ptr, int, locale_t __l) __INTRODUCED_IN(26);
+double strtod_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) __INTRODUCED_IN(26);
+float strtof_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) __INTRODUCED_IN(26);
+long strtol_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int, locale_t _Nonnull __l) __INTRODUCED_IN(26);
#else
// Implemented as static inlines before 26.
#endif
diff --git a/libc/include/sys/resource.h b/libc/include/sys/resource.h
index 9181125..ccb267d 100644
--- a/libc/include/sys/resource.h
+++ b/libc/include/sys/resource.h
@@ -41,6 +41,7 @@
#define RLIM_SAVED_MAX RLIM_INFINITY
typedef unsigned long rlim_t;
+typedef unsigned long long rlim64_t;
int getrlimit(int __resource, struct rlimit* __limit);
int setrlimit(int __resource, const struct rlimit* __limit);
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 5695dc6..4a4e607 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1518,34 +1518,34 @@
tss_set;
# Unwinder implementation
- __aeabi_unwind_cpp_pr0; # apex llndk arm
- __aeabi_unwind_cpp_pr1; # apex llndk arm
- __aeabi_unwind_cpp_pr2; # apex llndk arm
- __deregister_frame; # apex llndk arm64 x86 x86_64
- __gnu_unwind_frame; # apex llndk arm
- __register_frame; # apex llndk arm64 x86 x86_64
- _Unwind_Backtrace; # apex llndk
- _Unwind_Complete; # apex llndk arm
- _Unwind_DeleteException; # apex llndk
- _Unwind_Find_FDE; # apex llndk
- _Unwind_FindEnclosingFunction; # apex llndk
- _Unwind_ForcedUnwind; # apex llndk arm64 x86 x86_64
- _Unwind_GetCFA; # apex llndk
- _Unwind_GetDataRelBase; # apex llndk
- _Unwind_GetGR; # apex llndk
- _Unwind_GetIP; # apex llndk
- _Unwind_GetIPInfo; # apex llndk
- _Unwind_GetLanguageSpecificData; # apex llndk
- _Unwind_GetRegionStart; # apex llndk
- _Unwind_GetTextRelBase; # apex llndk
- _Unwind_RaiseException; # apex llndk
- _Unwind_Resume; # apex llndk
- _Unwind_Resume_or_Rethrow; # apex llndk
- _Unwind_SetGR; # apex llndk
- _Unwind_SetIP; # apex llndk
- _Unwind_VRS_Get; # apex llndk arm
- _Unwind_VRS_Pop; # apex llndk arm
- _Unwind_VRS_Set; # apex llndk arm
+ __aeabi_unwind_cpp_pr0; # arm
+ __aeabi_unwind_cpp_pr1; # arm
+ __aeabi_unwind_cpp_pr2; # arm
+ __deregister_frame; # arm64 x86 x86_64
+ __gnu_unwind_frame; # arm
+ __register_frame; # arm64 x86 x86_64
+ _Unwind_Backtrace;
+ _Unwind_Complete; # arm
+ _Unwind_DeleteException;
+ _Unwind_Find_FDE;
+ _Unwind_FindEnclosingFunction;
+ _Unwind_ForcedUnwind; # arm64 x86 x86_64
+ _Unwind_GetCFA;
+ _Unwind_GetDataRelBase;
+ _Unwind_GetGR;
+ _Unwind_GetIP;
+ _Unwind_GetIPInfo;
+ _Unwind_GetLanguageSpecificData;
+ _Unwind_GetRegionStart;
+ _Unwind_GetTextRelBase;
+ _Unwind_RaiseException;
+ _Unwind_Resume;
+ _Unwind_Resume_or_Rethrow;
+ _Unwind_SetGR;
+ _Unwind_SetIP;
+ _Unwind_VRS_Get; # arm
+ _Unwind_VRS_Pop; # arm
+ _Unwind_VRS_Set; # arm
} LIBC_Q;
LIBC_S { # introduced=S
diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp
index 5ab2232..e3a35a6 100644
--- a/libc/malloc_debug/PointerData.cpp
+++ b/libc/malloc_debug/PointerData.cpp
@@ -26,6 +26,7 @@
* SUCH DAMAGE.
*/
+#include <cxxabi.h>
#include <errno.h>
#include <inttypes.h>
#include <signal.h>
@@ -54,8 +55,6 @@
#include "malloc_debug.h"
#include "UnwindBacktrace.h"
-extern "C" char* __cxa_demangle(const char*, char*, size_t*, int*);
-
std::atomic_uint8_t PointerData::backtrace_enabled_;
std::atomic_bool PointerData::backtrace_dump_;
@@ -617,8 +616,8 @@
if (frame.function_name.empty()) {
dprintf(fd, " \"\" 0}");
} else {
- char* demangled_name = __cxa_demangle(frame.function_name.c_str(), nullptr, nullptr,
- nullptr);
+ char* demangled_name =
+ abi::__cxa_demangle(frame.function_name.c_str(), nullptr, nullptr, nullptr);
const char* name;
if (demangled_name != nullptr) {
name = demangled_name;
diff --git a/libc/malloc_debug/UnwindBacktrace.cpp b/libc/malloc_debug/UnwindBacktrace.cpp
index c892a39..8a6ff7b 100644
--- a/libc/malloc_debug/UnwindBacktrace.cpp
+++ b/libc/malloc_debug/UnwindBacktrace.cpp
@@ -26,6 +26,7 @@
* SUCH DAMAGE.
*/
+#include <cxxabi.h>
#include <inttypes.h>
#include <pthread.h>
#include <stdint.h>
@@ -48,8 +49,6 @@
#define PAD_PTR "08" PRIx64
#endif
-extern "C" char* __cxa_demangle(const char*, char*, size_t*, int*);
-
bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* frame_info,
size_t max_frames) {
[[clang::no_destroy]] static unwindstack::AndroidLocalUnwinder unwinder(
@@ -89,7 +88,8 @@
if (!info->function_name.empty()) {
line += " (";
- char* demangled_name = __cxa_demangle(info->function_name.c_str(), nullptr, nullptr, nullptr);
+ char* demangled_name =
+ abi::__cxa_demangle(info->function_name.c_str(), nullptr, nullptr, nullptr);
if (demangled_name != nullptr) {
line += demangled_name;
free(demangled_name);
diff --git a/libc/malloc_debug/backtrace.cpp b/libc/malloc_debug/backtrace.cpp
index 0649571..ecb3a80 100644
--- a/libc/malloc_debug/backtrace.cpp
+++ b/libc/malloc_debug/backtrace.cpp
@@ -26,6 +26,7 @@
* SUCH DAMAGE.
*/
+#include <cxxabi.h>
#include <dlfcn.h>
#include <errno.h>
#include <inttypes.h>
@@ -48,8 +49,6 @@
typedef struct _Unwind_Context __unwind_context;
-extern "C" char* __cxa_demangle(const char*, char*, size_t*, int*);
-
static MapData g_map_data;
static const MapEntry* g_current_code_map = nullptr;
@@ -145,7 +144,7 @@
char buf[1024];
if (symbol != nullptr) {
- char* demangled_name = __cxa_demangle(symbol, nullptr, nullptr, nullptr);
+ char* demangled_name = abi::__cxa_demangle(symbol, nullptr, nullptr, nullptr);
const char* name;
if (demangled_name != nullptr) {
name = demangled_name;
diff --git a/libfdtrack/fdtrack.cpp b/libfdtrack/fdtrack.cpp
index 2d114f2..b064401 100644
--- a/libfdtrack/fdtrack.cpp
+++ b/libfdtrack/fdtrack.cpp
@@ -71,7 +71,11 @@
static constexpr size_t kStackDepth = 32;
// Skip any initial frames from libfdtrack.so.
-static std::vector<std::string> kSkipFdtrackLib [[clang::no_destroy]] = {"libfdtrack.so"};
+// Also ignore frames from ART (http://b/236197847) because we'd rather spend
+// our precious few frames on the actual Java calling code rather than the
+// implementation of JNI!
+static std::vector<std::string> kSkipFdtrackLib
+ [[clang::no_destroy]] = {"libfdtrack.so", "libart.so"};
static bool installed = false;
static std::array<FdEntry, kFdTableSize> stack_traces [[clang::no_destroy]];
diff --git a/libm/Android.bp b/libm/Android.bp
index df81e1c..2748871 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -346,10 +346,33 @@
],
exclude_srcs: [
+ // TODO: do the rest when our clang has https://reviews.llvm.org/D136508.
+ // TODO: "upstream-freebsd/lib/msun/src/s_ceil.c",
+ // TODO: "upstream-freebsd/lib/msun/src/s_ceilf.c",
+ "upstream-freebsd/lib/msun/src/s_copysign.c",
+ "upstream-freebsd/lib/msun/src/s_copysignf.c",
+ // TODO: "upstream-freebsd/lib/msun/src/s_floor.c",
+ // TODO: "upstream-freebsd/lib/msun/src/s_floorf.c",
+ "upstream-freebsd/lib/msun/src/s_fma.c",
+ "upstream-freebsd/lib/msun/src/s_fmaf.c",
+ "upstream-freebsd/lib/msun/src/s_fmax.c",
+ "upstream-freebsd/lib/msun/src/s_fmaxf.c",
+ "upstream-freebsd/lib/msun/src/s_fmin.c",
+ "upstream-freebsd/lib/msun/src/s_fminf.c",
"upstream-freebsd/lib/msun/src/s_llrint.c",
"upstream-freebsd/lib/msun/src/s_llrintf.c",
+ "upstream-freebsd/lib/msun/src/s_llround.c",
+ "upstream-freebsd/lib/msun/src/s_llroundf.c",
"upstream-freebsd/lib/msun/src/s_lrint.c",
"upstream-freebsd/lib/msun/src/s_lrintf.c",
+ "upstream-freebsd/lib/msun/src/s_lround.c",
+ "upstream-freebsd/lib/msun/src/s_lroundf.c",
+ // TODO: "upstream-freebsd/lib/msun/src/s_rint.c",
+ // TODO: "upstream-freebsd/lib/msun/src/s_rintf.c",
+ // TODO: "upstream-freebsd/lib/msun/src/s_round.c",
+ // TODO: "upstream-freebsd/lib/msun/src/s_roundf.c",
+ // TODO: "upstream-freebsd/lib/msun/src/s_trunc.c",
+ // TODO: "upstream-freebsd/lib/msun/src/s_truncf.c",
],
version_script: ":libm.riscv64.map",
},
diff --git a/libm/builtins.cpp b/libm/builtins.cpp
index 7487323..58cd81d 100644
--- a/libm/builtins.cpp
+++ b/libm/builtins.cpp
@@ -18,43 +18,26 @@
#include "fpmath.h"
-double fabs(double x) {
-#if __arm__
- // Both Clang and GCC insist on moving r0/r1 into a double register
- // and using fabs where bit-twiddling would be a better choice.
- // They get fabsf right, but we need to be careful in fabsl too.
- IEEEd2bits u;
- u.d = x;
- u.bits.sign = 0;
- return u.d;
-#else
- return __builtin_fabs(x);
-#endif
-}
-
-float fabsf(float x) {
- return __builtin_fabsf(x);
-}
-
-#if defined(__LP64__)
+double fabs(double x) { return __builtin_fabs(x); }
+float fabsf(float x) { return __builtin_fabsf(x); }
long double fabsl(long double x) { return __builtin_fabsl(x); }
-#else
-long double fabsl(long double x) {
- // Don't use __builtin_fabs here because of ARM. (See fabs above.)
- return fabs(x);
-}
-#endif
#if defined(__aarch64__)
float ceilf(float x) { return __builtin_ceilf(x); }
double ceil(double x) { return __builtin_ceil(x); }
+#endif
+#if defined(__aarch64__) || defined(__riscv)
double copysign(double x, double y) { return __builtin_copysign(x, y); }
float copysignf(float x, float y) { return __builtin_copysignf(x, y); }
+#endif
+#if defined(__aarch64__)
float floorf(float x) { return __builtin_floorf(x); }
double floor(double x) { return __builtin_floor(x); }
+#endif
+#if defined(__aarch64__) || defined(__riscv)
float fmaf(float x, float y, float z) { return __builtin_fmaf(x, y, z); }
double fma(double x, double y, double z) { return __builtin_fma(x, y, z); }
@@ -68,7 +51,9 @@
long lroundf(float x) { return __builtin_lroundf(x); }
long long llround(double x) { return __builtin_llround(x); }
long long llroundf(float x) { return __builtin_llroundf(x); }
+#endif
+#if defined(__aarch64__)
float rintf(float x) { return __builtin_rintf(x); }
double rint(double x) { return __builtin_rint(x); }
diff --git a/tests/__cxa_atexit_test.cpp b/tests/__cxa_atexit_test.cpp
index 6a122d1..9f73261 100644
--- a/tests/__cxa_atexit_test.cpp
+++ b/tests/__cxa_atexit_test.cpp
@@ -26,19 +26,30 @@
* SUCH DAMAGE.
*/
-#include <cxxabi.h>
#include <gtest/gtest.h>
+extern "C" {
+int __cxa_atexit(void (*func)(void*), void* arg, void* dso);
+
+// TODO(b/175635923). __cxa_finalize's return type should actually be "void",
+// but it is declared "int" here instead to be compatible with the declaration
+// in an old version of cxxabi.h, which is included indirectly. The declarations
+// of __cxa_atexit and __cxa_finalize are removed from newer versions of
+// cxxabi.h, so once libc++ is updated, this return type should be changed to
+// "void".
+int __cxa_finalize(void* dso);
+}
+
TEST(__cxa_atexit, simple) {
int counter = 0;
- __cxxabiv1::__cxa_atexit([](void* arg) { ++*static_cast<int*>(arg); }, &counter, &counter);
+ __cxa_atexit([](void* arg) { ++*static_cast<int*>(arg); }, &counter, &counter);
- __cxxabiv1::__cxa_finalize(&counter);
+ __cxa_finalize(&counter);
ASSERT_EQ(counter, 1);
// The handler won't be called twice.
- __cxxabiv1::__cxa_finalize(&counter);
+ __cxa_finalize(&counter);
ASSERT_EQ(counter, 1);
}
@@ -54,16 +65,16 @@
};
for (int i = 0; i < 500; ++i) {
- __cxxabiv1::__cxa_atexit(append_to_actual, new int{i}, &handles[i % 2]);
+ __cxa_atexit(append_to_actual, new int{i}, &handles[i % 2]);
}
- __cxxabiv1::__cxa_finalize(&handles[0]);
+ __cxa_finalize(&handles[0]);
for (int i = 500; i < 750; ++i) {
- __cxxabiv1::__cxa_atexit(append_to_actual, new int{i}, &handles[1]);
+ __cxa_atexit(append_to_actual, new int{i}, &handles[1]);
}
- __cxxabiv1::__cxa_finalize(&handles[1]);
+ __cxa_finalize(&handles[1]);
std::vector<int> expected;
for (int i = 498; i >= 0; i -= 2) expected.push_back(i);
diff --git a/tests/__cxa_demangle_test.cpp b/tests/__cxa_demangle_test.cpp
index 4628a61..d400619 100644
--- a/tests/__cxa_demangle_test.cpp
+++ b/tests/__cxa_demangle_test.cpp
@@ -29,11 +29,9 @@
#include <cxxabi.h>
#include <gtest/gtest.h>
-extern "C" char* __cxa_demangle(const char*, char*, size_t*, int*);
-
TEST(__cxa_demangle, cxa_demangle_fuzz_152588929) {
#if defined(__aarch64__)
- char* p = __cxa_demangle("1\006ILeeeEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE", 0, 0, 0);
+ char* p = abi::__cxa_demangle("1\006ILeeeEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE", 0, 0, 0);
ASSERT_STREQ("\x6<-0x1.cecececececececececececececep+11983", p);
free(p);
#endif
@@ -41,7 +39,7 @@
TEST(__cxa_demangle, DISABLED_cxa_demangle_fuzz_167977068) {
#if defined(__aarch64__)
- char* p = __cxa_demangle("DTLeeeeeeeeeeeeeeeeeeeeeeeeeEEEEeeEEEE", 0, 0, 0);
+ char* p = abi::__cxa_demangle("DTLeeeeeeeeeeeeeeeeeeeeeeeeeEEEEeeEEEE", 0, 0, 0);
ASSERT_EQ(nullptr, p) << p;
free(p);
#endif
diff --git a/tests/clang_fortify_tests.cpp b/tests/clang_fortify_tests.cpp
index 40cb83f..544af43 100644
--- a/tests/clang_fortify_tests.cpp
+++ b/tests/clang_fortify_tests.cpp
@@ -387,6 +387,8 @@
}
static void testStdlib() {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
char path_buffer[PATH_MAX - 1];
// expected-warning@+2{{ignoring return value of function}}
// expected-error@+1{{must be NULL or a pointer to a buffer with >= PATH_MAX bytes}}
@@ -401,6 +403,7 @@
// expected-warning@+2{{ignoring return value of function}}
// expected-error@+1{{flipped arguments?}}
realpath(nullptr, nullptr);
+#pragma clang diagnostic pop
}
} // namespace compilation_tests
#endif
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index f507e08..45169e3 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -494,7 +494,10 @@
TEST(stdlib, system_NULL) {
// "The system() function shall always return non-zero when command is NULL."
// http://pubs.opengroup.org/onlinepubs/9699919799/functions/system.html
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
ASSERT_NE(0, system(nullptr));
+#pragma clang diagnostic pop
}
// https://austingroupbugs.net/view.php?id=1440
diff --git a/tests/sys_resource_test.cpp b/tests/sys_resource_test.cpp
index 0247fcb..492fabd 100644
--- a/tests/sys_resource_test.cpp
+++ b/tests/sys_resource_test.cpp
@@ -26,6 +26,7 @@
ASSERT_NE(sizeof(rlimit), sizeof(rlimit64));
ASSERT_EQ(4U, sizeof(rlim_t));
#endif
+ ASSERT_EQ(8U, sizeof(rlim64_t));
}
class SysResourceTest : public ::testing::Test {
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 5fce5b8..2a36460 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -294,10 +294,13 @@
}
TEST(UNISTD_TEST, setenv_EINVAL) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
EXPECT_EQ(-1, setenv(nullptr, "value", 0));
EXPECT_EQ(EINVAL, errno);
EXPECT_EQ(-1, setenv(nullptr, "value", 1));
EXPECT_EQ(EINVAL, errno);
+#pragma clang diagnostic pop
EXPECT_EQ(-1, setenv("", "value", 0));
EXPECT_EQ(EINVAL, errno);
EXPECT_EQ(-1, setenv("", "value", 1));