diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-04-10 13:10:22 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-10 13:10:22 -0500 |
commit | a22ddba19a16cd1abb59c2cce73cabb459ff9b46 (patch) | |
tree | e51fc04c8acccca2e52a558d128eff5c06e7fbff /tests | |
parent | 26eeb6db16a0c91f753063a720f4dde5be4ca565 (diff) | |
parent | c8a206adad0fc333b5f9aba410b7f4cccae77a22 (diff) |
Auto merge of #623 - fitzgen:issue-584-stylo-blacklisting-in-template-analysis, r=emilio
Correctly handle blacklisted items in the template analysis
The template analysis operates on whitelisted items, and uses our tracing
infrastructure to move between them. Usually, that means we can only reach other
whitelisted items by tracing, because the set of whitelisted items is the
transitive closure of all the items explicitly whitelisted. The exception is
when some type is explicitly blacklisted. It could still be reachable via
tracing from a whitelisted item, but is not considered whitelisted due to the
blacklisting.
The easy fix is to run the template analysis on the whole IR graph rather than
just the whitelisted set. This is an approximately one line change in the
analysis, however is not desirable due to performance concerns. The whole point
of whitelisting is that there may be *many* types in a header, but only a *few*
the user cares about, or there might be types that aren't explicitly needed and
that are too complicated for bindgen to handle generally (often in
`<type_traits>`). In these situations, we don't want to waste cycles or even
confuse ourselves by considering such types!
Instead, we keep the whitelisted item set around and check by hand whether any
given item is in it during the template type parameter analysis.
Additionally, we make the decision that blacklisted template definitions use all
of their type parameters. This seems like a reasonable choice because the type
will likely be ported to Rust manually by the bindgen user, and they will be
looking at the C++ definition with all of its type parameters. They can always
insert `PhantomData`s manually, so it also gives the most flexibility.
Fixes #584
r? @emilio
Diffstat (limited to 'tests')
-rw-r--r-- | tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs | 80 | ||||
-rw-r--r-- | tests/headers/issue-584-stylo-template-analysis-panic.hpp | 13 |
2 files changed, 93 insertions, 0 deletions
diff --git a/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs b/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs new file mode 100644 index 00000000..91b8e49a --- /dev/null +++ b/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs @@ -0,0 +1,80 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + +pub type RefPtr<T> = T; + +#[repr(C)] +#[derive(Debug, Copy)] +pub struct b { + pub _base: g, +} +#[test] +fn bindgen_test_layout_b() { + assert_eq!(::std::mem::size_of::<b>() , 1usize , concat ! ( + "Size of: " , stringify ! ( b ) )); + assert_eq! (::std::mem::align_of::<b>() , 1usize , concat ! ( + "Alignment of " , stringify ! ( b ) )); +} +impl Clone for b { + fn clone(&self) -> Self { *self } +} +impl Default for b { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct A { + pub _address: u8, +} +pub type A_a = b; +#[test] +fn bindgen_test_layout_A() { + assert_eq!(::std::mem::size_of::<A>() , 1usize , concat ! ( + "Size of: " , stringify ! ( A ) )); + assert_eq! (::std::mem::align_of::<A>() , 1usize , concat ! ( + "Alignment of " , stringify ! ( A ) )); +} +impl Clone for A { + fn clone(&self) -> Self { *self } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct e<c> { + pub d: RefPtr<c>, +} +impl <c> Default for e<c> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct f { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Copy)] +pub struct g { + pub h: f, +} +#[test] +fn bindgen_test_layout_g() { + assert_eq!(::std::mem::size_of::<g>() , 1usize , concat ! ( + "Size of: " , stringify ! ( g ) )); + assert_eq! (::std::mem::align_of::<g>() , 1usize , concat ! ( + "Alignment of " , stringify ! ( g ) )); + assert_eq! (unsafe { & ( * ( 0 as * const g ) ) . h as * const _ as usize + } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( g ) , "::" , stringify + ! ( h ) )); +} +impl Clone for g { + fn clone(&self) -> Self { *self } +} +impl Default for g { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +extern "C" { + #[link_name = "_Z25Servo_Element_GetSnapshotv"] + pub fn Servo_Element_GetSnapshot() -> A; +} diff --git a/tests/headers/issue-584-stylo-template-analysis-panic.hpp b/tests/headers/issue-584-stylo-template-analysis-panic.hpp new file mode 100644 index 00000000..3bf00e5d --- /dev/null +++ b/tests/headers/issue-584-stylo-template-analysis-panic.hpp @@ -0,0 +1,13 @@ +// bindgen-flags: --blacklist-type RefPtr --whitelist-function 'Servo_.*' --raw-line 'pub type RefPtr<T> = T;' -- -std=c++14 +template <class> class RefPtr; +class b; +class A { + typedef b a; +}; +template <class c> class e { RefPtr<c> d; }; +template <class> class f {}; +class g { + f<e<int>> h; +}; +class b : g {}; +A Servo_Element_GetSnapshot(); |