diff --git a/src/librustc_mir/transform/add_validation.rs b/src/librustc_mir/transform/add_validation.rs index bbd2829c303..52c2eaa7cb6 100644 --- a/src/librustc_mir/transform/add_validation.rs +++ b/src/librustc_mir/transform/add_validation.rs @@ -248,18 +248,23 @@ fn run_pass<'a, 'tcx>(&self, match block_data.terminator { Some(Terminator { kind: TerminatorKind::Call { ref args, ref destination, .. }, source_info }) => { - // Before the call: Release all arguments + // Before the call: Release all arguments *and* the return value. + // The callee may write into the return value! Note that this relies + // on "release of uninitialized" to be a NOP. if !restricted_validation { let release_stmt = Statement { source_info, kind: StatementKind::Validate(ValidationOp::Release, - args.iter().filter_map(|op| { - match op { - &Operand::Consume(ref lval) => - Some(lval_to_operand(lval.clone())), - &Operand::Constant(..) => { None }, - } - }).collect()) + destination.iter().map(|dest| lval_to_operand(dest.0.clone())) + .chain( + args.iter().filter_map(|op| { + match op { + &Operand::Consume(ref lval) => + Some(lval_to_operand(lval.clone())), + &Operand::Constant(..) => { None }, + } + }) + ).collect()) }; block_data.statements.push(release_stmt); } diff --git a/src/test/mir-opt/validate_1.rs b/src/test/mir-opt/validate_1.rs index 542ba87fef4..9ac76a5f4ea 100644 --- a/src/test/mir-opt/validate_1.rs +++ b/src/test/mir-opt/validate_1.rs @@ -46,7 +46,7 @@ fn main() { // Validate(Suspend(ReScope(Misc(NodeId(34)))), [(*_6): i32/ReScope(Misc(NodeId(34)))]); // _5 = &ReErased mut (*_6); // Validate(Acquire, [(*_5): i32/ReScope(Misc(NodeId(34)))]); -// Validate(Release, [_3: &ReScope(Misc(NodeId(34))) Test, _5: &ReScope(Misc(NodeId(34))) mut i32]); +// Validate(Release, [_2: (), _3: &ReScope(Misc(NodeId(34))) Test, _5: &ReScope(Misc(NodeId(34))) mut i32]); // _2 = const Test::foo(_3, _5) -> bb1; // } // diff --git a/src/test/mir-opt/validate_3.rs b/src/test/mir-opt/validate_3.rs index 100fae5c678..9140cf5768f 100644 --- a/src/test/mir-opt/validate_3.rs +++ b/src/test/mir-opt/validate_3.rs @@ -38,7 +38,7 @@ fn _unused2(x: *const i32) -> i32 { unsafe { *x }} // Validate(Suspend(ReScope(Misc(NodeId(46)))), [(*_5): i32/ReScope(Misc(NodeId(46))) (imm)]); // _4 = &ReErased (*_5); // Validate(Acquire, [(*_4): i32/ReScope(Misc(NodeId(46))) (imm)]); -// Validate(Release, [_4: &ReScope(Misc(NodeId(46))) i32]); +// Validate(Release, [_3: (), _4: &ReScope(Misc(NodeId(46))) i32]); // _3 = const foo(_4) -> bb1; // } // bb1: { diff --git a/src/test/mir-opt/validate_5.rs b/src/test/mir-opt/validate_5.rs index 1831f9dd713..e9919af9fd3 100644 --- a/src/test/mir-opt/validate_5.rs +++ b/src/test/mir-opt/validate_5.rs @@ -37,7 +37,7 @@ fn main() { // fn test(_1: &ReErased mut i32) -> () { // bb0: { // Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(4) => validate_5/8cd878b::test[0] }, BrAnon(0)) mut i32]); -// Validate(Release, [_4: *mut i32]); +// Validate(Release, [_3: bool, _4: *mut i32]); // _3 = const write_42(_4) -> bb1; // } // }