Merge "Run pvalloc/valloc tests in unsupported envs."
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index e2ea065..e0fa16a 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -105,10 +105,10 @@
 ssize_t     __pwritev64:pwritev(int, const struct iovec*, int, long, long) lp32
 ssize_t     pwritev|pwritev64(int, const struct iovec*, int, off_t) lp64
 
-int         ___close:close(int)  all
+int         __close:close(int)  all
 pid_t       __getpid:getpid()  all
 int         munmap(void*, size_t)  all
-void*       ___mremap:mremap(void*, size_t, size_t, int, void*)  all
+void*       __mremap:mremap(void*, size_t, size_t, int, void*)  all
 int         msync(const void*, size_t, int)    all
 int         mprotect(const void*, size_t, int)  all
 int         madvise(void*, size_t, int)  all
@@ -123,7 +123,7 @@
 int         __fcntl64:fcntl64(int, int, void*)  lp32
 int         fcntl(int, int, void*)  lp64
 int         flock(int, int)   all
-int         ___fchmod:fchmod(int, mode_t)  all
+int         __fchmod:fchmod(int, mode_t)  all
 int         dup(int)  all
 int         pipe2(int*, int) all
 int         dup3(int, int, int)   all
@@ -133,16 +133,16 @@
 int         fchown:fchown(int, uid_t, gid_t)    arm64,mips,mips64,x86_64
 void        sync(void)  all
 int         syncfs(int)  all
-int         ___fsetxattr:fsetxattr(int, const char*, const void*, size_t, int) all
-ssize_t     ___fgetxattr:fgetxattr(int, const char*, void*, size_t) all
-ssize_t     ___flistxattr:flistxattr(int, char*, size_t) all
+int         __fsetxattr:fsetxattr(int, const char*, const void*, size_t, int) all
+ssize_t     __fgetxattr:fgetxattr(int, const char*, void*, size_t) all
+ssize_t     __flistxattr:flistxattr(int, char*, size_t) all
 int         fremovexattr(int, const char*) all
 
 int __getdents64:getdents64(unsigned int, struct dirent*, unsigned int)   arm,arm64,mips,mips64,x86,x86_64
 
 int __openat:openat(int, const char*, int, mode_t) all
-int ___faccessat:faccessat(int, const char*, int)  all
-int ___fchmodat:fchmodat(int, const char*, mode_t)  all
+int __faccessat:faccessat(int, const char*, int)  all
+int __fchmodat:fchmodat(int, const char*, mode_t)  all
 int fchownat(int, const char*, uid_t, gid_t, int)  all
 int fstatat64|fstatat:fstatat64(int, const char*, struct stat*, int)   lp32
 int fstatat64|fstatat:newfstatat(int, const char*, struct stat*, int)  arm64,x86_64
@@ -213,7 +213,7 @@
 clock_t       times(struct tms*)       all
 int           nanosleep(const struct timespec*, struct timespec*)   all
 int           clock_settime(clockid_t, const struct timespec*)  all
-int           ___clock_nanosleep:clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*)  all
+int           __clock_nanosleep:clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*)  all
 int           getitimer(int, const struct itimerval*)   all
 int           setitimer(int, const struct itimerval*, struct itimerval*)  all
 int           __timer_create:timer_create(clockid_t clockid, struct sigevent* evp, __kernel_timer_t* timerid)    all
@@ -234,7 +234,7 @@
 int     __rt_sigprocmask:rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t)  all
 int     __rt_sigsuspend:rt_sigsuspend(const sigset64_t*, size_t)  all
 int     __rt_sigtimedwait:rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t)  all
-int     ___rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*)  all
+int     __rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*)  all
 int     __signalfd4:signalfd4(int, const sigset64_t*, size_t, int)  all
 
 # sockets
