rust/tests/codegen-llvm/sanitizer/sanitize-off.rs
Bastian Kersting 95bdb34494 Remove the no_sanitize attribute in favor of sanitize
This removes the #[no_sanitize] attribute, which was behind an unstable
feature named no_sanitize. Instead, we introduce the sanitize attribute
which is more powerful and allows to be extended in the future (instead
of just focusing on turning sanitizers off).

This also makes sanitize(kernel_address = ..) attribute work with
-Zsanitize=address

To do it the same as how clang disables address sanitizer, we now
disable ASAN on sanitize(kernel_address = "off") and KASAN on
sanitize(address = "off").

The same was added to clang in https://reviews.llvm.org/D44981.
2025-08-18 08:45:28 +00:00

139 lines
3.8 KiB
Rust

// Verifies that the `#[sanitize(address = "off")]` attribute can be used to
// selectively disable sanitizer instrumentation.
//
//@ needs-sanitizer-address
//@ compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static -Copt-level=0
#![crate_type = "lib"]
#![feature(sanitize)]
// CHECK: @UNSANITIZED = constant{{.*}} no_sanitize_address
// CHECK-NOT: @__asan_global_SANITIZED
#[no_mangle]
#[sanitize(address = "off")]
pub static UNSANITIZED: u32 = 0;
// CHECK: @__asan_global_SANITIZED
#[no_mangle]
pub static SANITIZED: u32 = 0;
// CHECK-LABEL: ; sanitize_off::unsanitized
// CHECK-NEXT: ; Function Attrs:
// CHECK-NOT: sanitize_address
// CHECK: start:
// CHECK-NOT: call void @__asan_report_load
// CHECK: }
#[sanitize(address = "off")]
pub fn unsanitized(b: &mut u8) -> u8 {
*b
}
// CHECK-LABEL: ; sanitize_off::sanitized
// CHECK-NEXT: ; Function Attrs:
// CHECK: sanitize_address
// CHECK: start:
// CHECK: call void @__asan_report_load
// CHECK: }
pub fn sanitized(b: &mut u8) -> u8 {
*b
}
#[sanitize(address = "off")]
pub mod foo {
// CHECK-LABEL: ; sanitize_off::foo::unsanitized
// CHECK-NEXT: ; Function Attrs:
// CHECK-NOT: sanitize_address
// CHECK: start:
// CHECK-NOT: call void @__asan_report_load
// CHECK: }
pub fn unsanitized(b: &mut u8) -> u8 {
*b
}
// CHECK-LABEL: ; sanitize_off::foo::sanitized
// CHECK-NEXT: ; Function Attrs:
// CHECK: sanitize_address
// CHECK: start:
// CHECK: call void @__asan_report_load
// CHECK: }
#[sanitize(address = "on")]
pub fn sanitized(b: &mut u8) -> u8 {
*b
}
}
pub trait MyTrait {
fn unsanitized(&self, b: &mut u8) -> u8;
fn sanitized(&self, b: &mut u8) -> u8;
// CHECK-LABEL: ; sanitize_off::MyTrait::unsanitized_default
// CHECK-NEXT: ; Function Attrs:
// CHECK-NOT: sanitize_address
// CHECK: start:
// CHECK-NOT: call void @__asan_report_load
// CHECK: }
#[sanitize(address = "off")]
fn unsanitized_default(&self, b: &mut u8) -> u8 {
*b
}
// CHECK-LABEL: ; sanitize_off::MyTrait::sanitized_default
// CHECK-NEXT: ; Function Attrs:
// CHECK: sanitize_address
// CHECK: start:
// CHECK: call void @__asan_report_load
// CHECK: }
fn sanitized_default(&self, b: &mut u8) -> u8 {
*b
}
}
#[sanitize(address = "off")]
impl MyTrait for () {
// CHECK-LABEL: ; <() as sanitize_off::MyTrait>::unsanitized
// CHECK-NEXT: ; Function Attrs:
// CHECK-NOT: sanitize_address
// CHECK: start:
// CHECK-NOT: call void @__asan_report_load
// CHECK: }
fn unsanitized(&self, b: &mut u8) -> u8 {
*b
}
// CHECK-LABEL: ; <() as sanitize_off::MyTrait>::sanitized
// CHECK-NEXT: ; Function Attrs:
// CHECK: sanitize_address
// CHECK: start:
// CHECK: call void @__asan_report_load
// CHECK: }
#[sanitize(address = "on")]
fn sanitized(&self, b: &mut u8) -> u8 {
*b
}
}
pub fn expose_trait(b: &mut u8) -> u8 {
<() as MyTrait>::unsanitized_default(&(), b);
<() as MyTrait>::sanitized_default(&(), b)
}
#[sanitize(address = "off")]
pub mod outer {
#[sanitize(thread = "off")]
pub mod inner {
// CHECK-LABEL: ; sanitize_off::outer::inner::unsanitized
// CHECK-NEXT: ; Function Attrs:
// CHECK-NOT: sanitize_address
// CHECK: start:
// CHECK-NOT: call void @__asan_report_load
// CHECK: }
pub fn unsanitized() {
let xs = [0, 1, 2, 3];
// Avoid optimizing everything out.
let xs = std::hint::black_box(xs.as_ptr());
let code = unsafe { *xs.offset(4) };
std::process::exit(code);
}
}
}