[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