]> git.lizzy.rs Git - rust.git/commitdiff
Fix soundness hole when unsizing boxes.
authorNiko Matsakis <niko@alum.mit.edu>
Mon, 16 Mar 2015 20:26:28 +0000 (16:26 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Tue, 17 Mar 2015 12:34:25 +0000 (08:34 -0400)
src/librustc/middle/expr_use_visitor.rs
src/test/compile-fail/borrowck-consume-unsize-vec.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-consume-upcast-box.rs [new file with mode: 0644]

index a1e38a1c8bda795d4c35e304cb35bc4bc406fc32..c0d51f5675ca2e7b15b28cf8f1f46fed5c7dd5c7 100644 (file)
@@ -857,28 +857,13 @@ fn walk_autoref(&mut self,
                     n: uint) {
         debug!("walk_autoref expr={}", expr.repr(self.tcx()));
 
-        // Match for unique trait coercions first, since we don't need the
-        // call to cat_expr_autoderefd.
-        match *autoref {
-            ty::AutoUnsizeUniq(ty::UnsizeVtable(..)) |
-            ty::AutoUnsize(ty::UnsizeVtable(..)) => {
-                assert!(n == 1, format!("Expected exactly 1 deref with Uniq \
-                                         AutoRefs, found: {}", n));
-                let cmt_unadjusted =
-                    return_if_err!(self.mc.cat_expr_unadjusted(expr));
-                self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
-                return;
-            }
-            _ => {}
-        }
-
-        let cmt_derefd = return_if_err!(
-            self.mc.cat_expr_autoderefd(expr, n));
-        debug!("walk_adjustment: cmt_derefd={}",
-               cmt_derefd.repr(self.tcx()));
-
         match *autoref {
             ty::AutoPtr(r, m, _) => {
+                let cmt_derefd = return_if_err!(
+                    self.mc.cat_expr_autoderefd(expr, n));
+                debug!("walk_adjustment: cmt_derefd={}",
+                       cmt_derefd.repr(self.tcx()));
+
                 self.delegate.borrow(expr.id,
                                      expr.span,
                                      cmt_derefd,
@@ -886,7 +871,16 @@ fn walk_autoref(&mut self,
                                      ty::BorrowKind::from_mutbl(m),
                                      AutoRef);
             }
-            ty::AutoUnsizeUniq(_) | ty::AutoUnsize(_) | ty::AutoUnsafe(..) => {}
+            ty::AutoUnsize(_) |
+            ty::AutoUnsizeUniq(_) => {
+                assert!(n == 1, format!("Expected exactly 1 deref with Uniq \
+                                         AutoRefs, found: {}", n));
+                let cmt_unadjusted =
+                    return_if_err!(self.mc.cat_expr_unadjusted(expr));
+                self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
+            }
+            ty::AutoUnsafe(..) => {
+            }
         }
     }
 
diff --git a/src/test/compile-fail/borrowck-consume-unsize-vec.rs b/src/test/compile-fail/borrowck-consume-unsize-vec.rs
new file mode 100644 (file)
index 0000000..32490e0
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2015 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.
+
+// Check that we report an error if an upcast box is moved twice.
+
+fn consume(_: Box<[i32]>) {
+}
+
+fn foo(b: Box<[i32;5]>) {
+    consume(b);
+    consume(b); //~ ERROR use of moved value
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/borrowck-consume-upcast-box.rs b/src/test/compile-fail/borrowck-consume-upcast-box.rs
new file mode 100644 (file)
index 0000000..5bcafa6
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2015 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.
+
+// Check that we report an error if an upcast box is moved twice.
+
+trait Foo { fn dummy(&self); }
+
+fn consume(_: Box<Foo>) {
+}
+
+fn foo(b: Box<Foo+Send>) {
+    consume(b);
+    consume(b); //~ ERROR use of moved value
+}
+
+fn main() {
+}