diff --git a/libc/bionic/clock_nanosleep.cpp b/libc/bionic/clock_nanosleep.cpp
index eade850..6f77d83 100644
--- a/libc/bionic/clock_nanosleep.cpp
+++ b/libc/bionic/clock_nanosleep.cpp
@@ -30,11 +30,11 @@
 
 #include "private/ErrnoRestorer.h"
 
-extern "C" int ___clock_nanosleep(clockid_t, int, const timespec*, timespec*);
+extern "C" int __clock_nanosleep(clockid_t, int, const timespec*, timespec*);
 
 int clock_nanosleep(clockid_t clock_id, int flags, const timespec* in, timespec* out) {
   if (clock_id == CLOCK_THREAD_CPUTIME_ID) return EINVAL;
 
   ErrnoRestorer errno_restorer;
-  return (___clock_nanosleep(clock_id, flags, in, out) == 0) ? 0 : errno;
+  return (__clock_nanosleep(clock_id, flags, in, out) == 0) ? 0 : errno;
 }
diff --git a/libc/bionic/faccessat.cpp b/libc/bionic/faccessat.cpp
index a86aeb2..bfaec51 100644
--- a/libc/bionic/faccessat.cpp
+++ b/libc/bionic/faccessat.cpp
@@ -30,7 +30,7 @@
 #include <unistd.h>
 #include <errno.h>
 
-extern "C" int ___faccessat(int, const char*, int);
+extern "C" int __faccessat(int, const char*, int);
 
 int faccessat(int dirfd, const char* pathname, int mode, int flags) {
   // "The mode specifies the accessibility check(s) to be performed,
@@ -56,5 +56,5 @@
     return -1;
   }
 
-  return ___faccessat(dirfd, pathname, mode);
+  return __faccessat(dirfd, pathname, mode);
 }
diff --git a/libc/bionic/fchmod.cpp b/libc/bionic/fchmod.cpp
index a486aae..0326fc2 100644
--- a/libc/bionic/fchmod.cpp
+++ b/libc/bionic/fchmod.cpp
@@ -35,11 +35,11 @@
 
 #include "private/FdPath.h"
 
-extern "C" int ___fchmod(int, mode_t);
+extern "C" int __fchmod(int, mode_t);
 
 int fchmod(int fd, mode_t mode) {
   int saved_errno = errno;
-  int result = ___fchmod(fd, mode);
+  int result = __fchmod(fd, mode);
   if (result == 0 || errno != EBADF) {
     return result;
   }
diff --git a/libc/bionic/fchmodat.cpp b/libc/bionic/fchmodat.cpp
index 1f83c4b..c28e15a 100644
--- a/libc/bionic/fchmodat.cpp
+++ b/libc/bionic/fchmodat.cpp
@@ -34,7 +34,7 @@
 
 #include "private/ErrnoRestorer.h"
 
-extern "C" int ___fchmodat(int, const char*, mode_t);
+extern "C" int __fchmodat(int, const char*, mode_t);
 
 int fchmodat(int dirfd, const char* pathname, mode_t mode, int flags) {
   if ((flags & ~AT_SYMLINK_NOFOLLOW) != 0) {
@@ -63,5 +63,5 @@
     return result;
   }
 
-  return ___fchmodat(dirfd, pathname, mode);
+  return __fchmodat(dirfd, pathname, mode);
 }
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index 6440ae0..dd3a96e 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -46,7 +46,7 @@
 #include "private/bionic_inline_raise.h"
 #include "pthread_internal.h"
 
-extern "C" int ___close(int fd);
+extern "C" int __close(int fd);
 pid_t __get_cached_pid();
 
 static constexpr const char* kFdsanPropertyName = "debug.fdsan";
@@ -269,7 +269,7 @@
 int android_fdsan_close_with_tag(int fd, uint64_t expected_tag) {
   FdEntry* fde = GetFdEntry(fd);
   if (!fde) {
-    return ___close(fd);
+    return __close(fd);
   }
 
   uint64_t tag = expected_tag;
@@ -299,7 +299,7 @@
     }
   }
 
