Merge "Fix the types in the arm64 dynamic function dispatch."
diff --git a/docs/defines.md b/docs/defines.md
index 65a715e..65cc873 100644
--- a/docs/defines.md
+++ b/docs/defines.md
@@ -54,13 +54,19 @@
 work around issues with some of them, use these macros to detect the versinon of
 the NDK you're being built with. Usually only `__NDK_MAJOR__` will be necessary.
 
-## `__arm__`, `__aarch64__`, `__i386__`, `__x86_64__`, `__riscv`
+## `__arm__`/`__aarch64__`, `__i386__`/`__x86_64__`, `__riscv`
 
-If your code is specific to a particular processor architecture, use these
-macros to conditionally compile. Note that the ABI usually called `arm64` uses
-the macro `__aarch64__` and the ABI usually called `x86` uses `__i386__`.
+If your code is specific to a particular processor architecture, use
+these macros to conditionally compile. Note that the ABI usually called
+`arm64` uses the macro `__aarch64__` and the ABI usually called `x86` uses
+`__i386__`. Android only supports riscv64, so `__riscv` is a sufficient
+check for Android-only code. If you need to write code portable to other
+operating systems that do support riscv32, you'll also need to check
+whether `__riscv_xlen` is 32 or 64.
 
-## `__LP32__` and `__LP64__`
+## `__ILP32__` and `__LP64__`
 
-If your code depends on "bitness" -- whether `long` and pointers are 32- or
-64-bit -- use these macros to conditionally compile.
+If your code depends on "bitness" -- whether `long` and pointers are 32-
+or 64-bit -- use these macros to conditionally compile. Note the extra
+"I" in the 32-bit macro (since `int`, `long`, and pointers are all 32-bit
+on such systems, with `long long` being needed for a 64-bit type).
diff --git a/libc/bionic/gwp_asan_wrappers.cpp b/libc/bionic/gwp_asan_wrappers.cpp
index fab29ef..251633d 100644
--- a/libc/bionic/gwp_asan_wrappers.cpp
+++ b/libc/bionic/gwp_asan_wrappers.cpp
@@ -307,10 +307,8 @@
     sysprop_names[3] = persist_default_sysprop;
   }
 
-  // TODO(mitchp): Log overrides using this.
-  const char* source;
   return get_config_from_env_or_sysprops(env_var, sysprop_names, arraysize(sysprop_names),
-                                         value_out, PROP_VALUE_MAX, &source);
+                                         value_out, PROP_VALUE_MAX);
 }
 
 bool GetGwpAsanIntegerOption(unsigned long long* result,
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 0935cd6..d64d402 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -217,13 +217,16 @@
 // Returns true if there's an environment setting (either sysprop or env var)
 // that should overwrite the ELF note, and places the equivalent heap tagging
 // level into *level.
-static bool get_environment_memtag_setting(const char* basename, HeapTaggingLevel* level) {
+static bool get_environment_memtag_setting(HeapTaggingLevel* level) {
   static const char kMemtagPrognameSyspropPrefix[] = "arm64.memtag.process.";
   static const char kMemtagGlobalSysprop[] = "persist.arm64.memtag.default";
   static const char kMemtagOverrideSyspropPrefix[] =
       "persist.device_config.memory_safety_native.mode_override.process.";
 
-  if (basename == nullptr) return false;
+  const char* progname = __libc_shared_globals()->init_progname;
+  if (progname == nullptr) return false;
+
+  const char* basename = __gnu_basename(progname);
 
   char options_str[PROP_VALUE_MAX];
   char sysprop_name[512];
@@ -234,9 +237,8 @@
                            kMemtagOverrideSyspropPrefix, basename);
   const char* sys_prop_names[] = {sysprop_name, remote_sysprop_name, kMemtagGlobalSysprop};
 
-  const char* source = nullptr;
   if (!get_config_from_env_or_sysprops("MEMTAG_OPTIONS", sys_prop_names, arraysize(sys_prop_names),
-                                       options_str, sizeof(options_str), &source)) {
+                                       options_str, sizeof(options_str))) {
     return false;
   }
 
@@ -247,20 +249,14 @@
   } else if (strcmp("off", options_str) == 0) {
     *level = M_HEAP_TAGGING_LEVEL_TBI;
   } else {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc",
-                          "%s: unrecognized memtag level in %s: \"%s\" (options are \"sync\", "
-                          "\"async\", or \"off\").",
-                          basename, source, options_str);
+    async_safe_format_log(
+        ANDROID_LOG_ERROR, "libc",
+        "unrecognized memtag level: \"%s\" (options are \"sync\", \"async\", or \"off\").",
+        options_str);
     return false;
   }
