[compiler-rt] [asan][tsan][ubasn][test][darwin] Fix some sanitizer tests on Apple platforms (PR #207898)

Ian Anderson via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 6 22:11:38 PDT 2026


https://github.com/ian-twilightcoder created https://github.com/llvm/llvm-project/pull/207898

asan_symbolize doesn't seem to be working properly on Apple Silicon Macs when /usr/lib/dyld is involved, XFAIL the affected tests.

Array cookie poisoning hooks are not generated for arm64, XFAIL those tests as well.
Array cookies are supported on ARM though, they're just a different size than Itanium. Update new_array_cookie_with_new_from_class.cpp to use the correct size.

rdar://109379358 is fixed, get rid of that to remove the XPASS status.

str{n}cpy has an extra cold function on Darwin, support that in the tests.

dedup_token_length_test.cpp failes for UBSan on macOS Apple Silicon, TSan on iOS, and all the time on watchOS and tvOS.

>From 53098669eefb0717dfada38b603bec2cd395f7a1 Mon Sep 17 00:00:00 2001
From: Ian Anderson <iana at apple.com>
Date: Mon, 6 Jul 2026 17:29:07 -0700
Subject: [PATCH] [asan][tsan][ubasn][test][darwin] Fix some sanitizer tests on
 Apple platforms

asan_symbolize doesn't seem to be working properly on Apple Silicon Macs when /usr/lib/dyld is involved, XFAIL the affected tests.

Array cookie poisoning hooks are not generated for arm64, XFAIL those tests as well.
Array cookies are supported on ARM though, they're just a different size than Itanium. Update new_array_cookie_with_new_from_class.cpp to use the correct size.

rdar://109379358 is fixed, get rid of that to remove the XPASS status.

str{n}cpy has an extra cold function on Darwin, support that in the tests.

dedup_token_length_test.cpp failes for UBSan on macOS Apple Silicon, TSan on iOS, and all the time on watchOS and tvOS.
---
 ...ymbolize-partial-report-with-module-map.cpp |  6 ++++++
 .../Darwin/asan-symbolize-with-module-map.cpp  |  5 +++++
 .../Posix/asan-symbolize-sanity-test.cpp       |  4 ++++
 .../plugin_no_op_symbolicate.cpp               |  5 +++++
 .../plugin_wrong_frame_number_bug.cpp          |  4 ++++
 .../TestCases/Posix/new_array_cookie_test.cpp  |  1 +
 .../Posix/new_array_cookie_uaf_test.cpp        |  1 +
 .../new_array_cookie_with_new_from_class.cpp   | 11 ++++++++---
 .../test/asan/TestCases/strcpy-overlap.cpp     | 18 +++++++++++-------
 .../test/asan/TestCases/strncpy-overlap.cpp    | 18 +++++++++++-------
 .../Posix/dedup_token_length_test.cpp          |  7 +++++++
 11 files changed, 63 insertions(+), 17 deletions(-)

diff --git a/compiler-rt/test/asan/TestCases/Darwin/asan-symbolize-partial-report-with-module-map.cpp b/compiler-rt/test/asan/TestCases/Darwin/asan-symbolize-partial-report-with-module-map.cpp
index 750df8109029f..a0cbcdc3909f4 100644
--- a/compiler-rt/test/asan/TestCases/Darwin/asan-symbolize-partial-report-with-module-map.cpp
+++ b/compiler-rt/test/asan/TestCases/Darwin/asan-symbolize-partial-report-with-module-map.cpp
@@ -1,4 +1,10 @@
 // UNSUPPORTED: darwin-remote
+
+// The test process is usually arm64, but /usr/lib/dyld is arm64e, so when
+// asan_symbolize calls otool/llvm-symbolizer for arm64, it fails.
+// rdar://181532154
+// XFAIL: darwin && arm64-target-arch
+
 // FIXME(dliew): We currently have to use module map for this test due to the atos
 // symbolizer changing the module name from an absolute path to just the file name.
 // rdar://problem/49784442
diff --git a/compiler-rt/test/asan/TestCases/Darwin/asan-symbolize-with-module-map.cpp b/compiler-rt/test/asan/TestCases/Darwin/asan-symbolize-with-module-map.cpp
index 7de28b0dfd172..b5c99ef6affc7 100644
--- a/compiler-rt/test/asan/TestCases/Darwin/asan-symbolize-with-module-map.cpp
+++ b/compiler-rt/test/asan/TestCases/Darwin/asan-symbolize-with-module-map.cpp
@@ -1,4 +1,9 @@
 // UNSUPPORTED: darwin-remote
+
+// The test process is usually arm64, but /usr/lib/dyld is arm64e, so when
+// asan_symbolize calls otool/llvm-symbolizer for arm64, it fails.
+// XFAIL: darwin && arm64-target-arch
+
 // RUN: %clangxx_asan -O0 -g %s -o %t.executable
 
 // Deliberately don't produce the module map and then check that offline symbolization fails
diff --git a/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cpp b/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cpp
index ab57400b78c58..de8a1d5ce2615 100644
--- a/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cpp
@@ -1,6 +1,10 @@
 // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316
 // XFAIL: android
 //
+// The test process is usually arm64, but /usr/lib/dyld is arm64e, so when
+// asan_symbolize calls otool/llvm-symbolizer for arm64, it fails.
+// XFAIL: darwin && arm64-target-arch
+//
 // Check that asan_symbolize.py script works (for binaries, ASan RTL and
 // shared object files.
 
diff --git a/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_no_op_symbolicate.cpp b/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_no_op_symbolicate.cpp
index 3f3ad9bfdf753..b35cb649f2028 100644
--- a/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_no_op_symbolicate.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_no_op_symbolicate.cpp
@@ -1,4 +1,9 @@
 // UNSUPPORTED: ios, android
+
+// The test process is usually arm64, but /usr/lib/dyld is arm64e, so when
+// asan_symbolize calls otool/llvm-symbolizer for arm64, it fails.
+// XFAIL: darwin && arm64-target-arch
+
 // Check plugin command line args get parsed and that plugin functions get called as expected.
 
 // RUN: %clangxx_asan -O0 -g %s -o %t.executable
diff --git a/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_wrong_frame_number_bug.cpp b/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_wrong_frame_number_bug.cpp
index 6c71660f37541..e564f857e8b4b 100644
--- a/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_wrong_frame_number_bug.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_wrong_frame_number_bug.cpp
@@ -3,6 +3,10 @@
 // UNSUPPORTED: android
 // UNSUPPORTED: darwin-remote
 
+// The test process is usually arm64, but /usr/lib/dyld is arm64e, so when
+// asan_symbolize calls otool/llvm-symbolizer for arm64, it fails.
+// XFAIL: darwin && arm64-target-arch
+
 // RUN: %clangxx_asan -O0 -g %s -o %t
 // RUN: %env_asan_opts=symbolize=0 not %run %t DUMMY_ARG > %t.asan_report 2>&1
 // RUN: %asan_symbolize --log-level debug --log-dest %t_debug_log_output.txt -l %t.asan_report --plugins %S/plugin_wrong_frame_number_bug.py > %t.asan_report_sym
diff --git a/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_test.cpp b/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_test.cpp
index fa896128cdb72..0b597365b626f 100644
--- a/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_test.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_test.cpp
@@ -5,6 +5,7 @@
 // RUN: %env_asan_opts=poison_array_cookie=0 not %run %t 2>&1  | FileCheck %s --check-prefix=NO_COOKIE
 
 // UNSUPPORTED: ios
+// XFAIL: darwin && (arm64-target-arch || arm64e-target-arch)
 
 // Poisoning C++ array redzones is not implemented on arm
 // XFAIL: target=arm{{.*}}
diff --git a/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cpp b/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cpp
index 63b1171df0aef..866e170668541 100644
--- a/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cpp
@@ -4,6 +4,7 @@
 // RUN: %env_asan_opts=poison_array_cookie=0 not %run %t 2>&1  | FileCheck %s --check-prefix=NO_COOKIE
 
 // UNSUPPORTED: ios
+// XFAIL: darwin && (arm64-target-arch || arm64e-target-arch)
 
 // Poisoning C++ array redzones is not implemented on arm
 // XFAIL: target=arm{{.*}}
diff --git a/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cpp b/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cpp
index 23d65100f96a8..da7e99681bbf5 100644
--- a/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cpp
@@ -1,8 +1,6 @@
 // Test that we do not poison the array cookie if the operator new is defined
 // inside the class.
 // RUN: %clangxx_asan  %s -o %t && %run %t
-//
-// XFAIL: target=arm{{.*}}
 
 // UNSUPPORTED: darwin-remote
 
@@ -11,6 +9,13 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <assert.h>
+
+#if defined(__arm__) || defined(__arm64__)
+static const size_t kArrayCookieSize = 2 * sizeof(void *);
+#else
+static const size_t kArrayCookieSize = sizeof(void *);
+#endif
+
 struct Foo {
   void *operator new(size_t s) { return Allocate(s); }
   void *operator new[] (size_t s) { return Allocate(s); }
@@ -34,7 +39,7 @@ int main() {
   fprintf(stderr, "foo  : %p\n", foo);
   fprintf(stderr, "alloc: %p\n", Foo::allocated);
   assert(reinterpret_cast<uintptr_t>(foo) ==
-         reinterpret_cast<uintptr_t>(Foo::allocated) + sizeof(void*));
+         reinterpret_cast<uintptr_t>(Foo::allocated) + kArrayCookieSize);
   *reinterpret_cast<uintptr_t*>(Foo::allocated) = 42;
   return 0;
 }
diff --git a/compiler-rt/test/asan/TestCases/strcpy-overlap.cpp b/compiler-rt/test/asan/TestCases/strcpy-overlap.cpp
index 89ac7a39b33ca..e50f8786970eb 100644
--- a/compiler-rt/test/asan/TestCases/strcpy-overlap.cpp
+++ b/compiler-rt/test/asan/TestCases/strcpy-overlap.cpp
@@ -1,26 +1,26 @@
 // RUN: %clangxx_asan -O0 -fno-builtin %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: not %run %t 2>&1 | FileCheck %s %if system-darwin %{ --check-prefixes=CHECK,DARWIN %} %else %{ --check-prefixes=CHECK,NON_DARWIN %}
 // RUN: echo "interceptor_via_fun:bad_function" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 // RUN: echo "interceptor_name:strcpy" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 //
 // RUN: %clangxx_asan -O1 -fno-builtin %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: not %run %t 2>&1 | FileCheck %s %if system-darwin %{ --check-prefixes=CHECK,DARWIN %} %else %{ --check-prefixes=CHECK,NON_DARWIN %}
 // RUN: echo "interceptor_via_fun:bad_function" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 // RUN: echo "interceptor_name:strcpy" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 //
 // RUN: %clangxx_asan -O2 -fno-builtin %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: not %run %t 2>&1 | FileCheck %s %if system-darwin %{ --check-prefixes=CHECK,DARWIN %} %else %{ --check-prefixes=CHECK,NON_DARWIN %}
 // RUN: echo "interceptor_via_fun:bad_function" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 // RUN: echo "interceptor_name:strcpy" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 //
 // RUN: %clangxx_asan -O3 -fno-builtin %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: not %run %t 2>&1 | FileCheck %s %if system-darwin %{ --check-prefixes=CHECK,DARWIN %} %else %{ --check-prefixes=CHECK,NON_DARWIN %}
 // RUN: echo "interceptor_via_fun:bad_function" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 // RUN: echo "interceptor_name:strcpy" > %t.supp
@@ -37,9 +37,13 @@ ATTRIBUTE_NOINLINE void bad_function() {
   char buffer[] = "hello";
   // CHECK: strcpy-param-overlap: memory ranges
   // CHECK: [{{0x.*,[ ]*0x.*}}) and [{{0x.*,[ ]*0x.*}}) overlap
-  // CHECK: {{#0 0x.* in .*strcpy}}
-  // CHECK: {{#1 0x.* in bad_function.*strcpy-overlap.cpp:}}[[@LINE+2]]
-  // CHECK: {{#2 0x.* in main .*strcpy-overlap.cpp:}}[[@LINE+5]]
+  // DARWIN: {{#0 0x.* in .*strcpy.cold}}
+  // DARWIN: {{#1 0x.* in .*strcpy}}
+  // DARWIN: {{#2 0x.* in bad_function.*strcpy-overlap.cpp:}}[[@LINE+5]]
+  // DARWIN: {{#3 0x.* in main .*strcpy-overlap.cpp:}}[[@LINE+8]]
+  // NON_DARWIN: {{#0 0x.* in .*strcpy}}
+  // NON_DARWIN: {{#1 0x.* in bad_function.*strcpy-overlap.cpp:}}[[@LINE+2]]
+  // NON_DARWIN: {{#2 0x.* in main .*strcpy-overlap.cpp:}}[[@LINE+5]]
   strcpy(buffer, buffer + 1); // BOOM
 }
 
diff --git a/compiler-rt/test/asan/TestCases/strncpy-overlap.cpp b/compiler-rt/test/asan/TestCases/strncpy-overlap.cpp
index 9334a333c052a..5a530b2bca379 100644
--- a/compiler-rt/test/asan/TestCases/strncpy-overlap.cpp
+++ b/compiler-rt/test/asan/TestCases/strncpy-overlap.cpp
@@ -1,26 +1,26 @@
 // RUN: %clangxx_asan -O0 -fno-builtin %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: not %run %t 2>&1 | FileCheck %s %if system-darwin %{ --check-prefixes=CHECK,DARWIN %} %else %{ --check-prefixes=CHECK,NON_DARWIN %}
 // RUN: echo "interceptor_via_fun:bad_function" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 // RUN: echo "interceptor_name:strncpy" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 //
 // RUN: %clangxx_asan -O1 -fno-builtin %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: not %run %t 2>&1 | FileCheck %s %if system-darwin %{ --check-prefixes=CHECK,DARWIN %} %else %{ --check-prefixes=CHECK,NON_DARWIN %}
 // RUN: echo "interceptor_via_fun:bad_function" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 // RUN: echo "interceptor_name:strncpy" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 //
 // RUN: %clangxx_asan -O2 -fno-builtin %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: not %run %t 2>&1 | FileCheck %s %if system-darwin %{ --check-prefixes=CHECK,DARWIN %} %else %{ --check-prefixes=CHECK,NON_DARWIN %}
 // RUN: echo "interceptor_via_fun:bad_function" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 // RUN: echo "interceptor_name:strncpy" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 //
 // RUN: %clangxx_asan -O3 -fno-builtin %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: not %run %t 2>&1 | FileCheck %s %if system-darwin %{ --check-prefixes=CHECK,DARWIN %} %else %{ --check-prefixes=CHECK,NON_DARWIN %}
 // RUN: echo "interceptor_via_fun:bad_function" > %t.supp
 // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t
 // RUN: echo "interceptor_name:strncpy" > %t.supp
@@ -37,9 +37,13 @@ ATTRIBUTE_NOINLINE void bad_function() {
   char buffer[] = "hello";
   // CHECK: strncpy-param-overlap: memory ranges
   // CHECK: [{{0x.*,[ ]*0x.*}}) and [{{0x.*,[ ]*0x.*}}) overlap
-  // CHECK: {{#0 0x.* in .*strncpy}}
-  // CHECK: {{#1 0x.* in bad_function.*strncpy-overlap.cpp:}}[[@LINE+2]]
-  // CHECK: {{#2 0x.* in main .*strncpy-overlap.cpp:}}[[@LINE+5]]
+  // DARWIN: {{#0 0x.* in .*strncpy.cold}}
+  // DARWIN: {{#1 0x.* in .*strncpy}}
+  // DARWIN: {{#2 0x.* in bad_function.*strncpy-overlap.cpp:}}[[@LINE+5]]
+  // DARWIN: {{#3 0x.* in main .*strncpy-overlap.cpp:}}[[@LINE+8]]
+  // NON_DARWIN: {{#0 0x.* in .*strncpy}}
+  // NON_DARWIN: {{#1 0x.* in bad_function.*strncpy-overlap.cpp:}}[[@LINE+2]]
+  // NON_DARWIN: {{#2 0x.* in main .*strncpy-overlap.cpp:}}[[@LINE+5]]
   strncpy(buffer, buffer + 1, 5); // BOOM
 }
 
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cpp
index 37bfee4806173..baf1d89921658 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cpp
@@ -16,6 +16,13 @@
 
 // XFAIL: target={{.*netbsd.*}} && !asan
 
+// XFAIL: (darwin && ubsan && (arm64-target-arch || arm64e-target-arch))
+
+// Signal handlers not available on tvOS or watchOS
+// XFAIL: tvos || watchos
+
+// UNSUPPORTED: ios && !(tvos || watchos)
+
 volatile int *null = 0;
 
 namespace Xyz {



More information about the llvm-commits mailing list