[clang] [compiler-rt] [llvm] [compiler-rt][UBSan] Add __ubsan_default_suppressions() hook (PR #194862)

Vitaly Buka via cfe-commits cfe-commits at lists.llvm.org
Sat May 2 14:07:12 PDT 2026


https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/194862

>From a95016a7c06b903c9c7393a721cd2c6e40b0d89f Mon Sep 17 00:00:00 2001
From: Kleis Auke Wolthuizen <github at kleisauke.nl>
Date: Wed, 29 Apr 2026 15:32:49 +0200
Subject: [PATCH 1/9] [compiler-rt][UBSan] Add __ubsan_default_suppressions()
 hook

In line with commit 5c62af5 and 83566da.
---
 compiler-rt/lib/ubsan/ubsan_diag.cpp                       | 7 +++++++
 compiler-rt/lib/ubsan/ubsan_interface.inc                  | 1 +
 compiler-rt/lib/ubsan/weak_symbols.txt                     | 1 +
 .../test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp | 7 +++++++
 llvm/utils/gn/secondary/compiler-rt/lib/asan/BUILD.gn      | 1 +
 llvm/utils/gn/secondary/compiler-rt/lib/ubsan/BUILD.gn     | 1 +
 6 files changed, 18 insertions(+)
 create mode 100644 compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp

diff --git a/compiler-rt/lib/ubsan/ubsan_diag.cpp b/compiler-rt/lib/ubsan/ubsan_diag.cpp
index 2146ed3c27287..6ec81736d4502 100644
--- a/compiler-rt/lib/ubsan/ubsan_diag.cpp
+++ b/compiler-rt/lib/ubsan/ubsan_diag.cpp
@@ -16,6 +16,7 @@
 #include "ubsan_init.h"
 #include "ubsan_flags.h"
 #include "ubsan_monitor.h"
+#include "sanitizer_common/sanitizer_internal_defs.h"
 #include "sanitizer_common/sanitizer_placement_new.h"
 #include "sanitizer_common/sanitizer_report_decorator.h"
 #include "sanitizer_common/sanitizer_stacktrace.h"
@@ -26,6 +27,11 @@
 
 using namespace __ubsan;
 
+// Can be overriden in frontend.
+SANITIZER_INTERFACE_WEAK_DEF(const char *, __ubsan_default_suppressions, void) {
+  return "";
+}
+
 // UBSan is combined with runtimes that already provide this functionality
 // (e.g., ASan) as well as runtimes that lack it (e.g., scudo). Tried to use
 // weak linkage to resolve this issue which is not portable and breaks on
@@ -417,6 +423,7 @@ void __ubsan::InitializeSuppressions() {
   suppression_ctx = new (suppression_placeholder)
       SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));
   suppression_ctx->ParseFromFile(flags()->suppressions);