-  async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "%s: chose memtag level \"%s\" from %s.",
-                        basename, options_str, source);
-  return true;
-}
 
-static void log_elf_memtag_level(const char* basename, const char* level) {
-  async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "%s: chose memtag level \"%s\" from ELF note",
-                        basename ?: "<unknown>", level);
+  return true;
 }
 
 // Returns the initial heap tagging level. Note: This function will never return
@@ -268,14 +264,12 @@
 // M_HEAP_TAGGING_LEVEL_TBI.
 static HeapTaggingLevel __get_heap_tagging_level(const void* phdr_start, size_t phdr_ct,
                                                  uintptr_t load_bias, bool* stack) {
-  const char* progname = __libc_shared_globals()->init_progname;
-  const char* basename = progname ? __gnu_basename(progname) : nullptr;
   unsigned note_val =
       __get_memtag_note(reinterpret_cast<const ElfW(Phdr)*>(phdr_start), phdr_ct, load_bias);
   *stack = note_val & NT_MEMTAG_STACK;
 
   HeapTaggingLevel level;
-  if (get_environment_memtag_setting(basename, &level)) return level;
+  if (get_environment_memtag_setting(&level)) return level;
 
   // Note, previously (in Android 12), any value outside of bits [0..3] resulted
   // in a check-fail. In order to be permissive of further extensions, we
@@ -290,17 +284,14 @@
       // by anyone, but we note it (heh) here for posterity, in case the zero
       // level becomes meaningful, and binaries with this note can be executed
       // on Android 12 devices.
-      log_elf_memtag_level(basename, "off");
       return M_HEAP_TAGGING_LEVEL_TBI;
     case NT_MEMTAG_LEVEL_ASYNC:
-      log_elf_memtag_level(basename, "async");
       return M_HEAP_TAGGING_LEVEL_ASYNC;
     case NT_MEMTAG_LEVEL_SYNC:
     default:
       // We allow future extensions to specify mode 3 (currently unused), with
       // the idea that it might be used for ASYMM mode or something else. On
       // this version of Android, it falls back to SYNC mode.
-      log_elf_memtag_level(basename, "sync");
       return M_HEAP_TAGGING_LEVEL_SYNC;
   }
 }
diff --git a/libc/bionic/sysprop_helpers.cpp b/libc/bionic/sysprop_helpers.cpp
index 2051330..5627034 100644
--- a/libc/bionic/sysprop_helpers.cpp
+++ b/libc/bionic/sysprop_helpers.cpp
@@ -57,22 +57,18 @@
 }
 
 bool get_config_from_env_or_sysprops(const char* env_var_name, const char* const* sys_prop_names,
-                                     size_t sys_prop_names_size, char* options, size_t options_size,
-                                     const char** chosen_source) {
+                                     size_t sys_prop_names_size, char* options,
+                                     size_t options_size) {
   const char* env = getenv(env_var_name);
   if (env && *env != '\0') {
     strncpy(options, env, options_size);
     options[options_size - 1] = '\0';  // Ensure null-termination.
-    *chosen_source = env_var_name;
     return true;
   }
 
   for (size_t i = 0; i < sys_prop_names_size; ++i) {
     if (sys_prop_names[i] == nullptr) continue;
-    if (get_property_value(sys_prop_names[i], options, options_size)) {
-      *chosen_source = sys_prop_names[i];
-      return true;
-    }
+    if (get_property_value(sys_prop_names[i], options, options_size)) return true;
   }
   return false;
 }
