about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/trans/expr.rs4
-rw-r--r--src/test/run-pass/out-pointer-aliasing.rs30
2 files changed, 32 insertions, 2 deletions
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index d638286a9c5..a7b9c137331 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -940,6 +940,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             controlflow::trans_loop(bcx, expr.id, &**body)
         }
         ast::ExprAssign(ref dst, ref src) => {
+            let src_datum = unpack_datum!(bcx, trans(bcx, &**src));
             let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &**dst, "assign"));
 
             if ty::type_needs_drop(bcx.tcx(), dst_datum.ty) {
@@ -960,7 +961,6 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 // We could avoid this intermediary with some analysis
                 // to determine whether `dst` may possibly own `src`.
                 debuginfo::set_source_location(bcx.fcx, expr.id, expr.span);
-                let src_datum = unpack_datum!(bcx, trans(bcx, &**src));
                 let src_datum = unpack_datum!(
                     bcx, src_datum.to_rvalue_datum(bcx, "ExprAssign"));
                 bcx = glue::drop_ty(bcx,
@@ -969,7 +969,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                     Some(NodeInfo { id: expr.id, span: expr.span }));
                 src_datum.store_to(bcx, dst_datum.val)
             } else {
-                trans_into(bcx, &**src, SaveIn(dst_datum.to_llref()))
+                src_datum.store_to(bcx, dst_datum.val)
             }
         }
         ast::ExprAssignOp(op, ref dst, ref src) => {
diff --git a/src/test/run-pass/out-pointer-aliasing.rs b/src/test/run-pass/out-pointer-aliasing.rs
new file mode 100644
index 00000000000..2a44df7a1b5
--- /dev/null
+++ b/src/test/run-pass/out-pointer-aliasing.rs
@@ -0,0 +1,30 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct Foo {
+    f1: int,
+    _f2: int,
+}
+
+#[inline(never)]
+pub fn foo(f: &mut Foo) -> Foo {
+    let ret = *f;
+    f.f1 = 0;
+    ret
+}
+
+pub fn main() {
+    let mut f = Foo {
+        f1: 8,
+        _f2: 9,
+    };
+    f = foo(&mut f);
+    assert_eq!(f.f1, 8);
+}