From 993a95922c12fd4e46efa368e2a8b0807d38eff5 Mon Sep 17 00:00:00 2001 From: Emilio Cobos Álvarez Date: Wed, 1 Feb 2017 18:59:33 +0100 Subject: ir: Fix is_in_non_fully_specialized_template check. Fixes https://github.com/servo/rust-bindgen/issues/462 --- src/clang.rs | 16 +++++++++++---- src/ir/function.rs | 2 +- .../tests/constant-non-specialized-tp.rs | 24 ++++++++++++++++++++++ tests/headers/constant-non-specialized-tp.hpp | 15 ++++++++++++++ 4 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 tests/expectations/tests/constant-non-specialized-tp.rs create mode 100644 tests/headers/constant-non-specialized-tp.hpp diff --git a/src/clang.rs b/src/clang.rs index 9cf51436..b659343e 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -201,14 +201,14 @@ impl Cursor { } /// Is the referent a template specialization? - pub fn is_template(&self) -> bool { + pub fn is_template_specialization(&self) -> bool { self.specialized().is_some() } /// Is the referent a fully specialized template specialization without any /// remaining free template arguments? pub fn is_fully_specialized_template(&self) -> bool { - self.is_template() && self.num_template_args().unwrap_or(0) > 0 + self.is_template_specialization() && self.num_template_args().unwrap_or(0) > 0 } /// Is the referent a template specialization that still has remaining free @@ -217,9 +217,17 @@ impl Cursor { if self.is_toplevel() { return false; } + let parent = self.semantic_parent(); - (parent.is_template() && !parent.is_fully_specialized_template()) || - parent.is_in_non_fully_specialized_template() + if parent.is_fully_specialized_template() { + return false; + } + + if !parent.is_template_like() { + return parent.is_in_non_fully_specialized_template(); + } + + return true; } /// Is this cursor pointing a valid referent? diff --git a/src/ir/function.rs b/src/ir/function.rs index 6e205f1b..a50edfde 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -93,7 +93,7 @@ fn get_abi(cc: CXCallingConv) -> abi::Abi { pub fn cursor_mangling(cursor: &clang::Cursor) -> Option { // We early return here because libclang may crash in some case // if we pass in a variable inside a partial specialized template. - // See servo/rust-bindgen#67. + // See servo/rust-bindgen#67, and servo/rust-bindgen#462. if cursor.is_in_non_fully_specialized_template() { return None; } diff --git a/tests/expectations/tests/constant-non-specialized-tp.rs b/tests/expectations/tests/constant-non-specialized-tp.rs new file mode 100644 index 00000000..bbadf8a2 --- /dev/null +++ b/tests/expectations/tests/constant-non-specialized-tp.rs @@ -0,0 +1,24 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Test { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Outer { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Outer_Inner { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData, +} diff --git a/tests/headers/constant-non-specialized-tp.hpp b/tests/headers/constant-non-specialized-tp.hpp new file mode 100644 index 00000000..539c2887 --- /dev/null +++ b/tests/headers/constant-non-specialized-tp.hpp @@ -0,0 +1,15 @@ +// bindgen-flags: -- -std=c++11 + +// This test ensure we protect ourselves from an LLVM crash. + +template +struct Test { + static constexpr bool x[] = {Args::x...}; +}; + +template +struct Outer { + struct Inner { + static constexpr int value[] = { T::value... }; + }; +}; -- cgit v1.2.3