diff --git a/libc/bionic/sysprop_helpers.h b/libc/bionic/sysprop_helpers.h
index 84e7af1..a02c2dc 100644
--- a/libc/bionic/sysprop_helpers.h
+++ b/libc/bionic/sysprop_helpers.h
@@ -36,13 +36,10 @@
 //   2. System properties, in the order they're specified in sys_prop_names.
 // If neither of these options are specified (or they're both an empty string),
 // this function returns false. Otherwise, it returns true, and the presiding
-// options string is written to the `options` buffer of size `size`. It will
-// store a pointer to either env_var_name, or into the relevant entry of
-// sys_prop_names into choicen_source, indiciating which value was used. If
-// this function returns true, `options` is guaranteed to be null-terminated.
+// options string is written to the `options` buffer of size `size`. If this
+// function returns true, `options` is guaranteed to be null-terminated.
 // `options_size` should be at least PROP_VALUE_MAX.
 __LIBC_HIDDEN__ bool get_config_from_env_or_sysprops(const char* env_var_name,
                                                      const char* const* sys_prop_names,
                                                      size_t sys_prop_names_size, char* options,
-                                                     size_t options_size,
-                                                     const char** chosen_source);
+                                                     size_t options_size);
diff --git a/libc/include/sys/_system_properties.h b/libc/include/sys/_system_properties.h
index 744a45b..943d4c6 100644
--- a/libc/include/sys/_system_properties.h
+++ b/libc/include/sys/_system_properties.h
@@ -61,7 +61,7 @@
 ** This was previously for testing, but now that SystemProperties is its own testable class,
 ** there is never a reason to call this function and its implementation simply returns -1.
 */
-int __system_property_set_filename(const char* __filename);
+int __system_property_set_filename(const char* __unused __filename);
 
 /*
 ** Initialize the area to be used to store properties.  Can
@@ -102,7 +102,7 @@
 **
 ** Returns 0 on success, -1 if the property area is full.
 */
-int __system_property_add(const char* __name, unsigned int __name_length, const char* __value, unsigned int __value_length);
+int __system_property_add(const char* _Nonnull __name, unsigned int __name_length, const char* _Nonnull __value, unsigned int __value_length);
 
 /* Update the value of a system property returned by
 ** __system_property_find.  Can only be done by a single process
@@ -112,14 +112,14 @@
 **
 ** Returns 0 on success, -1 if the parameters are incorrect.
 */
-int __system_property_update(prop_info* __pi, const char* __value, unsigned int __value_length);
+int __system_property_update(prop_info* _Nonnull __pi, const char* _Nonnull __value, unsigned int __value_length);
 
 /* Read the serial number of a system property returned by
 ** __system_property_find.
 **
 ** Returns the serial number on success, -1 on error.
 */
-uint32_t __system_property_serial(const prop_info* __pi);
+uint32_t __system_property_serial(const prop_info* _Nonnull __pi);
 
 /* Initialize the system properties area in read only mode.
  * Should be done by all processes that need to read system
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index bcf856d..cbe6a75 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -50,9 +50,9 @@
  * and returns `MAP_FAILED` and sets `errno` on failure.
  */
 #if defined(__USE_FILE_OFFSET64)
-void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset) __RENAME(mmap64);
+void* _Nonnull mmap(void* _Nullable __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);
+void* _Nonnull mmap(void* _Nullable __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset);
 #endif
 
 /**
@@ -62,7 +62,7 @@
  *
  * Available since API level 21.
  */
