]> git.lizzy.rs Git - rust.git/commitdiff
Thinify the fat pointer on virtual function calls
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Thu, 23 Mar 2017 17:32:57 +0000 (18:32 +0100)
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Thu, 23 Mar 2017 17:32:57 +0000 (18:32 +0100)
src/lvalue.rs
src/terminator/mod.rs
tests/run-pass/issue-3794.rs [new file with mode: 0644]

index 62855c0450579a16afe3b30bbbc0ce11751edb4b..b78824ea5c9e74892f4a285c7e99e26808f2d49d 100644 (file)
@@ -200,6 +200,12 @@ pub fn lvalue_field(
                 (Size::from_bytes(field * elem_size), false)
             }
 
+            FatPointer { .. } => {
+                let bytes = field_index as u64 * self.memory.pointer_size();
+                let offset = Size::from_bytes(bytes);
+                (offset, false)
+            }
+
             _ => bug!("field access on non-product type: {:?}", base_layout),
         };
 
index 060299983ed45284d443098537e79dc92b98cfa4..03804ccd0bd5137e920cd66dcc6f1a1f3f9a9f88 100644 (file)
@@ -337,11 +337,18 @@ fn eval_fn_call(
                 let (_, vtable) = self.eval_operand(&arg_operands[0])?.expect_ptr_vtable_pair(&self.memory)?;
                 let fn_ptr = self.memory.read_ptr(vtable.offset(ptr_size * (idx as u64 + 3)))?;
                 let instance = self.memory.get_fn(fn_ptr.alloc_id)?;
+                let mut arg_operands = arg_operands.to_vec();
+                let ty = self.operand_ty(&arg_operands[0]);
+                let ty = self.get_field_ty(ty, 0)?;
+                match arg_operands[0] {
+                    mir::Operand::Consume(ref mut lval) => *lval = lval.clone().field(mir::Field::new(0), ty),
+                    _ => bug!("virtual call first arg cannot be a constant"),
+                }
                 // recurse with concrete function
                 self.eval_fn_call(
                     instance,
                     destination,
-                    arg_operands,
+                    &arg_operands,
                     span,
                     sig,
                 )
diff --git a/tests/run-pass/issue-3794.rs b/tests/run-pass/issue-3794.rs
new file mode 100644 (file)
index 0000000..badb833
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2012 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.
+
+#![feature(box_syntax)]
+
+trait T {
+    fn print(&self);
+}
+
+#[derive(Debug)]
+struct S {
+    s: isize,
+}
+
+impl T for S {
+    fn print(&self) {
+        println!("{:?}", self);
+    }
+}
+
+fn print_t(t: &T) {
+    t.print();
+}
+
+fn print_s(s: &S) {
+    s.print();
+}
+
+pub fn main() {
+    let s: Box<S> = box S { s: 5 };
+    print_s(&*s);
+    let t: Box<T> = s as Box<T>;
+    print_t(&*t);
+}