summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2018-05-14 12:15:59 -0400
committerGitHub <noreply@github.com>2018-05-14 12:15:59 -0400
commit74dcb202e398f8101a5bb387628d21ed0f781359 (patch)
tree5a40cdad7e6a79b798a8da584bc14ea7a861cd41
parent515ca97b462f348b7b3bb9eaea98b2e0bb1b624b (diff)
parent1fc8172889e981d45e819c9f394fe4b6b41dbc38 (diff)
Auto merge of #1311 - cynecx:canonicalize_pointer_ty, r=emilio
Canonicalize a type (pointer type) first before checking for constness This fixes cases like: ```cpp int sodium_munlock(int* const addr); // addr itself is const but the pointer points to mutable data ``` Before fix: ```rust extern "C" { pub fn sodium_munlock( addr: *const ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } ``` After this patch: ```rust extern "C" { pub fn sodium_munlock( addr: *mut ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } ```
-rw-r--r--src/ir/ty.rs18
-rw-r--r--tests/expectations/tests/const_tparam.rs4
-rw-r--r--tests/expectations/tests/derive-hash-struct-with-pointer.rs5
-rw-r--r--tests/expectations/tests/issue-511.rs20
-rw-r--r--tests/expectations/tests/layout_array.rs2
-rw-r--r--tests/headers/issue-511.h4
6 files changed, 44 insertions, 9 deletions
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index b5c78c16..b742dcc1 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -1194,7 +1194,23 @@ impl Type {
};
let name = if name.is_empty() { None } else { Some(name) };
- let is_const = ty.is_const();
+
+ // Just using ty.is_const() is wrong here, because when we declare an
+ // argument like 'int* const arg0', arg0 is considered
+ // const but the pointer itself points to mutable data.
+ //
+ // Without canonicalizing the type to the pointer type, we'll get the
+ // following mapping:
+ //
+ // arg0: *const c_int
+ //
+ // So by canonicalizing the type first, we can check constness by
+ // calling is_const() on the pointer type.
+ let is_const = if let Some(pty) = ty.pointee_type() {
+ pty.is_const()
+ } else {
+ ty.is_const()
+ };
let ty = Type::new(name, layout, kind, is_const);
// TODO: maybe declaration.canonical()?
diff --git a/tests/expectations/tests/const_tparam.rs b/tests/expectations/tests/const_tparam.rs
index 218abbdb..c7863931 100644
--- a/tests/expectations/tests/const_tparam.rs
+++ b/tests/expectations/tests/const_tparam.rs
@@ -1,14 +1,12 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct C<T> {
pub foo: *const T,
- pub bar: *mut T,
+ pub bar: *const T,
pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
}
impl<T> Default for C<T> {
diff --git a/tests/expectations/tests/derive-hash-struct-with-pointer.rs b/tests/expectations/tests/derive-hash-struct-with-pointer.rs
index ee41c4f4..c69bcd7c 100644
--- a/tests/expectations/tests/derive-hash-struct-with-pointer.rs
+++ b/tests/expectations/tests/derive-hash-struct-with-pointer.rs
@@ -1,15 +1,12 @@
/* automatically generated by rust-bindgen */
-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
-
-
/// Pointers can derive Hash/PartialOrd/Ord/PartialEq/Eq
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct ConstPtrMutObj {
- pub bar: *const ::std::os::raw::c_int,
+ pub bar: *mut ::std::os::raw::c_int,
}
#[test]
fn bindgen_test_layout_ConstPtrMutObj() {
diff --git a/tests/expectations/tests/issue-511.rs b/tests/expectations/tests/issue-511.rs
new file mode 100644
index 00000000..ff725b33
--- /dev/null
+++ b/tests/expectations/tests/issue-511.rs
@@ -0,0 +1,20 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+extern "C" {
+ #[link_name = "\u{1}a"]
+ pub static mut a: *mut ::std::os::raw::c_char;
+}
+extern "C" {
+ #[link_name = "\u{1}b"]
+ pub static mut b: *const ::std::os::raw::c_char;
+}
+extern "C" {
+ #[link_name = "\u{1}c"]
+ pub static mut c: *mut ::std::os::raw::c_char;
+}
+extern "C" {
+ #[link_name = "\u{1}d"]
+ pub static mut d: *const ::std::os::raw::c_char;
+}
diff --git a/tests/expectations/tests/layout_array.rs b/tests/expectations/tests/layout_array.rs
index 7ca267dc..15fbfa42 100644
--- a/tests/expectations/tests/layout_array.rs
+++ b/tests/expectations/tests/layout_array.rs
@@ -27,7 +27,7 @@ pub type rte_mempool_free_t = ::std::option::Option<unsafe extern "C" fn(mp: *mu
pub type rte_mempool_enqueue_t = ::std::option::Option<
unsafe extern "C" fn(
mp: *mut rte_mempool,
- obj_table: *const *const ::std::os::raw::c_void,
+ obj_table: *const *mut ::std::os::raw::c_void,
n: ::std::os::raw::c_uint,
) -> ::std::os::raw::c_int,
>;
diff --git a/tests/headers/issue-511.h b/tests/headers/issue-511.h
new file mode 100644
index 00000000..da364312
--- /dev/null
+++ b/tests/headers/issue-511.h
@@ -0,0 +1,4 @@
+char * a;
+const char * b;
+char * const c;
+const char * const d; \ No newline at end of file