Skip to content

Commit

Permalink
Handle pointer constness at the right level.
Browse files Browse the repository at this point in the history
  • Loading branch information
emilio committed May 15, 2018
1 parent 35fb113 commit 716d53b
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3054,7 +3054,7 @@ impl TryToRustTy for Type {
}
TypeKind::Pointer(inner) |
TypeKind::Reference(inner) => {
let is_const = self.is_const() || ctx.resolve_type(inner).is_const();
let is_const = ctx.resolve_type(inner).is_const();

let inner = inner.into_resolver().through_type_refs().resolve(ctx);
let inner_ty = inner.expect_type();
Expand Down
17 changes: 1 addition & 16 deletions src/ir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1195,22 +1195,7 @@ impl Type {

let name = if name.is_empty() { None } else { Some(name) };

// 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 is_const = ty.is_const();

let ty = Type::new(name, layout, kind, is_const);
// TODO: maybe declaration.canonical()?
Expand Down
32 changes: 32 additions & 0 deletions tests/expectations/tests/const-const-mut-ptr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* 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 foo {
pub bar: *const *const *mut *const ::std::os::raw::c_int,
}
#[test]
fn bindgen_test_layout_foo() {
assert_eq!(
::std::mem::size_of::<foo>(),
8usize,
concat!("Size of: ", stringify!(foo))
);
assert_eq!(
::std::mem::align_of::<foo>(),
8usize,
concat!("Alignment of ", stringify!(foo))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<foo>())).bar as *const _ as usize },
0usize,
concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar))
);
}
impl Default for foo {
fn default() -> Self {
unsafe { ::std::mem::zeroed() }
}
}
3 changes: 3 additions & 0 deletions tests/headers/const-const-mut-ptr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
struct foo {
const int** const* const* bar;
};

0 comments on commit 716d53b

Please sign in to comment.