about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2017-08-01 21:06:33 -0700
committerRalf Jung <post@ralfj.de>2017-08-01 21:06:33 -0700
commit7d8dc7a979975ab6d8aab29cfa0b69e8a64f1280 (patch)
treeb04fcc597beb15357996b7a742fb70b59621330e
parent321a72c1c1329415c6b94cc18b42b05c1ce8b59d (diff)
downloadrust-7d8dc7a979975ab6d8aab29cfa0b69e8a64f1280.tar.gz
rust-7d8dc7a979975ab6d8aab29cfa0b69e8a64f1280.zip
also release-validate return value before a call
-rw-r--r--src/librustc_mir/transform/add_validation.rs21
-rw-r--r--src/test/mir-opt/validate_1.rs2
-rw-r--r--src/test/mir-opt/validate_3.rs2
-rw-r--r--src/test/mir-opt/validate_5.rs2
4 files changed, 16 insertions, 11 deletions
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 @@ impl MirPass for AddValidation {
             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 main() {
 //         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;
 //     }
 // }