Skip to content

Commit 6390196

Browse files
committed
Map size_t to usize by default and check compatibility (fixes rust-lang#1901, rust-lang#1903)
This addresses the underlying issue identified in rust-lang#1671, that size_t (integer that can hold any object size) isn't guaranteed to match usize, which is defined more like uintptr_t (integer that can hold any pointer). However, on almost all platforms, this is true, and in fact Rust already uses usize extensively in contexts where size_t would be more appropriate, such as slice indexing. So, it's better for ergonomics when interfacing with C code to map the C size_t type to usize. (See also discussion in rust-lang/rust#65473 about how usize really should be defined as size_t, not uintptr_t.) The previous fix for rust-lang#1671 removed the special case for size_t and defaulted to binding it as a normal typedef. This change effectively reverts that and goes back to mapping size_t to usize (and ssize_t to isize), but also ensures that if size_t is emitted, the typedef'd type of size_t in fact is compatible with usize (defined by checking that the size and alignment match the target pointer width). For (hypothetical) platforms where this is not true, or for compatibility with the default behavior of bindgen between 0.53 and this commit, onwards, you can disable this mapping with --no-size_t-is-usize.
1 parent b60339e commit 6390196

13 files changed

+32
-31
lines changed

src/codegen/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -820,9 +820,16 @@ impl CodeGenerator for Type {
820820
}
821821

822822
// If this is a known named type, disallow generating anything
823-
// for it too.
823+
// for it too. If size_t -> usize conversions are enabled, we
824+
// need to check that these conversions are permissible, but
825+
// nothing needs to be generated, still.
824826
let spelling = self.name().expect("Unnamed alias?");
825827
if utils::type_from_named(ctx, spelling).is_some() {
828+
if let "size_t" | "ssize_t" = spelling {
829+
let layout = inner_item.kind().expect_type().layout(ctx).expect("No layout?");
830+
assert!(layout.size == ctx.target_pointer_size() && layout.align == ctx.target_pointer_size(),
831+
"Target platform requires --no-size_t-is-usize");
832+
}
826833
return;
827834
}
828835

src/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -523,8 +523,8 @@ impl Builder {
523523
output_vector.push("--no-record-matches".into());
524524
}
525525

526-
if self.options.size_t_is_usize {
527-
output_vector.push("--size_t-is-usize".into());
526+
if !self.options.size_t_is_usize {
527+
output_vector.push("--no-size_t-is-usize".into());
528528
}
529529

530530
if !self.options.rustfmt_bindings {
@@ -2065,7 +2065,7 @@ impl Default for BindgenOptions {
20652065
time_phases: false,
20662066
record_matches: true,
20672067
rustfmt_bindings: true,
2068-
size_t_is_usize: false,
2068+
size_t_is_usize: true,
20692069
rustfmt_configuration_file: None,
20702070
no_partialeq_types: Default::default(),
20712071
no_copy_types: Default::default(),

src/options.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,12 @@ where
429429
),
430430
Arg::with_name("size_t-is-usize")
431431
.long("size_t-is-usize")
432-
.help("Translate size_t to usize."),
432+
.help("Ignored - this is enabled by default.")
433+
.hidden(true),
434+
Arg::with_name("no-size_t-is-usize")
435+
.long("no-size_t-is-usize")
436+
.help("Do not bind size_t as usize (useful on platforms \
437+
where those types are incompatible)."),
433438
Arg::with_name("no-rustfmt-bindings")
434439
.long("no-rustfmt-bindings")
435440
.help("Do not format the generated bindings with rustfmt."),
@@ -874,8 +879,8 @@ where
874879
builder = builder.record_matches(false);
875880
}
876881

877-
if matches.is_present("size_t-is-usize") {
878-
builder = builder.size_t_is_usize(true);
882+
if matches.is_present("no-size_t-is-usize") {
883+
builder = builder.size_t_is_usize(false);
879884
}
880885

881886
let no_rustfmt_bindings = matches.is_present("no-rustfmt-bindings");

tests/expectations/tests/blocks-signature.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#![cfg(target_os = "macos")]
88

99
extern crate block;
10-
pub type size_t = ::std::os::raw::c_ulonglong;
1110
extern "C" {
1211
#[link_name = "\u{1}_Z8atexit_bU13block_pointerFvvE"]
1312
pub fn atexit_b(arg1: _bindgen_ty_id_33);
@@ -85,16 +84,11 @@ impl Default for contains_block_pointers {
8584
}
8685
pub type _bindgen_ty_id_33 = *const ::block::Block<(), ()>;
8786
pub type _bindgen_ty_id_40 = *const ::block::Block<
88-
(
89-
dispatch_data_t,
90-
size_t,
91-
*const ::std::os::raw::c_void,
92-
size_t,
93-
),
87+
(dispatch_data_t, usize, *const ::std::os::raw::c_void, usize),
9488
bool,
9589
>;
96-
pub type _bindgen_ty_id_50 = *const ::block::Block<(size_t,), ()>;
97-
pub type _bindgen_ty_id_56 = *const ::block::Block<(size_t,), ()>;
90+
pub type _bindgen_ty_id_50 = *const ::block::Block<(usize,), ()>;
91+
pub type _bindgen_ty_id_56 = *const ::block::Block<(usize,), ()>;
9892
pub type contains_block_pointers__bindgen_ty_id_61 =
9993
*const ::block::Block<(::std::os::raw::c_int,), ()>;
10094
pub type _bindgen_ty_id_68 =

tests/expectations/tests/blocks.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
)]
77
#![cfg(target_os = "macos")]
88

9-
pub type size_t = ::std::os::raw::c_ulonglong;
109
extern "C" {
1110
#[link_name = "\u{1}_Z8atexit_bU13block_pointerFvvE"]
1211
pub fn atexit_b(arg1: *mut ::std::os::raw::c_void);

tests/expectations/tests/issue-1498.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
non_upper_case_globals
66
)]
77

8-
pub type size_t = u64;
98
#[repr(C, packed)]
109
#[derive(Copy, Clone)]
1110
pub struct rte_memseg {
1211
///< Start physical address.
1312
pub phys_addr: u64,
1413
pub __bindgen_anon_1: rte_memseg__bindgen_ty_1,
1514
///< Length of the segment.
16-
pub len: size_t,
15+
pub len: usize,
1716
///< The pagesize of underlying memory
1817
pub hugepage_sz: u64,
1918
///< NUMA socket ID.

tests/expectations/tests/jsval_layout_opaque.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ where
9494
pub const JSVAL_TAG_SHIFT: u32 = 47;
9595
pub const JSVAL_PAYLOAD_MASK: u64 = 140737488355327;
9696
pub const JSVAL_TAG_MASK: i64 = -140737488355328;
97-
pub type size_t = ::std::os::raw::c_ulonglong;
9897
#[repr(u8)]
9998
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
10099
pub enum JSValueType {
@@ -186,7 +185,7 @@ pub union jsval_layout {
186185
pub s: jsval_layout__bindgen_ty_2,
187186
pub asDouble: f64,
188187
pub asPtr: *mut ::std::os::raw::c_void,
189-
pub asWord: size_t,
188+
pub asWord: usize,
190189
pub asUIntPtr: usize,
191190
}
192191
#[repr(C)]

tests/expectations/tests/jsval_layout_opaque_1_0.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ impl<T> ::std::cmp::Eq for __BindgenUnionField<T> {}
137137
pub const JSVAL_TAG_SHIFT: u32 = 47;
138138
pub const JSVAL_PAYLOAD_MASK: u64 = 140737488355327;
139139
pub const JSVAL_TAG_MASK: i64 = -140737488355328;
140-
pub type size_t = ::std::os::raw::c_ulonglong;
141140
#[repr(u8)]
142141
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
143142
pub enum JSValueType {
@@ -229,7 +228,7 @@ pub struct jsval_layout {
229228
pub s: __BindgenUnionField<jsval_layout__bindgen_ty_2>,
230229
pub asDouble: __BindgenUnionField<f64>,
231230
pub asPtr: __BindgenUnionField<*mut ::std::os::raw::c_void>,
232-
pub asWord: __BindgenUnionField<size_t>,
231+
pub asWord: __BindgenUnionField<usize>,
233232
pub asUIntPtr: __BindgenUnionField<usize>,
234233
pub bindgen_union_field: u64,
235234
}

tests/expectations/tests/layout_array.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ pub const RTE_CACHE_LINE_SIZE: u32 = 64;
99
pub const RTE_MEMPOOL_OPS_NAMESIZE: u32 = 32;
1010
pub const RTE_MEMPOOL_MAX_OPS_IDX: u32 = 16;
1111
pub const RTE_HEAP_NUM_FREELISTS: u32 = 13;
12-
pub type size_t = ::std::os::raw::c_longlong;
1312
#[repr(C)]
1413
#[derive(Debug, Copy, Clone)]
1514
pub struct rte_mempool {
@@ -298,7 +297,7 @@ pub struct malloc_heap {
298297
pub lock: rte_spinlock_t,
299298
pub free_head: [malloc_heap__bindgen_ty_1; 13usize],
300299
pub alloc_count: ::std::os::raw::c_uint,
301-
pub total_size: size_t,
300+
pub total_size: usize,
302301
}
303302
#[repr(C)]
304303
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]

tests/expectations/tests/msvc-no-usr.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
non_upper_case_globals
66
)]
77

8-
pub type size_t = ::std::os::raw::c_ulonglong;
98
#[repr(C)]
109
#[derive(Debug, Default, Copy, Clone)]
1110
pub struct A {
12-
pub foo: size_t,
11+
pub foo: usize,
1312
}
1413
#[test]
1514
fn bindgen_test_layout_A() {

tests/expectations/tests/size_t_is_usize.rs renamed to tests/expectations/tests/no_size_t_is_usize.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
non_upper_case_globals
66
)]
77

8+
pub type size_t = ::std::os::raw::c_ulong;
9+
pub type ssize_t = ::std::os::raw::c_long;
810
#[repr(C)]
911
#[derive(Debug, Copy, Clone)]
1012
pub struct A {
11-
pub len: usize,
12-
pub offset: isize,
13+
pub len: size_t,
14+
pub offset: ssize_t,
1315
pub next: *mut A,
1416
}
1517
#[test]

tests/expectations/tests/nsBaseHashtable.rs

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
non_upper_case_globals
66
)]
77

8-
pub type size_t = ::std::os::raw::c_ulonglong;
98
#[repr(C)]
109
#[derive(Debug, Default, Copy, Clone)]
1110
pub struct nsBaseHashtableET {

tests/headers/size_t_is_usize.h renamed to tests/headers/no_size_t_is_usize.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// bindgen-flags: --size_t-is-usize
1+
// bindgen-flags: --no-size_t-is-usize
22

33
typedef unsigned long size_t;
44
typedef long ssize_t;

0 commit comments

Comments
 (0)