-void* mmap64(void* __addr, size_t __size, int __prot, int __flags, int __fd, off64_t __offset) __INTRODUCED_IN(21);
+void* _Nonnull mmap64(void* _Nullable __addr, size_t __size, int __prot, int __flags, int __fd, off64_t __offset) __INTRODUCED_IN(21);
 
 /**
  * [munmap(2)](http://man7.org/linux/man-pages/man2/munmap.2.html)
@@ -70,7 +70,7 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int munmap(void* __addr, size_t __size);
+int munmap(void* _Nonnull __addr, size_t __size);
 
 /**
  * [msync(2)](http://man7.org/linux/man-pages/man2/msync.2.html)
@@ -78,7 +78,7 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int msync(void* __addr, size_t __size, int __flags);
+int msync(void* _Nonnull __addr, size_t __size, int __flags);
 
 /**
  * [mprotect(2)](http://man7.org/linux/man-pages/man2/mprotect.2.html)
@@ -86,7 +86,7 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int mprotect(void* __addr, size_t __size, int __prot);
+int mprotect(void* _Nonnull __addr, size_t __size, int __prot);
 
 /** Flag for mremap(). */
 #define MREMAP_MAYMOVE  1
@@ -101,7 +101,7 @@
  * Returns the address of the mapping on success,
  * and returns `MAP_FAILED` and sets `errno` on failure.
  */
-void* mremap(void* __old_addr, size_t __old_size, size_t __new_size, int __flags, ...);
+void* _Nonnull mremap(void* _Nonnull __old_addr, size_t __old_size, size_t __new_size, int __flags, ...);
 
 /**
  * [mlockall(2)](http://man7.org/linux/man-pages/man2/mlockall.2.html)
@@ -129,7 +129,7 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int mlock(const void* __addr, size_t __size);
+int mlock(const void* _Nonnull __addr, size_t __size);
 
 /**
  * [mlock2(2)](http://man7.org/linux/man-pages/man2/mlock.2.html)
@@ -139,7 +139,7 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int mlock2(const void* __addr, size_t __size, int __flags) __INTRODUCED_IN(30);
+int mlock2(const void* _Nonnull __addr, size_t __size, int __flags) __INTRODUCED_IN(30);
 
 /**
  * [munlock(2)](http://man7.org/linux/man-pages/man2/munlock.2.html)
@@ -147,7 +147,7 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int munlock(const void* __addr, size_t __size);
+int munlock(const void* _Nonnull __addr, size_t __size);
 
 /**
  * [mincore(2)](http://man7.org/linux/man-pages/man2/mincore.2.html)
@@ -155,7 +155,7 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int mincore(void* __addr, size_t __size, unsigned char* __vector);
+int mincore(void* _Nonnull __addr, size_t __size, unsigned char* _Nonnull __vector);
 
 /**
  * [madvise(2)](http://man7.org/linux/man-pages/man2/madvise.2.html)
@@ -163,7 +163,7 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int madvise(void* __addr, size_t __size, int __advice);
+int madvise(void* _Nonnull __addr, size_t __size, int __advice);
 
 /**
  * [process_madvise(2)](http://man7.org/linux/man-pages/man2/process_madvise.2.html)
@@ -177,7 +177,7 @@
  *
  * Returns the number of bytes advised on success, and returns -1 and sets `errno` on failure.
  */
-ssize_t process_madvise(int __pid_fd, const struct iovec* __iov, size_t __count, int __advice, unsigned __flags) __INTRODUCED_IN(31);
+ssize_t process_madvise(int __pid_fd, const struct iovec* _Nonnull __iov, size_t __count, int __advice, unsigned __flags) __INTRODUCED_IN(31);
 
 #if defined(__USE_GNU)
 
@@ -189,7 +189,7 @@
  *
  * Returns an fd on success, and returns -1 and sets `errno` on failure.
  */
-int memfd_create(const char* __name, unsigned __flags) __INTRODUCED_IN(30);
+int memfd_create(const char* _Nonnull __name, unsigned __flags) __INTRODUCED_IN(30);
 
 #endif
 
@@ -226,6 +226,6 @@
  *
  * Returns 0 on success, and returns a positive error number on failure.
  */