+  suppression_ctx->Parse(__ubsan_default_suppressions());
 }
 
 bool __ubsan::IsVptrCheckSuppressed(const char *TypeName) {
diff --git a/compiler-rt/lib/ubsan/ubsan_interface.inc b/compiler-rt/lib/ubsan/ubsan_interface.inc
index 0eb109f37d445..7a9cb9b336f6e 100644
--- a/compiler-rt/lib/ubsan/ubsan_interface.inc
+++ b/compiler-rt/lib/ubsan/ubsan_interface.inc
@@ -59,5 +59,6 @@ INTERFACE_FUNCTION(__ubsan_handle_type_mismatch_v1_abort)
 INTERFACE_FUNCTION(__ubsan_handle_vla_bound_not_positive)
 INTERFACE_FUNCTION(__ubsan_handle_vla_bound_not_positive_abort)
 INTERFACE_WEAK_FUNCTION(__ubsan_default_options)
+INTERFACE_WEAK_FUNCTION(__ubsan_default_suppressions)
 INTERFACE_FUNCTION(__ubsan_on_report)
 INTERFACE_FUNCTION(__ubsan_get_current_report_data)
diff --git a/compiler-rt/lib/ubsan/weak_symbols.txt b/compiler-rt/lib/ubsan/weak_symbols.txt
index 69e1bc1857ed6..587a6aee18dff 100644
--- a/compiler-rt/lib/ubsan/weak_symbols.txt
+++ b/compiler-rt/lib/ubsan/weak_symbols.txt
@@ -1 +1,2 @@
 ___ubsan_default_options
+___ubsan_default_suppressions
diff --git a/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp b/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp
new file mode 100644
index 0000000000000..6936c56bb2256
--- /dev/null
+++ b/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp
@@ -0,0 +1,7 @@
+// Test that we use the suppressions from __ubsan_default_suppressions.
+// RUN: %clangxx -fsanitize=undefined %s -o %t && not %run %t 2>&1 | FileCheck %s
+extern "C" {
+  const char *__ubsan_default_suppressions() { return "FooBar"; }
+}
+// CHECK: UndefinedBehaviorSanitizer: failed to parse suppressions
+int main() {}
diff --git a/llvm/utils/gn/secondary/compiler-rt/lib/asan/BUILD.gn b/llvm/utils/gn/secondary/compiler-rt/lib/asan/BUILD.gn
index ab8ea1ffb56b0..290aa3f77a7d9 100644
--- a/llvm/utils/gn/secondary/compiler-rt/lib/asan/BUILD.gn
+++ b/llvm/utils/gn/secondary/compiler-rt/lib/asan/BUILD.gn
@@ -109,6 +109,7 @@ if (current_toolchain == host_toolchain) {
 
         # ubsan
         "-Wl,-U,___ubsan_default_options",
+        "-Wl,-U,___ubsan_default_suppressions",
 
         # sanitizer_common
         "-Wl,-U,___sanitizer_free_hook",
diff --git a/llvm/utils/gn/secondary/compiler-rt/lib/ubsan/BUILD.gn b/llvm/utils/gn/secondary/compiler-rt/lib/ubsan/BUILD.gn
index 541b86ad0970e..c6a511c3c714c 100644
--- a/llvm/utils/gn/secondary/compiler-rt/lib/ubsan/BUILD.gn
+++ b/llvm/utils/gn/secondary/compiler-rt/lib/ubsan/BUILD.gn
@@ -176,6 +176,7 @@ shared_library("ubsan_shared") {
 
       # ubsan
       "-Wl,-U,___ubsan_default_options",
+      "-Wl,-U,___ubsan_default_suppressions",
 
       # sanitizer_common
       "-Wl,-U,___sanitizer_free_hook",

>From b68cc81762ce5fd09d829442c544651124f7bb0b Mon Sep 17 00:00:00 2001
From: Kleis Auke Wolthuizen <github at kleisauke.nl>
Date: Wed, 29 Apr 2026 15:59:28 +0200
Subject: [PATCH 2/9] Fix CI

---
 .../test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp b/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp
index 6936c56bb2256..ffc42ab436664 100644
--- a/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp
+++ b/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp
@@ -3,5 +3,5 @@
 extern "C" {
   const char *__ubsan_default_suppressions() { return "FooBar"; }
 }
-// CHECK: UndefinedBehaviorSanitizer: failed to parse suppressions
+// CHECK: {{.*}}Sanitizer: failed to parse suppressions
 int main() {}

>From 3e466db912a085a63082ff164bffc746e65a2d16 Mon Sep 17 00:00:00 2001
From: Kleis Auke Wolthuizen <github at kleisauke.nl>
Date: Wed, 29 Apr 2026 16:15:49 +0200
Subject: [PATCH 3/9] Fix CI (2)

---
 .../ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp    | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp b/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp
index ffc42ab436664..fa565e332d922 100644
--- a/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp
+++ b/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp
@@ -1,7 +1,10 @@
 // Test that we use the suppressions from __ubsan_default_suppressions.
 // RUN: %clangxx -fsanitize=undefined %s -o %t && not %run %t 2>&1 | FileCheck %s
-extern "C" {
-  const char *__ubsan_default_suppressions() { return "FooBar"; }
-}
+
+// Temporarily unsupporting on TySan until suppressions are implemented
+// UNSUPPORTED: ubsan-tysan
+
+extern "C" const char *__ubsan_default_suppressions() { return "FooBar"; }
+
 // CHECK: {{.*}}Sanitizer: failed to parse suppressions
 int main() {}

>From a6aa80917443e9f613ca3ed0106a2457e8b82d2d Mon Sep 17 00:00:00 2001
From: Kleis Auke Wolthuizen <github at kleisauke.nl>
Date: Sat, 2 May 2026 10:57:25 +0200
Subject: [PATCH 4/9] Appease clang-format

---
 compiler-rt/lib/ubsan/ubsan_diag.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/compiler-rt/lib/ubsan/ubsan_diag.cpp b/compiler-rt/lib/ubsan/ubsan_diag.cpp
index 6ec81736d4502..6efd082a89934 100644
--- a/compiler-rt/lib/ubsan/ubsan_diag.cpp
+++ b/compiler-rt/lib/ubsan/ubsan_diag.cpp
@@ -13,9 +13,10 @@
 #include "ubsan_platform.h"
 #if CAN_SANITIZE_UB
 #include "ubsan_diag.h"
-#include "ubsan_init.h"
 #include "ubsan_flags.h"
+#include "ubsan_init.h"
 #include "ubsan_monitor.h"
+
 #include "sanitizer_common/sanitizer_internal_defs.h"
 #include "sanitizer_common/sanitizer_placement_new.h"
 #include "sanitizer_common/sanitizer_report_decorator.h"
@@ -23,6 +24,7 @@
 #include "sanitizer_common/sanitizer_stacktrace_printer.h"
 #include "sanitizer_common/sanitizer_suppressions.h"
 #include "sanitizer_common/sanitizer_symbolizer.h"
+
 #include <stdio.h>
 
 using namespace __ubsan;

>From b982112a8d0b963cc7bfa23006934f43eb2eb6e8 Mon Sep 17 00:00:00 2001
From: Kleis Auke Wolthuizen <github at kleisauke.nl>
Date: Sat, 2 May 2026 13:23:22 +0200
Subject: [PATCH 5/9] Revise test

---
 .../Misc/Posix/ubsan_suppressions.cpp         | 25 ++++++++++++++-----
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp b/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp
index fa565e332d922..583077bf2cf46 100644
--- a/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp
+++ b/compiler-rt/test/ubsan/TestCases/Misc/Posix/ubsan_suppressions.cpp
@@ -1,10 +1,23 @@
 // Test that we use the suppressions from __ubsan_default_suppressions.
-// RUN: %clangxx -fsanitize=undefined %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx -fsanitize=integer -fsanitize-recover=integer -g0 %s -o %t
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t
 
-// Temporarily unsupporting on TySan until suppressions are implemented
-// UNSUPPORTED: ubsan-tysan
+// Suppression by symbol name requires the compiler-rt runtime to be able to
+// symbolize stack addresses.
+// REQUIRES: can-symbolize
+// UNSUPPORTED: android
 
-extern "C" const char *__ubsan_default_suppressions() { return "FooBar"; }
+#include <stdint.h>
 
-// CHECK: {{.*}}Sanitizer: failed to parse suppressions
-int main() {}
+extern "C" const char *__ubsan_default_suppressions() {
+  return "unsigned-integer-overflow:do_overflow";
+}
+
+extern "C" void do_overflow() {
+  (void)(uint64_t(10000000000000000000ull) + uint64_t(9000000000000000000ull));
+}
+
+int main() {
+  do_overflow();
+  return 0;
+}

>From 4cbfbcabee80f3203829e6b43ad78c9cc5130798 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Sat, 2 May 2026 14:01:56 -0700
Subject: [PATCH 6/9] docs

---
 clang/docs/UndefinedBehaviorSanitizer.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/clang/docs/UndefinedBehaviorSanitizer.rst b/clang/docs/UndefinedBehaviorSanitizer.rst
index bb0dc00609688..3ff1a77e33a6c 100644
--- a/clang/docs/UndefinedBehaviorSanitizer.rst
+++ b/clang/docs/UndefinedBehaviorSanitizer.rst
@@ -448,6 +448,16 @@ suppression file in a ``UBSAN_OPTIONS`` environment variable.
 
     UBSAN_OPTIONS=suppressions=MyUBSan.supp
 
+Alternatively, you can provide default suppressions by defining a
+``__ubsan_default_suppressions`` function:
+
+.. code-block:: c++
+
+    extern "C" const char *__ubsan_default_suppressions() {
+      return "signed-integer-overflow:file-with-known-overflow.cpp\n"
+             "alignment:function_doing_unaligned_access\n";
+    }
+
 You need to specify a :ref:`check <ubsan-checks>` you are suppressing and the
 bug location. For example:
 

>From 60cde262650716de5596bb9c93af3fad3b375abf Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Sat, 2 May 2026 14:02:33 -0700
Subject: [PATCH 7/9] include

---
 compiler-rt/include/sanitizer/ubsan_interface.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/compiler-rt/include/sanitizer/ubsan_interface.h b/compiler-rt/include/sanitizer/ubsan_interface.h
index b53d6013c71cd..a6cad89bfcedc 100644
--- a/compiler-rt/include/sanitizer/ubsan_interface.h
+++ b/compiler-rt/include/sanitizer/ubsan_interface.h
@@ -27,6 +27,14 @@ extern "C" {
 /// \returns Default options string.
 const char *SANITIZER_CDECL __ubsan_default_options(void);
 
+/// User-provided default suppressions.
+///
+/// You can provide your own implementation of this function to return a string
+/// containing UBSan suppressions.
+///
+/// \returns Default suppressions string.
+const char *SANITIZER_CDECL __ubsan_default_suppressions(void);
+
 /// Set up an interval timer and install a SIGPROF signal handler that crashes
 /// the program if it is stuck in a trap loop generated by -fsanitize-trap-loop.
 ///

>From 2275d2636f90fda94ce786b357b992ca1120ea87 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Sat, 2 May 2026 14:02:45 -0700
Subject: [PATCH 8/9] internal include

---
 compiler-rt/lib/ubsan/ubsan_flags.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/compiler-rt/lib/ubsan/ubsan_flags.h b/compiler-rt/lib/ubsan/ubsan_flags.h
index c47009bafe539..76615123cd735 100644
--- a/compiler-rt/lib/ubsan/ubsan_flags.h
+++ b/compiler-rt/lib/ubsan/ubsan_flags.h
@@ -41,6 +41,10 @@ extern "C" {
 // override the default flag values.
 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
 const char *__ubsan_default_options();
+// Users may provide their own implementation of __ubsan_default_suppressions to
+// override the default suppression values.
+SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+const char *__ubsan_default_suppressions();
 }  // extern "C"
 
 #endif  // UBSAN_FLAGS_H

>From 062734892387ead74fb30063a961aa49f6071712 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Sat, 2 May 2026 14:06:35 -0700
Subject: [PATCH 9/9] release notes

---
 clang/docs/ReleaseNotes.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index fdafc4871ed1b..1864fe363e508 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -746,6 +746,7 @@ Static Analyzer
 
 Sanitizers
 ----------
+- UndefinedBehaviorSanitizer now supports ``__ubsan_default_suppressions``.
 
 Python Binding Changes
 ----------------------



More information about the cfe-commits mailing list