summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Fitzgerald <fitzgen@gmail.com>2017-03-09 13:53:20 -0800
committerNick Fitzgerald <fitzgen@gmail.com>2017-03-09 13:56:53 -0800
commitb662443c1bf0c6c0103b91aec30e6b95ea5c4ff4 (patch)
treebdfbbbf4bec63ade4956837fbf09ed01a5667374
parent72ab471539fcf2809f82e2dd980c59352a67eba4 (diff)
Generate better opaque blobs in the face of non-type parameters
When instantiating templates whose definitions have non-type generic parameters, prefer the layout of the instantiation type to the garbage we get from the definition's layout. In general, an instantiation's layout will always be a better choice than the definition's layout, regardless of non-type parameters. Fixes #569
-rw-r--r--src/codegen/mod.rs16
-rw-r--r--tests/expectations/tests/issue-569-non-type-template-params-causing-layout-test-failures.rs42
-rw-r--r--tests/expectations/tests/non-type-params.rs48
-rw-r--r--tests/expectations/tests/opaque_pointer.rs2
-rw-r--r--tests/expectations/tests/type_alias_empty.rs2
-rw-r--r--tests/headers/issue-569-non-type-template-params-causing-layout-test-failures.hpp27
-rw-r--r--tests/headers/non-type-params.hpp17
7 files changed, 148 insertions, 6 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 49b320ae..fe93783f 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -561,7 +561,13 @@ impl CodeGenerator for Type {
let layout = self.layout(ctx).unwrap_or_else(Layout::zero);
BlobTyBuilder::new(layout).build()
} else {
- inner_item.to_rust_ty(ctx)
+ let inner_rust_ty = inner_item.to_rust_ty(ctx);
+ if inner_rust_ty == aster::AstBuilder::new().ty().unit() {
+ let layout = self.layout(ctx).unwrap_or_else(|| Layout::for_size(1));
+ BlobTyBuilder::new(layout).build()
+ } else {
+ inner_rust_ty
+ }
};
{
@@ -2356,12 +2362,14 @@ impl ToRustTy for TemplateInstantiation {
let decl = self.template_definition();
let mut ty = decl.to_rust_ty(ctx).unwrap();
- // If we gave up when making a type for the template definition,
- // check if maybe we can make a better opaque blob for the
- // instantiation.
if ty == aster::AstBuilder::new().ty().unit().unwrap() {
+ // If we gave up when making a type for the template definition,
+ // check if maybe we can make a better opaque blob for the
+ // instantiation. If not, at least don't use a zero-sized type.
if let Some(layout) = self_ty.layout(ctx) {
return BlobTyBuilder::new(layout).build();
+ } else {
+ return quote_ty!(ctx.ext_cx(), u8);
}
}
diff --git a/tests/expectations/tests/issue-569-non-type-template-params-causing-layout-test-failures.rs b/tests/expectations/tests/issue-569-non-type-template-params-causing-layout-test-failures.rs
new file mode 100644
index 00000000..6cf2ba16
--- /dev/null
+++ b/tests/expectations/tests/issue-569-non-type-template-params-causing-layout-test-failures.rs
@@ -0,0 +1,42 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+pub const ENUM_VARIANT_1: _bindgen_ty_1 = _bindgen_ty_1::ENUM_VARIANT_1;
+pub const ENUM_VARIANT_2: _bindgen_ty_1 = _bindgen_ty_1::ENUM_VARIANT_2;
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum _bindgen_ty_1 { ENUM_VARIANT_1 = 0, ENUM_VARIANT_2 = 1, }
+pub type JS_Alias = u8;
+#[repr(C)]
+pub struct JS_Base {
+ pub f: JS_Alias,
+}
+impl Default for JS_Base {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
+#[repr(C)]
+pub struct JS_AutoIdVector {
+ pub _base: JS_Base,
+}
+#[test]
+fn bindgen_test_layout_JS_AutoIdVector() {
+ assert_eq!(::std::mem::size_of::<JS_AutoIdVector>() , 1usize , concat ! (
+ "Size of: " , stringify ! ( JS_AutoIdVector ) ));
+ assert_eq! (::std::mem::align_of::<JS_AutoIdVector>() , 1usize , concat !
+ ( "Alignment of " , stringify ! ( JS_AutoIdVector ) ));
+}
+impl Default for JS_AutoIdVector {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
+#[test]
+fn __bindgen_test_layout_JS_Base_instantiation_16() {
+ assert_eq!(::std::mem::size_of::<JS_Base>() , 1usize , concat ! (
+ "Size of template specialization: " , stringify ! ( JS_Base )
+ ));
+ assert_eq!(::std::mem::align_of::<JS_Base>() , 1usize , concat ! (
+ "Alignment of template specialization: " , stringify ! (
+ JS_Base ) ));
+}
diff --git a/tests/expectations/tests/non-type-params.rs b/tests/expectations/tests/non-type-params.rs
new file mode 100644
index 00000000..039aa711
--- /dev/null
+++ b/tests/expectations/tests/non-type-params.rs
@@ -0,0 +1,48 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+pub type Array16 = u8;
+pub type ArrayInt4 = [u32; 4usize];
+#[repr(C)]
+pub struct UsesArray {
+ pub array_char_16: [u8; 16usize],
+ pub array_bool_8: [u8; 8usize],
+ pub array_int_4: ArrayInt4,
+}
+#[test]
+fn bindgen_test_layout_UsesArray() {
+ assert_eq!(::std::mem::size_of::<UsesArray>() , 40usize , concat ! (
+ "Size of: " , stringify ! ( UsesArray ) ));
+ assert_eq! (::std::mem::align_of::<UsesArray>() , 4usize , concat ! (
+ "Alignment of " , stringify ! ( UsesArray ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const UsesArray ) ) . array_char_16 as * const
+ _ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( UsesArray ) , "::" ,
+ stringify ! ( array_char_16 ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const UsesArray ) ) . array_bool_8 as * const _
+ as usize } , 16usize , concat ! (
+ "Alignment of field: " , stringify ! ( UsesArray ) , "::" ,
+ stringify ! ( array_bool_8 ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const UsesArray ) ) . array_int_4 as * const _
+ as usize } , 24usize , concat ! (
+ "Alignment of field: " , stringify ! ( UsesArray ) , "::" ,
+ stringify ! ( array_int_4 ) ));
+}
+impl Default for UsesArray {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
+#[test]
+fn __bindgen_test_layout_Array_instantiation_18() {
+ assert_eq!(::std::mem::size_of::<[u32; 4usize]>() , 16usize , concat ! (
+ "Size of template specialization: " , stringify ! (
+ [u32; 4usize] ) ));
+ assert_eq!(::std::mem::align_of::<[u32; 4usize]>() , 4usize , concat ! (
+ "Alignment of template specialization: " , stringify ! (
+ [u32; 4usize] ) ));
+}
diff --git a/tests/expectations/tests/opaque_pointer.rs b/tests/expectations/tests/opaque_pointer.rs
index 2e1890a8..1a2da431 100644
--- a/tests/expectations/tests/opaque_pointer.rs
+++ b/tests/expectations/tests/opaque_pointer.rs
@@ -35,7 +35,7 @@ impl Default for Opaque {
#[repr(C)]
#[derive(Debug, Copy)]
pub struct WithOpaquePtr {
- pub whatever: *mut (),
+ pub whatever: *mut u8,
pub other: u32,
pub t: OtherOpaque,
}
diff --git a/tests/expectations/tests/type_alias_empty.rs b/tests/expectations/tests/type_alias_empty.rs
index 47e36006..c455b8ae 100644
--- a/tests/expectations/tests/type_alias_empty.rs
+++ b/tests/expectations/tests/type_alias_empty.rs
@@ -4,4 +4,4 @@
#![allow(non_snake_case)]
-pub type bool_constant = ();
+pub type bool_constant = u8;
diff --git a/tests/headers/issue-569-non-type-template-params-causing-layout-test-failures.hpp b/tests/headers/issue-569-non-type-template-params-causing-layout-test-failures.hpp
new file mode 100644
index 00000000..7f8c2d8a
--- /dev/null
+++ b/tests/headers/issue-569-non-type-template-params-causing-layout-test-failures.hpp
@@ -0,0 +1,27 @@
+// bindgen-flags: -- -std=c++14
+
+// Generated by C-Reduce, cleaned up and given names for readability.
+
+template <int, typename>
+struct HasNonTypeTemplateParam {
+ // But doesn't use the non-type template param nor its type param...
+};
+
+enum {
+ ENUM_VARIANT_1,
+ ENUM_VARIANT_2
+};
+
+namespace JS {
+
+template <typename T>
+using Alias = HasNonTypeTemplateParam<ENUM_VARIANT_1, T>;
+
+template <typename U>
+class Base {
+ Alias<U> f;
+};
+
+class AutoIdVector : Base<int> {};
+
+}
diff --git a/tests/headers/non-type-params.hpp b/tests/headers/non-type-params.hpp
new file mode 100644
index 00000000..3e2ccf8e
--- /dev/null
+++ b/tests/headers/non-type-params.hpp
@@ -0,0 +1,17 @@
+// bindgen-flags: -- -std=c++14
+
+template <typename T, unsigned int Capacity>
+struct Array {
+ T elements[Capacity];
+};
+
+template <typename T>
+using Array16 = Array<T, 16>;
+
+using ArrayInt4 = Array<int, 4>;
+
+struct UsesArray {
+ Array16<char> array_char_16;
+ Array<bool, 8> array_bool_8;
+ ArrayInt4 array_int_4;
+};