-  int rc = ___close(fd);
+  int rc = __close(fd);
   // If we were expecting to close with a tag, abort on EBADF.
   if (expected_tag && rc == -1 && errno == EBADF) {
     fdsan_error("double-close of file descriptor %d detected", fd);
diff --git a/libc/bionic/fgetxattr.cpp b/libc/bionic/fgetxattr.cpp
index 38b7ac3..c753235 100644
--- a/libc/bionic/fgetxattr.cpp
+++ b/libc/bionic/fgetxattr.cpp
@@ -35,11 +35,11 @@
 
 #include "private/FdPath.h"
 
-extern "C" ssize_t ___fgetxattr(int, const char*, void*, size_t);
+extern "C" ssize_t __fgetxattr(int, const char*, void*, size_t);
 
 ssize_t fgetxattr(int fd, const char *name, void *value, size_t size) {
   int saved_errno = errno;
-  ssize_t result = ___fgetxattr(fd, name, value, size);
+  ssize_t result = __fgetxattr(fd, name, value, size);
 
   if (result != -1 || errno != EBADF) {
     return result;
diff --git a/libc/bionic/flistxattr.cpp b/libc/bionic/flistxattr.cpp
index 8ad9b85..3bad383 100644
--- a/libc/bionic/flistxattr.cpp
+++ b/libc/bionic/flistxattr.cpp
@@ -35,11 +35,11 @@
 
 #include "private/FdPath.h"
 
-extern "C" ssize_t ___flistxattr(int, char*, size_t);
+extern "C" ssize_t __flistxattr(int, char*, size_t);
 
 ssize_t flistxattr(int fd, char *list, size_t size) {
   int saved_errno = errno;
-  ssize_t result = ___flistxattr(fd, list, size);
+  ssize_t result = __flistxattr(fd, list, size);
   if (result != -1 || errno != EBADF) {
     return result;
   }
diff --git a/libc/bionic/fsetxattr.cpp b/libc/bionic/fsetxattr.cpp
index 9ad0c76..00955bd 100644
--- a/libc/bionic/fsetxattr.cpp
+++ b/libc/bionic/fsetxattr.cpp
@@ -35,11 +35,11 @@
 
 #include "private/FdPath.h"
 
-extern "C" int ___fsetxattr(int, const char*, const void*, size_t, int);
+extern "C" int __fsetxattr(int, const char*, const void*, size_t, int);
 
 int fsetxattr(int fd, const char* name, const void* value, size_t size, int flags) {
   int saved_errno = errno;
-  int result = ___fsetxattr(fd, name, value, size, flags);
+  int result = __fsetxattr(fd, name, value, size, flags);
   if (result == 0 || errno != EBADF) {
     return result;
   }
diff --git a/libc/bionic/mremap.cpp b/libc/bionic/mremap.cpp
index 896ccef1..a4e5323 100644
--- a/libc/bionic/mremap.cpp
+++ b/libc/bionic/mremap.cpp
@@ -34,7 +34,7 @@
 
 #include "private/bionic_macros.h"
 
-extern "C" void* ___mremap(void*, size_t, size_t, int, void*);
+extern "C" void* __mremap(void*, size_t, size_t, int, void*);
 
 void* mremap(void* old_address, size_t old_size, size_t new_size, int flags, ...) {
   // prevent allocations large enough for `end - start` to overflow
@@ -53,5 +53,5 @@
     new_address = va_arg(ap, void*);
     va_end(ap);
   }
-  return ___mremap(old_address, old_size, new_size, flags, new_address);
+  return __mremap(old_address, old_size, new_size, flags, new_address);
 }
diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp
index d6be09a..8246cb4 100644
--- a/libc/bionic/signal.cpp
+++ b/libc/bionic/signal.cpp
@@ -41,7 +41,7 @@
 #include "private/sigrtmin.h"
 
 extern "C" int __rt_sigpending(const sigset64_t*, size_t);
-extern "C" int ___rt_sigqueueinfo(pid_t, int, siginfo_t*);
+extern "C" int __rt_sigqueueinfo(pid_t, int, siginfo_t*);
 extern "C" int __rt_sigsuspend(const sigset64_t*, size_t);
 extern "C" int __rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t);
 
@@ -216,7 +216,7 @@
   info.si_pid = getpid();
   info.si_uid = getuid();
   info.si_value = value;
-  return ___rt_sigqueueinfo(pid, sig, &info);
+  return __rt_sigqueueinfo(pid, sig, &info);
 }
 
 int sigrelse(int sig) {
diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h
index 6e47daf..e766b20 100644
--- a/libc/include/bits/fortify/stdio.h
+++ b/libc/include/bits/fortify/stdio.h
@@ -39,6 +39,8 @@
 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
 __BIONIC_FORTIFY_INLINE __printflike(3, 0)
 int vsnprintf(char* const __pass_object_size dest, size_t size, const char* format, va_list ap)
+        __clang_error_if(__bos_unevaluated_lt(__bos(dest), size),
+                         "in call to 'vsnprintf', size is larger than the destination buffer")
         __overloadable {
     return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
 }
@@ -50,19 +52,10 @@
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 
 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-/*
- * Simple case: `format` can't have format specifiers, so we can just compare
- * its length to the length of `dest`
- */
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int snprintf(char* dest, size_t size, const char* format)
-    __overloadable
-    __enable_if(__bos_unevaluated_lt(__bos(dest), __builtin_strlen(format)),
-                "format string will always overflow destination buffer")
-    __errorattr("format string will always overflow destination buffer");
-
 __BIONIC_FORTIFY_VARIADIC __printflike(3, 4)
 int snprintf(char* const __pass_object_size dest, size_t size, const char* format, ...)
+        __clang_error_if(__bos_unevaluated_lt(__bos(dest), size),
+                         "in call to 'snprintf', size is larger than the destination buffer")
         __overloadable {
     va_list va;
     va_start(va, format);
diff --git a/libc/include/bits/fortify/stdlib.h b/libc/include/bits/fortify/stdlib.h
index 0bb3d0d..623be58 100644
--- a/libc/include/bits/fortify/stdlib.h
+++ b/libc/include/bits/fortify/stdlib.h
@@ -36,10 +36,11 @@
 #define __PATH_MAX 4096
 
 char* realpath(const char* path, char* resolved)
+        __clang_error_if(!path, "'realpath': NULL path is never correct; flipped arguments?")
         __clang_error_if(__bos_unevaluated_lt(__bos(resolved), __PATH_MAX),
                          "'realpath' output parameter must be NULL or a pointer to a buffer "
-                         "with >= PATH_MAX bytes")
-        __clang_error_if(!path, "'realpath': NULL path is never correct; flipped arguments?");
+                         "with >= PATH_MAX bytes");
+
 /* No need for a definition; the only issues we can catch are at compile-time. */
 
 #undef __PATH_MAX
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index d5b8619..b66e3c6 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -90,7 +90,7 @@
 long atol(const char* __s) __attribute_pure__;
 long long atoll(const char* __s) __attribute_pure__;
 
-char* realpath(const char* __path, char* __resolved);
+__wur char* realpath(const char* __path, char* __resolved);
 int system(const char* __command);
 
 void* bsearch(const void* __key, const void* __base, size_t __nmemb, size_t __size, int (*__comparator)(const void* __lhs, const void* __rhs));
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index 91c7689..a0b4219 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -57,8 +57,6 @@
 #include "private/ErrnoRestorer.h"
 #include "private/thread_private.h"
 
-extern "C" int ___close(int fd);
-
 #define ALIGNBYTES (sizeof(uintptr_t) - 1)
 #define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
 
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index b307486..0f3f1dc 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -265,8 +265,7 @@
         stub += "\nALIAS_SYMBOL(%s, %s)\n" % (alias, syscall["func"])
 
     # Use hidden visibility on LP64 for any functions beginning with underscores.
-    # Force hidden visibility for any functions which begin with 3 underscores
-    if (pointer_length == 64 and syscall["func"].startswith("__")) or syscall["func"].startswith("___"):
+    if pointer_length == 64 and syscall["func"].startswith("__"):
         stub += '.hidden ' + syscall["func"] + '\n'
 
     return stub
diff --git a/tests/Android.bp b/tests/Android.bp
index 97712d3..65c6035 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -284,6 +284,7 @@
     name: "bionic_clang_fortify_tests_w_flags",
     cflags: [
         "-Wno-builtin-memcpy-chk-size",
+        "-Wno-format-security",
         "-Wno-format-zero-length",
         "-Wno-memset-transposed-args",
         "-Wno-strlcpy-strlcat-size",
diff --git a/tests/clang_fortify_tests.cpp b/tests/clang_fortify_tests.cpp
index 4c4e510..e1ecfa5 100644
--- a/tests/clang_fortify_tests.cpp
+++ b/tests/clang_fortify_tests.cpp
@@ -55,6 +55,12 @@
 #define __clang_error_if(...)
 #undef __clang_warning_if
 #define __clang_warning_if(...)
+
+// SOMETIMES_CONST allows clang to emit eager diagnostics when we're doing compilation tests, but
+// blocks them otherwise. This is needed for diagnostics emitted with __enable_if.
+#define SOMETIMES_CONST volatile
+#else
+#define SOMETIMES_CONST const
 #endif
 
 #include <err.h>
@@ -391,20 +397,17 @@
 
 static void testStdlib() {
   char path_buffer[PATH_MAX - 1];
-#if 0
-  // expected-error@+2{{ignoring return value of function}}
-#endif
+  // expected-warning@+2{{ignoring return value of function}}
   // expected-error@+1{{must be NULL or a pointer to a buffer with >= PATH_MAX bytes}}
   realpath("/", path_buffer);
-#if 0
-    // expected-error@+1{{ignoring return value of function}}
-#endif
+  // expected-warning@+1{{ignoring return value of function}}
   realpath("/", nullptr);
 
-  // FIXME: This should complain about flipped arguments, instead of objectsize.
-  // expected-error@+1{{must be NULL or a pointer to a buffer with >= PATH_MAX bytes}}
+  // expected-warning@+2{{ignoring return value of function}}
+  // expected-error@+1{{flipped arguments?}}
   realpath(nullptr, path_buffer);
 
+  // expected-warning@+2{{ignoring return value of function}}
   // expected-error@+1{{flipped arguments?}}
   realpath(nullptr, nullptr);
 }
@@ -487,17 +490,18 @@
 FORTIFY_TEST(stdio) {
   char small_buffer[8] = {};
   {
-#if 0
-    // expected-error@+1{{may overflow the destination buffer}}
-#endif
+    // expected-error@+1{{size is larger than the destination buffer}}
     EXPECT_FORTIFY_DEATH(snprintf(small_buffer, sizeof(small_buffer) + 1, ""));
 
     va_list va;
-#if 0
-    // expected-error@+1{{may overflow the destination buffer}}
-#endif
+    // expected-error@+2{{size is larger than the destination buffer}}
     // expected-warning@+1{{format string is empty}}
     EXPECT_FORTIFY_DEATH(vsnprintf(small_buffer, sizeof(small_buffer) + 1, "", va));
+
+    const char *SOMETIMES_CONST format_string = "aaaaaaaaa";
+
+    // expected-error@+1{{format string will always overflow}}
+    EXPECT_FORTIFY_DEATH(sprintf(small_buffer, format_string));
   }
 
   // expected-error@+1{{size should not be negative}}