diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 357b0b6c4515..c59b81eb4cc3 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -7,7 +7,7 @@ use crate::type_of::LayoutLlvmExt; use crate::value::Value; use libc::{c_char, c_uint}; use log::debug; -use rustc::session::config; +use rustc::session::config::{self, Sanitizer}; use rustc::ty::layout::{self, Align, Size, TyLayout}; use rustc::ty::{self, Ty, TyCtxt}; use rustc_codegen_ssa::base::to_immediate; @@ -1232,12 +1232,19 @@ impl Builder<'a, 'll, 'tcx> { } fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) { - if self.cx.sess().opts.optimize == config::OptLevel::No { + let size = size.bytes(); + if size == 0 { return; } - let size = size.bytes(); - if size == 0 { + let opts = &self.cx.sess().opts; + let emit = match opts.debugging_opts.sanitizer { + // Some sanitizer use lifetime intrinsics. When they are in use, + // emit lifetime intrinsics regardless of optimization level. + Some(Sanitizer::Address) | Some(Sanitizer::Memory) => true, + _ => opts.optimize != config::OptLevel::No, + }; + if !emit { return; } diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index eaa845a279fe..fad703698075 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -87,8 +87,9 @@ extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) { extern "C" LLVMPassRef LLVMRustCreateAddressSanitizerFunctionPass(bool Recover) { const bool CompileKernel = false; + const bool UseAfterScope = true; - return wrap(createAddressSanitizerFunctionPass(CompileKernel, Recover)); + return wrap(createAddressSanitizerFunctionPass(CompileKernel, Recover, UseAfterScope)); } extern "C" LLVMPassRef LLVMRustCreateModuleAddressSanitizerPass(bool Recover) { diff --git a/src/test/ui/sanitizer-use-after-scope.rs b/src/test/ui/sanitizer-use-after-scope.rs new file mode 100644 index 000000000000..6a2067e157af --- /dev/null +++ b/src/test/ui/sanitizer-use-after-scope.rs @@ -0,0 +1,18 @@ +// needs-sanitizer-support +// only-x86_64 +// +// compile-flags: -Zsanitizer=address +// run-fail +// error-pattern: ERROR: AddressSanitizer: stack-use-after-scope + +static mut P: *mut usize = std::ptr::null_mut(); + +fn main() { + unsafe { + { + let mut x = 0; + P = &mut x; + } + std::ptr::write_volatile(P, 123); + } +}