diff --git a/src/ir/ty.rs b/src/ir/ty.rs index b5c78c16b5..b742dcc1cc 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 218abbdbce..c7863931c0 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 { pub foo: *const T, - pub bar: *mut T, + pub bar: *const T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, } impl Default for C { diff --git a/tests/expectations/tests/derive-hash-struct-with-pointer.rs b/tests/expectations/tests/derive-hash-struct-with-pointer.rs index ee41c4f4f4..c69bcd7c4e 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 0000000000..ff725b3393 --- /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 7ca267dcbd..15fbfa42e4 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 ::std::os::raw::c_int, >; diff --git a/tests/headers/issue-511.h b/tests/headers/issue-511.h new file mode 100644 index 0000000000..da3643121e --- /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