From 6f87f0b73595bed44d8586dbad417b2146e2c875 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 13 Oct 2017 14:30:14 -0700 Subject: [PATCH] Add a test for inheriting from template instantiations with vtables We didn't previously handle this case until the `HasVtableAnalysis` was updated to determine which items have explicit vtable pointers. --- ...from-template-instantiation-with-vtable.rs | 228 ++++++++++++++++++ ...rom-template-instantiation-with-vtable.hpp | 37 +++ 2 files changed, 265 insertions(+) create mode 100644 tests/expectations/tests/inherit-from-template-instantiation-with-vtable.rs create mode 100644 tests/headers/inherit-from-template-instantiation-with-vtable.hpp diff --git a/tests/expectations/tests/inherit-from-template-instantiation-with-vtable.rs b/tests/expectations/tests/inherit-from-template-instantiation-with-vtable.rs new file mode 100644 index 0000000000..365114ba86 --- /dev/null +++ b/tests/expectations/tests/inherit-from-template-instantiation-with-vtable.rs @@ -0,0 +1,228 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] + + +#[repr(C)] +pub struct BaseWithVtable__bindgen_vtable(::std::os::raw::c_void); +/// This should have an explicit vtable. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct BaseWithVtable { + pub vtable_: *const BaseWithVtable__bindgen_vtable, + pub t: T, + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, +} +impl Default for BaseWithVtable { + fn default() -> Self { + unsafe { ::std::mem::zeroed() } + } +} +/// This should not have an explicit vtable. +#[repr(C)] +#[derive(Debug, Copy)] +pub struct DerivedWithNoVirtualMethods { + pub _base: BaseWithVtable<*mut ::std::os::raw::c_char>, +} +#[test] +fn bindgen_test_layout_DerivedWithNoVirtualMethods() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(DerivedWithNoVirtualMethods)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(DerivedWithNoVirtualMethods)) + ); +} +impl Clone for DerivedWithNoVirtualMethods { + fn clone(&self) -> Self { + *self + } +} +impl Default for DerivedWithNoVirtualMethods { + fn default() -> Self { + unsafe { ::std::mem::zeroed() } + } +} +/// This should not have an explicit vtable. +#[repr(C)] +#[derive(Debug, Copy)] +pub struct DerivedWithVirtualMethods { + pub _base: BaseWithVtable<*mut ::std::os::raw::c_char>, +} +#[test] +fn bindgen_test_layout_DerivedWithVirtualMethods() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(DerivedWithVirtualMethods)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(DerivedWithVirtualMethods)) + ); +} +impl Clone for DerivedWithVirtualMethods { + fn clone(&self) -> Self { + *self + } +} +impl Default for DerivedWithVirtualMethods { + fn default() -> Self { + unsafe { ::std::mem::zeroed() } + } +} +/// This should not have any vtable. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct BaseWithoutVtable { + pub u: U, + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, +} +impl Default for BaseWithoutVtable { + fn default() -> Self { + unsafe { ::std::mem::zeroed() } + } +} +#[repr(C)] +pub struct DerivedWithVtable__bindgen_vtable(::std::os::raw::c_void); +/// This should have an explicit vtable. +#[repr(C)] +#[derive(Debug, Copy)] +pub struct DerivedWithVtable { + pub vtable_: *const DerivedWithVtable__bindgen_vtable, + pub _base: BaseWithoutVtable<*mut ::std::os::raw::c_char>, +} +#[test] +fn bindgen_test_layout_DerivedWithVtable() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(DerivedWithVtable)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(DerivedWithVtable)) + ); +} +impl Clone for DerivedWithVtable { + fn clone(&self) -> Self { + *self + } +} +impl Default for DerivedWithVtable { + fn default() -> Self { + unsafe { ::std::mem::zeroed() } + } +} +/// This should not have any vtable. +#[repr(C)] +#[derive(Debug, Copy)] +pub struct DerivedWithoutVtable { + pub _base: BaseWithoutVtable<*mut ::std::os::raw::c_char>, +} +#[test] +fn bindgen_test_layout_DerivedWithoutVtable() { + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(DerivedWithoutVtable)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(DerivedWithoutVtable)) + ); +} +impl Clone for DerivedWithoutVtable { + fn clone(&self) -> Self { + *self + } +} +impl Default for DerivedWithoutVtable { + fn default() -> Self { + unsafe { ::std::mem::zeroed() } + } +} +#[test] +fn __bindgen_test_layout_BaseWithVtable_open0_ptr_char_close0_instantiation() { + assert_eq!( + ::std::mem::size_of::>(), + 16usize, + concat!( + "Size of template specialization: ", + stringify!(BaseWithVtable<*mut ::std::os::raw::c_char>) + ) + ); + assert_eq!( + ::std::mem::align_of::>(), + 8usize, + concat!( + "Alignment of template specialization: ", + stringify!(BaseWithVtable<*mut ::std::os::raw::c_char>) + ) + ); +} +#[test] +fn __bindgen_test_layout_BaseWithVtable_open0_ptr_char_close0_instantiation_1() { + assert_eq!( + ::std::mem::size_of::>(), + 16usize, + concat!( + "Size of template specialization: ", + stringify!(BaseWithVtable<*mut ::std::os::raw::c_char>) + ) + ); + assert_eq!( + ::std::mem::align_of::>(), + 8usize, + concat!( + "Alignment of template specialization: ", + stringify!(BaseWithVtable<*mut ::std::os::raw::c_char>) + ) + ); +} +#[test] +fn __bindgen_test_layout_BaseWithoutVtable_open0_ptr_char_close0_instantiation() { + assert_eq!( + ::std::mem::size_of::>(), + 8usize, + concat!( + "Size of template specialization: ", + stringify!(BaseWithoutVtable<*mut ::std::os::raw::c_char>) + ) + ); + assert_eq!( + ::std::mem::align_of::>(), + 8usize, + concat!( + "Alignment of template specialization: ", + stringify!(BaseWithoutVtable<*mut ::std::os::raw::c_char>) + ) + ); +} +#[test] +fn __bindgen_test_layout_BaseWithoutVtable_open0_ptr_char_close0_instantiation_1() { + assert_eq!( + ::std::mem::size_of::>(), + 8usize, + concat!( + "Size of template specialization: ", + stringify!(BaseWithoutVtable<*mut ::std::os::raw::c_char>) + ) + ); + assert_eq!( + ::std::mem::align_of::>(), + 8usize, + concat!( + "Alignment of template specialization: ", + stringify!(BaseWithoutVtable<*mut ::std::os::raw::c_char>) + ) + ); +} diff --git a/tests/headers/inherit-from-template-instantiation-with-vtable.hpp b/tests/headers/inherit-from-template-instantiation-with-vtable.hpp new file mode 100644 index 0000000000..562ca0e1b2 --- /dev/null +++ b/tests/headers/inherit-from-template-instantiation-with-vtable.hpp @@ -0,0 +1,37 @@ +// bindgen-flags: -- -std=c++14 + +// Small test that we handle virtual tables correctly when deriving from a +// template instantiation. This wasn't previously handled at all. Note that when +// inheriting from a template parameter, the type that is instantiated might or +// might not have a virtual table, and we have no way of knowing. We don't +// handle that yet, so no test for it here. + +/// This should have an explicit vtable. +template +class BaseWithVtable { + T t; + + virtual void hello(); +}; + +/// This should not have an explicit vtable. +class DerivedWithNoVirtualMethods : public BaseWithVtable {}; + +/// This should not have an explicit vtable. +class DerivedWithVirtualMethods : public BaseWithVtable { + virtual void zoidberg(); +}; + +/// This should not have any vtable. +template +class BaseWithoutVtable { + U u; +}; + +/// This should have an explicit vtable. +class DerivedWithVtable : public BaseWithoutVtable { + virtual void leela(); +}; + +/// This should not have any vtable. +class DerivedWithoutVtable : public BaseWithoutVtable {};