[compiler-rt] compiler-rt: ubsan: match suppressions against inlined frames (PR #206735)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 13 03:45:02 PDT 2026
https://github.com/maflcko updated https://github.com/llvm/llvm-project/pull/206735
>From fa327f99483c17338c4285f9367fe2e51b30a092 Mon Sep 17 00:00:00 2001
From: MarcoFalke <*~=`'#}+{/-|&$^_ at 721217.xyz>
Date: Tue, 30 Jun 2026 14:41:37 +0200
Subject: [PATCH 1/2] compiler-rt: ubsan: match suppressions against inlined
frames
When a function is inlined, it may not be possible to name it in a UBSan
suppressions file if only the top stack frame is checked.
Match function names against every inlined stack frame, while keeping file
names matched only against the top stack frame as before.
Also add a test for each case.
---
compiler-rt/lib/ubsan/ubsan_diag.cpp | 12 ++++++----
.../Inputs/suppressions-inline-origin-file.h | 1 +
.../Integer/suppressions-inline-origin-file.c | 22 +++++++++++++++++++
.../suppressions-nested-inline-function.c | 20 +++++++++++++++++
4 files changed, 51 insertions(+), 4 deletions(-)
create mode 100644 compiler-rt/test/ubsan/TestCases/Integer/Inputs/suppressions-inline-origin-file.h
create mode 100644 compiler-rt/test/ubsan/TestCases/Integer/suppressions-inline-origin-file.c
create mode 100644 compiler-rt/test/ubsan/TestCases/Integer/suppressions-nested-inline-function.c
diff --git a/compiler-rt/lib/ubsan/ubsan_diag.cpp b/compiler-rt/lib/ubsan/ubsan_diag.cpp
index 2146ed3c27287..543e358651d6d 100644
--- a/compiler-rt/lib/ubsan/ubsan_diag.cpp
+++ b/compiler-rt/lib/ubsan/ubsan_diag.cpp
@@ -429,6 +429,7 @@ bool __ubsan::IsVptrCheckSuppressed(const char *TypeName) {
bool __ubsan::IsPCSuppressed(ErrorType ET, uptr PC, const char *Filename) {
InitAsStandaloneIfNecessary();
CHECK(suppression_ctx);
+ PC = StackTrace::GetPreviousInstructionPc(PC);
const char *SuppType = ConvertTypeToFlagName(ET);
// Fast path: don't symbolize PC if there is no suppressions for given UB
// type.
@@ -443,11 +444,14 @@ bool __ubsan::IsPCSuppressed(ErrorType ET, uptr PC, const char *Filename) {
if (suppression_ctx->Match(Module, SuppType, &s))
return true;
}
- // Suppress by function or source file name from debug info.
+ // Suppress by function name from any inlined frame or by source file name
+ // from the top frame.
SymbolizedStackHolder Stack(Symbolizer::GetOrInit()->SymbolizePC(PC));
- const AddressInfo &AI = Stack.get()->info;
- return suppression_ctx->Match(AI.function, SuppType, &s) ||
- suppression_ctx->Match(AI.file, SuppType, &s);
+ for (const SymbolizedStack *Frame = Stack.get(); Frame; Frame = Frame->next) {
+ if (suppression_ctx->Match(Frame->info.function, SuppType, &s))
+ return true;
+ }
+ return suppression_ctx->Match(Stack.get()->info.file, SuppType, &s);
}
#endif // CAN_SANITIZE_UB
diff --git a/compiler-rt/test/ubsan/TestCases/Integer/Inputs/suppressions-inline-origin-file.h b/compiler-rt/test/ubsan/TestCases/Integer/Inputs/suppressions-inline-origin-file.h
new file mode 100644
index 0000000000000..4fed13ac4ce24
--- /dev/null
+++ b/compiler-rt/test/ubsan/TestCases/Integer/Inputs/suppressions-inline-origin-file.h
@@ -0,0 +1 @@
+__attribute__((always_inline)) static inline int fun(unsigned a) { return a; }
diff --git a/compiler-rt/test/ubsan/TestCases/Integer/suppressions-inline-origin-file.c b/compiler-rt/test/ubsan/TestCases/Integer/suppressions-inline-origin-file.c
new file mode 100644
index 0000000000000..b9dfa1cc0dbb7
--- /dev/null
+++ b/compiler-rt/test/ubsan/TestCases/Integer/suppressions-inline-origin-file.c
@@ -0,0 +1,22 @@
+// REQUIRES: can-symbolize
+// UNSUPPORTED: android
+
+// RUN: %clang -fsanitize=integer -O1 -g %s -o %t
+// RUN: echo "implicit-integer-sign-change:%s" > %t.main.supp
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1:report_error_type=1:suppressions='"%t.main.supp"' \
+// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-MAIN-FILE
+// RUN: echo "implicit-integer-sign-change:%p/Inputs/suppressions-inline-origin-file.h" > %t.header.supp
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1:report_error_type=1:suppressions='"%t.header.supp"' \
+// RUN: %run %t 2>&1 | FileCheck %s --allow-empty --check-prefix=CHECK-HEADER-FILE
+
+#include "Inputs/suppressions-inline-origin-file.h"
+
+int main(void) { (void)fun(4222111000U); }
+
+// Suppressing the caller file must not suppress a UB originating in the
+// inlined header.
+// CHECK-MAIN-FILE: runtime error: implicit conversion
+// CHECK-MAIN-FILE: {{.*}} in fun
+// CHECK-MAIN-FILE: {{.*}} in main
+
+// CHECK-HEADER-FILE-NOT: runtime error:
diff --git a/compiler-rt/test/ubsan/TestCases/Integer/suppressions-nested-inline-function.c b/compiler-rt/test/ubsan/TestCases/Integer/suppressions-nested-inline-function.c
new file mode 100644
index 0000000000000..e691b65c57a1f
--- /dev/null
+++ b/compiler-rt/test/ubsan/TestCases/Integer/suppressions-nested-inline-function.c
@@ -0,0 +1,20 @@
+// REQUIRES: can-symbolize
+// UNSUPPORTED: android
+
+// RUN: %clang -fsanitize=integer -O1 -g %s -o %t
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1:report_error_type=1 \
+// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOSUP
+// RUN: echo "implicit-integer-sign-change:mid" > %t.supp
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1:report_error_type=1:suppressions='"%t.supp"' \
+// RUN: %run %t 2>&1 | FileCheck %s --allow-empty --check-prefix=CHECK-SUP
+
+inline int leaf(unsigned a) { return a; }
+inline int mid(unsigned a) { return leaf(a); }
+
+int main(void) { (void)mid(4222111000U); }
+
+// CHECK-NOSUP: runtime error: implicit conversion
+// CHECK-NOSUP: {{.*}} in leaf
+// CHECK-NOSUP: {{.*}} in mid
+
+// CHECK-SUP-NOT: runtime error:
>From fe96012d76eb97b9ae0ee4c71652913f99b59cab Mon Sep 17 00:00:00 2001
From: MarcoFalke <*~=`'#}+{/-|&$^_ at 721217.xyz>
Date: Tue, 30 Jun 2026 16:15:09 +0200
Subject: [PATCH 2/2] test: Fixup tests, so that they pass under tsan and
clang-format
---
.../Integer/Inputs/suppressions-inline-origin-file.h | 2 +-
.../TestCases/Integer/suppressions-inline-origin-file.c | 6 +++---
.../TestCases/Integer/suppressions-nested-inline-function.c | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/compiler-rt/test/ubsan/TestCases/Integer/Inputs/suppressions-inline-origin-file.h b/compiler-rt/test/ubsan/TestCases/Integer/Inputs/suppressions-inline-origin-file.h
index 4fed13ac4ce24..8bb980a5a4d60 100644
--- a/compiler-rt/test/ubsan/TestCases/Integer/Inputs/suppressions-inline-origin-file.h
+++ b/compiler-rt/test/ubsan/TestCases/Integer/Inputs/suppressions-inline-origin-file.h
@@ -1 +1 @@
-__attribute__((always_inline)) static inline int fun(unsigned a) { return a; }
+inline int my_fun(unsigned a) { return a; }
diff --git a/compiler-rt/test/ubsan/TestCases/Integer/suppressions-inline-origin-file.c b/compiler-rt/test/ubsan/TestCases/Integer/suppressions-inline-origin-file.c
index b9dfa1cc0dbb7..09dbfa05612b1 100644
--- a/compiler-rt/test/ubsan/TestCases/Integer/suppressions-inline-origin-file.c
+++ b/compiler-rt/test/ubsan/TestCases/Integer/suppressions-inline-origin-file.c
@@ -11,12 +11,12 @@
#include "Inputs/suppressions-inline-origin-file.h"
-int main(void) { (void)fun(4222111000U); }
+int main(void) { (void)my_fun(4222111000U); }
// Suppressing the caller file must not suppress a UB originating in the
// inlined header.
// CHECK-MAIN-FILE: runtime error: implicit conversion
-// CHECK-MAIN-FILE: {{.*}} in fun
-// CHECK-MAIN-FILE: {{.*}} in main
+// CHECK-MAIN-FILE: {{.*}} my_fun
+// CHECK-MAIN-FILE: {{.*}} main
// CHECK-HEADER-FILE-NOT: runtime error:
diff --git a/compiler-rt/test/ubsan/TestCases/Integer/suppressions-nested-inline-function.c b/compiler-rt/test/ubsan/TestCases/Integer/suppressions-nested-inline-function.c
index e691b65c57a1f..e9c7e36a7ec78 100644
--- a/compiler-rt/test/ubsan/TestCases/Integer/suppressions-nested-inline-function.c
+++ b/compiler-rt/test/ubsan/TestCases/Integer/suppressions-nested-inline-function.c
@@ -14,7 +14,7 @@ inline int mid(unsigned a) { return leaf(a); }
int main(void) { (void)mid(4222111000U); }
// CHECK-NOSUP: runtime error: implicit conversion
-// CHECK-NOSUP: {{.*}} in leaf
-// CHECK-NOSUP: {{.*}} in mid
+// CHECK-NOSUP: {{.*}} leaf
+// CHECK-NOSUP: {{.*}} mid
// CHECK-SUP-NOT: runtime error:
More information about the llvm-commits
mailing list