-int posix_madvise(void* __addr, size_t __size, int __advice) __INTRODUCED_IN(23);
+int posix_madvise(void* _Nonnull __addr, size_t __size, int __advice) __INTRODUCED_IN(23);
 
 __END_DECLS
diff --git a/libc/include/sys/system_properties.h b/libc/include/sys/system_properties.h
index a2e1923..06b2188 100644
--- a/libc/include/sys/system_properties.h
+++ b/libc/include/sys/system_properties.h
@@ -43,7 +43,7 @@
 /*
  * Sets system property `name` to `value`, creating the system property if it doesn't already exist.
  */
-int __system_property_set(const char* __name, const char* __value);
+int __system_property_set(const char* _Nonnull __name, const char* _Nonnull __value);
 
 /*
  * Returns a `prop_info` corresponding system property `name`, or nullptr if it doesn't exist.
@@ -51,14 +51,14 @@
  *
  * Property lookup is expensive, so it can be useful to cache the result of this function.
  */
-const prop_info* __system_property_find(const char* __name);
+const prop_info* _Nullable __system_property_find(const char* _Nonnull __name);
 
 /*
  * Calls `callback` with a consistent trio of name, value, and serial number for property `pi`.
  */
-void __system_property_read_callback(const prop_info* __pi,
-    void (*__callback)(void* __cookie, const char* __name, const char* __value, uint32_t __serial),
-    void* __cookie) __INTRODUCED_IN(26);
+void __system_property_read_callback(const prop_info* _Nonnull __pi,
+    void (* _Nonnull __callback)(void* _Nullable __cookie, const char* _Nonnull __name, const char* _Nonnull __value, uint32_t __serial),
+    void* _Nullable __cookie) __INTRODUCED_IN(26);
 
 /*
  * Passes a `prop_info` for each system property to the provided
@@ -66,13 +66,13 @@
  *
  * This method is for inspecting and debugging the property system, and not generally useful.
  */
-int __system_property_foreach(void (*__callback)(const prop_info* __pi, void* __cookie), void* __cookie)
+int __system_property_foreach(void (* _Nonnull __callback)(const prop_info* _Nonnull __pi, void* _Nullable __cookie), void* _Nullable __cookie)
   __INTRODUCED_IN(19);
 
 /*
  * Waits for the specific system property identified by `pi` to be updated
  * past `old_serial`. Waits no longer than `relative_timeout`, or forever
- * if `relaive_timeout` is null.
+ * if `relative_timeout` is null.
  *
  * If `pi` is null, waits for the global serial number instead.
  *
@@ -82,17 +82,17 @@
  * timed out.
  */
 struct timespec;
-bool __system_property_wait(const prop_info* __pi, uint32_t __old_serial, uint32_t* __new_serial_ptr, const struct timespec* __relative_timeout)
+bool __system_property_wait(const prop_info* _Nullable __pi, uint32_t __old_serial, uint32_t* _Nonnull __new_serial_ptr, const struct timespec* _Nullable __relative_timeout)
     __INTRODUCED_IN(26);
 
 /* Deprecated. In Android O and above, there's no limit on property name length. */
 #define PROP_NAME_MAX   32
 /* Deprecated. Use __system_property_read_callback instead. */
-int __system_property_read(const prop_info* __pi, char* __name, char* __value);
+int __system_property_read(const prop_info* _Nonnull __pi, char* _Nullable __name, char* _Nonnull __value);
 /* Deprecated. Use __system_property_read_callback instead. */
-int __system_property_get(const char* __name, char* __value);
+int __system_property_get(const char* _Nonnull __name, char* _Nonnull __value);
 /* Deprecated. Use __system_property_foreach instead. */
-const prop_info* __system_property_find_nth(unsigned __n);
+const prop_info* _Nullable __system_property_find_nth(unsigned __n);
 
 __END_DECLS
 
diff --git a/libfdtrack/Android.bp b/libfdtrack/Android.bp
index 83ea7cb..7539052 100644
--- a/libfdtrack/Android.bp
+++ b/libfdtrack/Android.bp
@@ -22,10 +22,16 @@
     static_libs: [
         "libasync_safe",
         "libbase",
+        "libdexfile_support",
         "libunwindstack",
         "liblzma",
         "liblog",
     ],
