diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index 13a18269585..bce307d368c 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs @@ -117,8 +117,10 @@ fn visit_local(&mut self, local: Local, ctxt: PlaceContext, loc: Location) { self.assignments[local].insert(LocationExtended::Plain(loc)); self.assignment_order.push(local); } - PlaceContext::MutatingUse(_) => self.assignments[local] = Set1::Many, - // Immutable borrows and AddressOf are taken into account in `SsaLocals::new` by + // Anything can happen with raw pointers, so remove them. + PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) + | PlaceContext::MutatingUse(_) => self.assignments[local] = Set1::Many, + // Immutable borrows are taken into account in `SsaLocals::new` by // removing non-freeze locals. PlaceContext::NonMutatingUse(_) => { let set = &mut self.assignments[local]; diff --git a/tests/mir-opt/copy-prop/mutate_through_pointer.f.CopyProp.diff b/tests/mir-opt/copy-prop/mutate_through_pointer.f.CopyProp.diff new file mode 100644 index 00000000000..61fdd6f8c05 --- /dev/null +++ b/tests/mir-opt/copy-prop/mutate_through_pointer.f.CopyProp.diff @@ -0,0 +1,19 @@ +- // MIR for `f` before CopyProp ++ // MIR for `f` after CopyProp + + fn f(_1: bool) -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/mutate_through_pointer.rs:+0:18: +0:22 + let mut _2: bool; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: *const bool; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _4: *mut bool; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _2 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _3 = &raw const _2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _4 = &raw mut (*_3); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + (*_4) = const false; // scope 0 at $DIR/mutate_through_pointer.rs:+5:9: +5:20 + _0 = _1; // scope 0 at $DIR/mutate_through_pointer.rs:+6:9: +6:16 + return; // scope 0 at $DIR/mutate_through_pointer.rs:+7:9: +7:17 + } + } + diff --git a/tests/mir-opt/copy-prop/mutate_through_pointer.rs b/tests/mir-opt/copy-prop/mutate_through_pointer.rs new file mode 100644 index 00000000000..609e49d6bc9 --- /dev/null +++ b/tests/mir-opt/copy-prop/mutate_through_pointer.rs @@ -0,0 +1,22 @@ +#![feature(custom_mir, core_intrinsics)] +#![allow(unused_assignments)] +extern crate core; +use core::intrinsics::mir::*; + +#[custom_mir(dialect = "analysis", phase = "post-cleanup")] +fn f(c: bool) -> bool { + mir!({ + let a = c; + let p = core::ptr::addr_of!(a); + let p2 = core::ptr::addr_of_mut!(*p); + *p2 = false; + RET = c; + Return() + }) +} + +fn main() { + assert_eq!(true, f(true)); +} + +// EMIT_MIR mutate_through_pointer.f.CopyProp.diff