Files
clang-p2996/clang/test/CodeGen/sanitize-coverage.c
Marco Elver 280333021e [SanitizeCoverage] Add support for NoSanitizeCoverage function attribute
We really ought to support no_sanitize("coverage") in line with other
sanitizers. This came up again in discussions on the Linux-kernel
mailing lists, because we currently do workarounds using objtool to
remove coverage instrumentation. Since that support is only on x86, to
continue support coverage instrumentation on other architectures, we
must support selectively disabling coverage instrumentation via function
attributes.

Unfortunately, for SanitizeCoverage, it has not been implemented as a
sanitizer via fsanitize= and associated options in Sanitizers.def, but
rolls its own option fsanitize-coverage. This meant that we never got
"automatic" no_sanitize attribute support.

Implement no_sanitize attribute support by special-casing the string
"coverage" in the NoSanitizeAttr implementation. To keep the feature as
unintrusive to existing IR generation as possible, define a new negative
function attribute NoSanitizeCoverage to propagate the information
through to the instrumentation pass.

Fixes: https://bugs.llvm.org/show_bug.cgi?id=49035

Reviewed By: vitalybuka, morehouse

Differential Revision: https://reviews.llvm.org/D102772
2021-05-25 12:57:14 +02:00

90 lines
3.9 KiB
C

// RUN: %clang %s -target x86_64-unknown-linux-gnu -emit-llvm -S -fsanitize-coverage=trace-pc,trace-cmp -o - | FileCheck %s --check-prefixes=CHECK
// RUN: %clang %s -target x86_64-unknown-linux-gnu -emit-llvm -S -fsanitize=address -fsanitize-coverage=trace-pc,trace-cmp -o - | FileCheck %s --check-prefixes=CHECK,ASAN
// RUN: %clang %s -target x86_64-unknown-linux-gnu -emit-llvm -S -fsanitize=bounds -fsanitize-coverage=trace-pc,trace-cmp -o - | FileCheck %s --check-prefixes=CHECK,BOUNDS
// RUN: %clang %s -target x86_64-unknown-linux-gnu -emit-llvm -S -fsanitize=memory -fsanitize-coverage=trace-pc,trace-cmp -o - | FileCheck %s --check-prefixes=CHECK,MSAN
// RUN: %clang %s -target x86_64-unknown-linux-gnu -emit-llvm -S -fsanitize=thread -fsanitize-coverage=trace-pc,trace-cmp -o - | FileCheck %s --check-prefixes=CHECK,TSAN
// RUN: %clang %s -target x86_64-unknown-linux-gnu -emit-llvm -S -fsanitize=undefined -fsanitize-coverage=trace-pc,trace-cmp -o - | FileCheck %s --check-prefixes=CHECK,UBSAN
int x[10];
// CHECK-LABEL: define dso_local void @foo(
void foo(int n) {
// CHECK-DAG: call void @__sanitizer_cov_trace_pc
// CHECK-DAG: call void @__sanitizer_cov_trace_const_cmp
// ASAN-DAG: call void @__asan_report_store
// MSAN-DAG: call void @__msan_warning
// BOUNDS-DAG: call void @__ubsan_handle_out_of_bounds
// TSAN-DAG: call void @__tsan_func_entry
// UBSAN-DAG: call void @__ubsan_handle
if (n)
x[n] = 42;
}
static inline __attribute__((__always_inline__)) void always_inlined_fn(int n) {
if (n)
x[n] = 42;
}
// CHECK-LABEL: define dso_local void @test_always_inline(
void test_always_inline(int n) {
// CHECK-DAG: call void @__sanitizer_cov_trace_pc
// CHECK-DAG: call void @__sanitizer_cov_trace_const_cmp
always_inlined_fn(n);
}
// CHECK-LABEL: define dso_local void @test_no_sanitize_coverage(
__attribute__((no_sanitize("coverage"))) void test_no_sanitize_coverage(int n) {
// CHECK-NOT: call void @__sanitizer_cov_trace_pc
// CHECK-NOT: call void @__sanitizer_cov_trace_const_cmp
// ASAN-DAG: call void @__asan_report_store
// MSAN-DAG: call void @__msan_warning
// BOUNDS-DAG: call void @__ubsan_handle_out_of_bounds
// TSAN-DAG: call void @__tsan_func_entry
// UBSAN-DAG: call void @__ubsan_handle
if (n)
x[n] = 42;
}
// CHECK-LABEL: define dso_local void @test_no_sanitize_combined(
__attribute__((no_sanitize("address", "memory", "thread", "bounds", "undefined", "coverage")))
void test_no_sanitize_combined(int n) {
// CHECK-NOT: call void @__sanitizer_cov_trace_pc
// CHECK-NOT: call void @__sanitizer_cov_trace_const_cmp
// ASAN-NOT: call void @__asan_report_store
// MSAN-NOT: call void @__msan_warning
// BOUNDS-NOT: call void @__ubsan_handle_out_of_bounds
// TSAN-NOT: call void @__tsan_func_entry
// UBSAN-NOT: call void @__ubsan_handle
if (n)
x[n] = 42;
}
// CHECK-LABEL: define dso_local void @test_no_sanitize_separate(
__attribute__((no_sanitize("address")))
__attribute__((no_sanitize("memory")))
__attribute__((no_sanitize("thread")))
__attribute__((no_sanitize("bounds")))
__attribute__((no_sanitize("undefined")))
__attribute__((no_sanitize("coverage")))
void test_no_sanitize_separate(int n) {
// CHECK-NOT: call void @__sanitizer_cov_trace_pc
// CHECK-NOT: call void @__sanitizer_cov_trace_const_cmp
// ASAN-NOT: call void @__asan_report_store
// MSAN-NOT: call void @__msan_warning
// BOUNDS-NOT: call void @__ubsan_handle_out_of_bounds
// TSAN-NOT: call void @__tsan_func_entry
// UBSAN-NOT: call void @__ubsan_handle
if (n)
x[n] = 42;
}
// CHECK-LABEL: define dso_local void @test_no_sanitize_always_inline(
__attribute__((no_sanitize("coverage")))
void test_no_sanitize_always_inline(int n) {
// CHECK-NOT: call void @__sanitizer_cov_trace_pc
// CHECK-NOT: call void @__sanitizer_cov_trace_const_cmp
always_inlined_fn(n);
}
// CHECK-LABEL: declare void