+    target: {
+        recovery: {
+            exclude_static_libs: ["libdexfile_support"],
+        },
+    },
     version_script: "libfdtrack.map.txt",
 
     allow_undefined_symbols: true,
diff --git a/libfdtrack/fdtrack.cpp b/libfdtrack/fdtrack.cpp
index b064401..57b9d37 100644
--- a/libfdtrack/fdtrack.cpp
+++ b/libfdtrack/fdtrack.cpp
@@ -45,10 +45,8 @@
 #include <android-base/thread_annotations.h>
 #include <async_safe/log.h>
 #include <bionic/reserved_signals.h>
-#include <unwindstack/Maps.h>
-#include <unwindstack/Regs.h>
-#include <unwindstack/RegsGetLocal.h>
-#include <unwindstack/Unwinder.h>
+
+#include <unwindstack/AndroidUnwinder.h>
 
 struct FdEntry {
   std::mutex mutex;
@@ -70,22 +68,16 @@
 // Only unwind up to 32 frames outside of libfdtrack.so.
 static constexpr size_t kStackDepth = 32;
 
-// Skip any initial frames from 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]];
-static unwindstack::LocalUpdatableMaps& Maps() {
-  static android::base::NoDestructor<unwindstack::LocalUpdatableMaps> maps;
-  return *maps.get();
-}
-static std::shared_ptr<unwindstack::Memory>& ProcessMemory() {
-  static android::base::NoDestructor<std::shared_ptr<unwindstack::Memory>> process_memory;
-  return *process_memory.get();
+static unwindstack::AndroidLocalUnwinder& Unwinder() {
+  // Skip any initial frames from 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 android::base::NoDestructor<unwindstack::AndroidLocalUnwinder> unwinder(
+      std::vector<std::string>{"libfdtrack.so", "libart.so"});
+  return *unwinder.get();
 }
 
 __attribute__((constructor)) static void ctor() {
@@ -104,8 +96,8 @@
   sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
   sigaction(BIONIC_SIGNAL_FDTRACK, &sa, nullptr);
 
-  if (Maps().Parse()) {
-    ProcessMemory() = unwindstack::Memory::CreateProcessMemoryThreadCached(getpid());
+  unwindstack::ErrorData error;
+  if (Unwinder().Initialize(error)) {
     android_fdtrack_hook_t expected = nullptr;
     installed = android_fdtrack_compare_exchange_hook(&expected, &fd_hook);
   }
@@ -133,11 +125,10 @@
       std::lock_guard<std::mutex> lock(entry->mutex);
       entry->backtrace.clear();
 
-      std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::CreateFromLocal());
-      unwindstack::RegsGetLocal(regs.get());
-      unwindstack::Unwinder unwinder(kStackDepth, &Maps(), regs.get(), ProcessMemory());
-      unwinder.Unwind(&kSkipFdtrackLib);
-      entry->backtrace = unwinder.ConsumeFrames();
+      unwindstack::AndroidUnwinderData data(kStackDepth);
+      if (Unwinder().Unwind(data)) {
+        entry->backtrace = std::move(data.frames);
+      }
     }
   } else if (event->type == ANDROID_FDTRACK_EVENT_TYPE_CLOSE) {
     if (FdEntry* entry = GetFdEntry(event->fd); entry) {
diff --git a/tests/sys_mman_test.cpp b/tests/sys_mman_test.cpp
index e403ea5..803852a 100644
--- a/tests/sys_mman_test.cpp
+++ b/tests/sys_mman_test.cpp
@@ -218,7 +218,10 @@
 }
 
 TEST(sys_mman, mremap) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   ASSERT_EQ(MAP_FAILED, mremap(nullptr, 0, 0, 0));
+#pragma clang diagnostic pop
 }
 
 constexpr size_t kHuge = size_t(PTRDIFF_MAX) + 1;