Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable eager checks for memory sanitizer #99207

Merged
merged 2 commits into from
Sep 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use rustc_target::abi::call::ArgAbi;
pub use rustc_target::abi::call::*;
use rustc_target::abi::{self, HasDataLayout, Int};
pub use rustc_target::spec::abi::Abi;
use rustc_target::spec::SanitizerSet;

use libc::c_uint;
use smallvec::SmallVec;
Expand Down Expand Up @@ -90,6 +91,13 @@ fn get_attrs<'ll>(this: &ArgAttributes, cx: &CodegenCx<'ll, '_>) -> SmallVec<[&'
if regular.contains(ArgAttribute::NoAliasMutRef) && should_use_mutable_noalias(cx) {
attrs.push(llvm::AttributeKind::NoAlias.create_attr(cx.llcx));
}
} else if cx.tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) {
// If we're not optimising, *but* memory sanitizer is on, emit noundef, since it affects
// memory sanitizer's behavior.

if regular.contains(ArgAttribute::NoUndef) {
attrs.push(llvm::AttributeKind::NoUndef.create_attr(cx.llcx));
}
}

attrs
Expand Down
15 changes: 14 additions & 1 deletion compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,12 @@ extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool
const bool CompileKernel = false;

return wrap(createMemorySanitizerLegacyPassPass(
MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}));
#if LLVM_VERSION_GE(14, 0)
MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel, /*EagerChecks=*/true}
#else
MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}
#endif
));
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
Expand Down Expand Up @@ -931,10 +936,18 @@ LLVMRustOptimizeWithNewPassManager(

if (SanitizerOptions) {
if (SanitizerOptions->SanitizeMemory) {
#if LLVM_VERSION_GE(14, 0)
MemorySanitizerOptions Options(
SanitizerOptions->SanitizeMemoryTrackOrigins,
SanitizerOptions->SanitizeMemoryRecover,
/*CompileKernel=*/false,
/*EagerChecks=*/true);
#else
MemorySanitizerOptions Options(
SanitizerOptions->SanitizeMemoryTrackOrigins,
SanitizerOptions->SanitizeMemoryRecover,
/*CompileKernel=*/false);
#endif
OptimizerLastEPCallbacks.push_back(
[Options](ModulePassManager &MPM, OptimizationLevel Level) {
#if LLVM_VERSION_GE(14, 0)
Expand Down
38 changes: 38 additions & 0 deletions src/test/ui/sanitize/memory-eager.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// needs-sanitizer-support
// needs-sanitizer-memory
// min-llvm-version: 14.0.0
//
// revisions: unoptimized optimized
//
// [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
// [unoptimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins
//
// run-fail
// error-pattern: MemorySanitizer: use-of-uninitialized-value
// error-pattern: Uninitialized value was created by an allocation
// error-pattern: in the stack frame of function 'random'
//
// This test case intentionally limits the usage of the std,
// since it will be linked with an uninstrumented version of it.

#![feature(core_intrinsics)]
#![feature(start)]
#![feature(bench_black_box)]

use std::hint::black_box;
use std::mem::MaybeUninit;

#[inline(never)]
#[no_mangle]
#[allow(invalid_value)]
fn random() -> char {
let r = unsafe { MaybeUninit::uninit().assume_init() };
// Avoid optimizing everything out.
black_box(r)
}

#[start]
fn main(_: isize, _: *const *const u8) -> isize {
random();
0
}
11 changes: 7 additions & 4 deletions src/test/ui/sanitize/memory.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// needs-sanitizer-support
// needs-sanitizer-memory
//
// compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
// revisions: unoptimized optimized
//
// [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
// [unoptimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins
//
// run-fail
// error-pattern: MemorySanitizer: use-of-uninitialized-value
Expand All @@ -21,9 +24,9 @@ use std::mem::MaybeUninit;
#[inline(never)]
#[no_mangle]
fn random() -> [isize; 32] {
let r = unsafe { MaybeUninit::uninit().assume_init() };
let r = MaybeUninit::uninit();
// Avoid optimizing everything out.
black_box(r)
unsafe { std::intrinsics::volatile_load(r.as_ptr()) }
}

#[inline(never)]
Expand All @@ -38,6 +41,6 @@ fn xor(a: &[isize]) -> isize {

#[start]
fn main(_: isize, _: *const *const u8) -> isize {
let r = random();
let r = black_box(random as fn() -> [isize; 32])();
xor(&r)
}