Merge "Clarify what part of the NDK sets the soname."
diff --git a/libc/Android.bp b/libc/Android.bp
index 93f9ce9..7eaa1bf 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1318,7 +1318,7 @@
 // ========================================================
 
 genrule {
-    name: "syscalls-arm.S",
+    name: "syscalls-arm",
     out: ["syscalls-arm.S"],
     srcs: ["SYSCALLS.TXT"],
     tools: ["gensyscalls"],
@@ -1326,7 +1326,7 @@
 }
 
 genrule {
-    name: "syscalls-arm64.S",
+    name: "syscalls-arm64",
     out: ["syscalls-arm64.S"],
     srcs: ["SYSCALLS.TXT"],
     tools: ["gensyscalls"],
@@ -1334,7 +1334,7 @@
 }
 
 genrule {
-    name: "syscalls-riscv64.S",
+    name: "syscalls-riscv64",
     out: ["syscalls-riscv64.S"],
     srcs: ["SYSCALLS.TXT"],
     tools: ["gensyscalls"],
@@ -1342,7 +1342,7 @@
 }
 
 genrule {
-    name: "syscalls-x86.S",
+    name: "syscalls-x86",
     out: ["syscalls-x86.S"],
     srcs: ["SYSCALLS.TXT"],
     tools: ["gensyscalls"],
@@ -1350,7 +1350,7 @@
 }
 
 genrule {
-    name: "syscalls-x86_64.S",
+    name: "syscalls-x86_64",
     out: ["syscalls-x86_64.S"],
     srcs: ["SYSCALLS.TXT"],
     tools: ["gensyscalls"],
@@ -1362,19 +1362,19 @@
     srcs: ["bionic/__set_errno.cpp"],
     arch: {
         arm: {
-            srcs: [":syscalls-arm.S"],
+            srcs: [":syscalls-arm"],
         },
         arm64: {
-            srcs: [":syscalls-arm64.S"],
+            srcs: [":syscalls-arm64"],
         },
         riscv64: {
-            srcs: [":syscalls-riscv64.S"],
+            srcs: [":syscalls-riscv64"],
         },
         x86: {
-            srcs: [":syscalls-x86.S"],
+            srcs: [":syscalls-x86"],
         },
         x86_64: {
-            srcs: [":syscalls-x86_64.S"],
+            srcs: [":syscalls-x86_64"],
         },
     },
     name: "libc_syscalls",
@@ -1837,7 +1837,7 @@
 
 genrule {
     name: "libc.arm.map",
-    out: ["libc.arm.map"],
+    out: ["libc.arm.map.txt"],
     srcs: ["libc.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -1845,7 +1845,7 @@
 
 genrule {
     name: "libc.arm64.map",
-    out: ["libc.arm64.map"],
+    out: ["libc.arm64.map.txt"],
     srcs: ["libc.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -1853,7 +1853,7 @@
 
 genrule {
     name: "libc.riscv64.map",
-    out: ["libc.riscv64.map"],
+    out: ["libc.riscv64.map.txt"],
     srcs: ["libc.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -1861,7 +1861,7 @@
 
 genrule {
     name: "libc.x86.map",
-    out: ["libc.x86.map"],
+    out: ["libc.x86.map.txt"],
     srcs: ["libc.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -1869,7 +1869,7 @@
 
 genrule {
     name: "libc.x86_64.map",
-    out: ["libc.x86_64.map"],
+    out: ["libc.x86_64.map.txt"],
     srcs: ["libc.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
@@ -2074,7 +2074,7 @@
 
 genrule {
     name: "libstdc++.arm.map",
-    out: ["libstdc++.arm.map"],
+    out: ["libstdc++.arm.map.txt"],
     srcs: ["libstdc++.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -2082,7 +2082,7 @@
 
 genrule {
     name: "libstdc++.arm64.map",
-    out: ["libstdc++.arm64.map"],
+    out: ["libstdc++.arm64.map.txt"],
     srcs: ["libstdc++.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -2090,7 +2090,7 @@
 
 genrule {
     name: "libstdc++.riscv64.map",
-    out: ["libstdc++.riscv64.map"],
+    out: ["libstdc++.riscv64.map.txt"],
     srcs: ["libstdc++.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -2098,7 +2098,7 @@
 
 genrule {
     name: "libstdc++.x86.map",
-    out: ["libstdc++.x86.map"],
+    out: ["libstdc++.x86.map.txt"],
     srcs: ["libstdc++.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -2106,7 +2106,7 @@
 
 genrule {
     name: "libstdc++.x86_64.map",
-    out: ["libstdc++.x86_64.map"],
+    out: ["libstdc++.x86_64.map.txt"],
     srcs: ["libstdc++.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
@@ -2147,10 +2147,6 @@
     name: "crt_defaults",
     defaults: ["crt_and_memtag_defaults"],
     system_shared_libs: [],
-
-    conlyflags: [
-        "-mllvm -disable-check-noreturn-call",
-    ]
 }
 
 cc_defaults {
@@ -2183,6 +2179,8 @@
     srcs: ["arch-common/bionic/crtbrand.S"],
 
     defaults: ["crt_so_defaults"],
+    // crtbrand is an intermediate artifact, not a final CRT object.
+    exclude_from_ndk_sysroot: true,
 }
 
 cc_object {
diff --git a/libc/arch-riscv64/bionic/setjmp.S b/libc/arch-riscv64/bionic/setjmp.S
index ba3cacf..26f7ec9 100644
--- a/libc/arch-riscv64/bionic/setjmp.S
+++ b/libc/arch-riscv64/bionic/setjmp.S
@@ -36,50 +36,52 @@
 // 0      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
 // 1      sigmask         64-bit signal mask
 // 2      ra
-// 3      s0
+// 3      sp
+// 4      gp
+// 5      s0
 // ......
-// 14     s11
-// 15     sp
-// 16     fs0
+// 16     s11
+// 17     fs0
 // ......
-// 27     fs11
-// 28     checksum
+// 28     fs11
+// 29     checksum
 // _JBLEN: defined in bionic/libc/include/setjmp.h
 
 #define _JB_SIGFLAG   0
 #define _JB_SIGMASK   1 * 8
 #define _JB_RA        2 * 8
-#define _JB_S0        3 * 8
-#define _JB_S1        4 * 8
-#define _JB_S2        5 * 8
-#define _JB_S3        6 * 8
-#define _JB_S4        7 * 8
-#define _JB_S5        8 * 8
-#define _JB_S6        9 * 8
-#define _JB_S7       10 * 8
-#define _JB_S8       11 * 8
-#define _JB_S9       12 * 8
-#define _JB_S10      13 * 8
-#define _JB_S11      14 * 8
-#define _JB_SP       15 * 8
-#define _JB_FS0      16 * 8
-#define _JB_FS1      17 * 8
-#define _JB_FS2      18 * 8
-#define _JB_FS3      19 * 8
-#define _JB_FS4      20 * 8
-#define _JB_FS5      21 * 8
-#define _JB_FS6      22 * 8
-#define _JB_FS7      23 * 8
-#define _JB_FS8      24 * 8
-#define _JB_FS9      25 * 8
-#define _JB_FS10     26 * 8
-#define _JB_FS11     27 * 8
-#define _JB_CHECKSUM 28 * 8
+#define _JB_SP        3 * 8
+#define _JB_GP        4 * 8
+#define _JB_S0        5 * 8
+#define _JB_S1        6 * 8
+#define _JB_S2        7 * 8
+#define _JB_S3        8 * 8
+#define _JB_S4        9 * 8
+#define _JB_S5       10 * 8
+#define _JB_S6       11 * 8
+#define _JB_S7       12 * 8
+#define _JB_S8       13 * 8
+#define _JB_S9       14 * 8
+#define _JB_S10      15 * 8
+#define _JB_S11      16 * 8
+#define _JB_FS0      17 * 8
+#define _JB_FS1      18 * 8
+#define _JB_FS2      19 * 8
+#define _JB_FS3      20 * 8
+#define _JB_FS4      21 * 8
+#define _JB_FS5      22 * 8
+#define _JB_FS6      23 * 8
+#define _JB_FS7      24 * 8
+#define _JB_FS8      25 * 8
+#define _JB_FS9      26 * 8
+#define _JB_FS10     27 * 8
+#define _JB_FS11     28 * 8
+#define _JB_CHECKSUM 29 * 8
 
 .macro m_mangle_registers reg, sp_reg
   xor s0, s0, \reg
   xor s1, s1, \reg
-  xor a4, a4, \reg  // a4 is the masked s2 (x18) for SCS.
+  xor s2, s2, \reg
   xor s3, s3, \reg
   xor s4, s4, \reg
   xor s5, s5, \reg
@@ -89,12 +91,13 @@
   xor s9, s9, \reg
   xor s10, s10, \reg
   xor s11, s11, \reg
+  xor a4, a4, \reg  // a4 is the masked gp (x3) for SCS.
   xor \sp_reg, \sp_reg, \reg
 .endm
 
 .macro m_calculate_checksum dst, src, scratch
   li \dst, 0
-  .irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27
+  .irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28
     ld \scratch, (\i * 8)(\src)
     xor \dst, \dst, \scratch
   .endr
@@ -152,19 +155,21 @@
   andi a1, a1, -2
 
   // Mask off the high bits of the shadow call stack pointer.
-  // We only store the low bits of x18 to avoid leaking the
+  // We only store the low bits of gp to avoid leaking the
   // shadow call stack address into memory.
   // See the SCS commentary in pthread_internal.h for more detail.
   li a4, SCS_MASK
-  and a4, a4, x18
+  and a4, a4, gp
 
   // Save core registers.
   mv a2, sp
   m_mangle_registers a1, sp_reg=a2
   sd ra,  _JB_RA(a0)
+  sd a4,  _JB_GP(a0)  // a4 is the masked gp (x3) for SCS.
+  sd a2,  _JB_SP(a0)
   sd s0,  _JB_S0(a0)
   sd s1,  _JB_S1(a0)
-  sd a4,  _JB_S2(a0)  // a4 is the masked s2 (x18) for SCS.
+  sd s2,  _JB_S2(a0)
   sd s3,  _JB_S3(a0)
   sd s4,  _JB_S4(a0)
   sd s5,  _JB_S5(a0)
@@ -174,7 +179,6 @@
   sd s9,  _JB_S9(a0)
   sd s10, _JB_S10(a0)
   sd s11, _JB_S11(a0)
-  sd a2,  _JB_SP(a0)
   m_unmangle_registers a1, sp_reg=a2
 
   // Save floating point registers.
@@ -236,9 +240,10 @@
   // Restore core registers.
   andi a2, a2, -2
   ld ra,  _JB_RA(a0)
+  ld a4,  _JB_GP(a0)  // Don't clobber the upper bits of gp (x3) used for SCS yet.
   ld s0,  _JB_S0(a0)
   ld s1,  _JB_S1(a0)
-  ld a4,  _JB_S2(a0)  // Don't clobber s2 (x18) used for SCS yet.
+  ld s2,  _JB_S2(a0)
   ld s3,  _JB_S3(a0)
   ld s4,  _JB_S4(a0)
   ld s5,  _JB_S5(a0)
@@ -254,8 +259,8 @@
 
   // Restore the low bits of the shadow call stack pointer.
   li a5, ~SCS_MASK
-  and x18, x18, a5
-  or x18, a4, x18
+  and gp, gp, a5
+  or gp, gp, a4
 
   addi sp, sp, -24
   sd   ra, 0(sp)
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 15d6d6d..7bf9b40 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -133,14 +133,14 @@
   size_t scs_offset =
       (getpid() == 1) ? 0 : (arc4random_uniform(SCS_GUARD_REGION_SIZE / SCS_SIZE - 1) * SCS_SIZE);
 
-  // Make the stack readable and writable and store its address in x18.
-  // This is deliberately the only place where the address is stored.
+  // Make the stack read-write, and store its address in the register we're using as the shadow
+  // stack pointer. This is deliberately the only place where the address is stored.
   char* scs = scs_aligned_guard_region + scs_offset;
   mprotect(scs, SCS_SIZE, PROT_READ | PROT_WRITE);
 #if defined(__aarch64__)
   __asm__ __volatile__("mov x18, %0" ::"r"(scs));
 #elif defined(__riscv)
-  __asm__ __volatile__("mv x18, %0" ::"r"(scs));
+  __asm__ __volatile__("mv gp, %0" ::"r"(scs));
 #endif
 #endif
 }
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 083c2ed..a3a4ccd 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -110,7 +110,8 @@
   // are actually used.
   //
   // This address is only used to deallocate the shadow call stack on thread
-  // exit; the address of the stack itself is stored only in the x18 register.
+  // exit; the address of the stack itself is stored only in the register used
+  // as the shadow stack pointer (x18 on arm64, gp on riscv64).
   //
   // Because the protection offered by SCS relies on the secrecy of the stack
   // address, storing the address here weakens the protection, but only
@@ -119,22 +120,24 @@
   // to other allocations), but not the stack itself, which is <0.1% of the size
   // of the guard region.
   //
-  // longjmp()/setjmp() don't store all the bits of x18, only the bottom bits
-  // covered by SCS_MASK. Since longjmp()/setjmp() between different threads is
-  // undefined behavior (and unsupported on Android), we can retrieve the high
-  // bits of x18 from the current value in x18 --- all the jmp_buf needs to store
-  // is where exactly the shadow stack pointer is in the thread's shadow stack:
-  // the bottom bits of x18.
+  // longjmp()/setjmp() don't store all the bits of the shadow stack pointer,
+  // only the bottom bits covered by SCS_MASK. Since longjmp()/setjmp() between
+  // different threads is undefined behavior (and unsupported on Android), we
+  // can retrieve the high bits of the shadow stack pointer from the current
+  // value in the register --- all the jmp_buf needs to store is where exactly
+  // the shadow stack pointer is *within* the thread's shadow stack: the bottom
+  // bits of the register.
   //
   // There are at least two other options for discovering the start address of
   // the guard region on thread exit, but they are not as simple as storing in
   // TLS.
   //
-  // 1) Derive it from the value of the x18 register. This is only possible in
-  //    processes that do not contain legacy code that might clobber x18,
-  //    therefore each process must declare early during process startup whether
-  //    it might load legacy code.
-  //    TODO: riscv64 has no legacy code, so we can actually go this route there!
+  // 1) Derive it from the current value of the shadow stack pointer. This is
+  //    only possible in processes that do not contain legacy code that might
+  //    clobber x18 on arm64, therefore each process must declare early during
+  //    process startup whether it might load legacy code.
+  //    TODO: riscv64 has no legacy code, so we can actually go this route
+  //    there, but hopefully we'll actually get the Zsslpcfi extension instead.
   // 2) Mark the guard region as such using prctl(PR_SET_VMA_ANON_NAME) and
   //    discover its address by reading /proc/self/maps. One issue with this is
   //    that reading /proc/self/maps can race with allocations, so we may need
diff --git a/libc/include/semaphore.h b/libc/include/semaphore.h
index 5d66f7e..6ad9ea3 100644
--- a/libc/include/semaphore.h
+++ b/libc/include/semaphore.h
@@ -45,12 +45,12 @@
 
 #define SEM_FAILED __BIONIC_CAST(reinterpret_cast, sem_t*, 0)
 
-int sem_clockwait(sem_t* __sem, clockid_t __clock, const struct timespec* __ts) __INTRODUCED_IN(30);
-int sem_destroy(sem_t* __sem);
-int sem_getvalue(sem_t* __sem, int* __value);
-int sem_init(sem_t* __sem, int __shared, unsigned int __value);
-int sem_post(sem_t* __sem);
-int sem_timedwait(sem_t* __sem, const struct timespec* __ts);
+int sem_clockwait(sem_t* _Nonnull __sem, clockid_t __clock, const struct timespec* _Nonnull __ts) __INTRODUCED_IN(30);
+int sem_destroy(sem_t* _Nonnull __sem);
+int sem_getvalue(sem_t* _Nonnull __sem, int* _Nonnull __value);
+int sem_init(sem_t* _Nonnull __sem, int __shared, unsigned int __value);
+int sem_post(sem_t* _Nonnull __sem);
+int sem_timedwait(sem_t* _Nonnull __sem, const struct timespec* _Nonnull __ts);
 /*
  * POSIX historically only supported using sem_timedwait() with CLOCK_REALTIME, however that is
  * typically inappropriate, since that clock can change dramatically, causing the timeout to either
@@ -59,14 +59,14 @@
  * Note that sem_clockwait() allows specifying an arbitrary clock and has superseded this
  * function.
  */
-int sem_timedwait_monotonic_np(sem_t* __sem, const struct timespec* __ts) __INTRODUCED_IN(28);
-int sem_trywait(sem_t* __sem);
-int sem_wait(sem_t* __sem);
+int sem_timedwait_monotonic_np(sem_t* _Nonnull __sem, const struct timespec* _Nonnull __ts) __INTRODUCED_IN(28);
+int sem_trywait(sem_t* _Nonnull __sem);
+int sem_wait(sem_t* _Nonnull __sem);
 
 /* These aren't actually implemented. */
-sem_t* sem_open(const char* __name, int _flags, ...);
-int sem_close(sem_t* __sem);
-int sem_unlink(const char* __name);
+sem_t* _Nullable sem_open(const char* _Nonnull __name, int _flags, ...);
+int sem_close(sem_t* _Nonnull __sem);
+int sem_unlink(const char* _Nonnull __name);
 
 __END_DECLS
 
diff --git a/libc/include/setjmp.h b/libc/include/setjmp.h
index 141e925..6d047ae 100644
--- a/libc/include/setjmp.h
+++ b/libc/include/setjmp.h
@@ -47,14 +47,33 @@
 #include <sys/cdefs.h>
 
 #if defined(__aarch64__)
+/**
+ * The size in words of an arm64 jmp_buf. Room for callee-saved registers,
+ * including floating point, stack pointer and program counter, various
+ * internal implementation details, and leaving some free space.
+ *
+ * Coincidentally matches OpenBSD, though they also save/restore the
+ * floating point status register too.
+ */
 #define _JBLEN 32
 #elif defined(__arm__)
+/** The size in words of an arm32 jmp_buf. Inherited from OpenBSD. */
 #define _JBLEN 64
 #elif defined(__i386__)
+/** The size in words of an x86 jmp_buf. Inherited from OpenBSD. */
 #define _JBLEN 10
 #elif defined(__riscv)
+/**
+ * The size in words of a riscv64 jmp_buf. Room for callee-saved registers,
+ * including floating point, stack pointer and program counter, various
+ * internal implementation details, and leaving some free space.
+ *
+ * Coincidentally matches OpenBSD, though they also save/restore the
+ * floating point status register too.
+ */
 #define _JBLEN 32
 #elif defined(__x86_64__)
+/** The size in words of an x86-64 jmp_buf. Inherited from OpenBSD. */
 #define _JBLEN 11
 #endif
 
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 4cdec44..fde3dfc 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -244,7 +244,7 @@
 
 genrule {
     name: "libdl.arm.map",
-    out: ["libdl.arm.map"],
+    out: ["libdl.arm.map.txt"],
     srcs: ["libdl.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -252,7 +252,7 @@
 
 genrule {
     name: "libdl.arm64.map",
-    out: ["libdl.arm64.map"],
+    out: ["libdl.arm64.map.txt"],
     srcs: ["libdl.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -260,7 +260,7 @@
 
 genrule {
     name: "libdl.riscv64.map",
-    out: ["libdl.riscv64.map"],
+    out: ["libdl.riscv64.map.txt"],
     srcs: ["libdl.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -268,7 +268,7 @@
 
 genrule {
     name: "libdl.x86.map",
-    out: ["libdl.x86.map"],
+    out: ["libdl.x86.map.txt"],
     srcs: ["libdl.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -276,7 +276,7 @@
 
 genrule {
     name: "libdl.x86_64.map",
-    out: ["libdl.x86_64.map"],
+    out: ["libdl.x86_64.map.txt"],
     srcs: ["libdl.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
diff --git a/libm/Android.bp b/libm/Android.bp
index 4c34fb6..13fbf9a 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -473,7 +473,7 @@
 
 genrule {
     name: "libm.arm.map",
-    out: ["libm.arm.map"],
+    out: ["libm.arm.map.txt"],
     srcs: ["libm.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -481,7 +481,7 @@
 
 genrule {
     name: "libm.arm64.map",
-    out: ["libm.arm64.map"],
+    out: ["libm.arm64.map.txt"],
     srcs: ["libm.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -489,7 +489,7 @@
 
 genrule {
     name: "libm.riscv64.map",
-    out: ["libm.riscv64.map"],
+    out: ["libm.riscv64.map.txt"],
     srcs: ["libm.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -497,7 +497,7 @@
 
 genrule {
     name: "libm.x86.map",
-    out: ["libm.x86.map"],
+    out: ["libm.x86.map.txt"],
     srcs: ["libm.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -505,7 +505,7 @@
 
 genrule {
     name: "libm.x86_64.map",
-    out: ["libm.x86_64.map"],
+    out: ["libm.x86_64.map.txt"],
     srcs: ["libm.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
diff --git a/tests/semaphore_test.cpp b/tests/semaphore_test.cpp
index f3f6020..6f8797f 100644
--- a/tests/semaphore_test.cpp
+++ b/tests/semaphore_test.cpp
@@ -165,8 +165,10 @@
 TEST_F(semaphore_DeathTest, sem_timedwait_null_timeout) {
   sem_t s;
   ASSERT_EQ(0, sem_init(&s, 0, 0));
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   ASSERT_EXIT(sem_timedwait(&s, nullptr), testing::KilledBySignal(SIGSEGV), "");
+#pragma clang diagnostic pop
 }
 
 TEST(semaphore, sem_getvalue) {