summaryrefslogtreecommitdiff
path: root/src/codegen/mod.rs
diff options
context:
space:
mode:
authorGeoffrey Thomas <geofft@ldpreload.com>2021-06-03 10:47:26 -0400
committerChristian Poveda <christian.poveda@ferrous-systems.com>2022-09-23 21:13:37 -0500
commitcc78b6fdb6e829e5fb8fa1639f2182cb49333569 (patch)
tree09b846c15394d331489c2ae0ff6bf611736aa428 /src/codegen/mod.rs
parent6de2d3d1c17bb4dd432daabf2cd858254663f49e (diff)
Map size_t to usize by default and check compatibility (fixes #1901, #1903)
This addresses the underlying issue identified in #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 #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.
Diffstat (limited to 'src/codegen/mod.rs')
-rw-r--r--src/codegen/mod.rs27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 843d5111..8eb7b013 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -836,9 +836,34 @@ impl CodeGenerator for Type {
}
// If this is a known named type, disallow generating anything
- // for it too.
+ // for it too. If size_t -> usize conversions are enabled, we
+ // need to check that these conversions are permissible, but
+ // nothing needs to be generated, still.
let spelling = self.name().expect("Unnamed alias?");
if utils::type_from_named(ctx, spelling).is_some() {
+ if let "size_t" | "ssize_t" = spelling {
+ let layout = inner_item
+ .kind()
+ .expect_type()
+ .layout(ctx)
+ .expect("No layout?");
+ assert_eq!(
+ layout.size,
+ ctx.target_pointer_size(),
+ "Target platform requires `--no-size_t-is-usize`. The size of `{}` ({}) does not match the target pointer size ({})",
+ spelling,
+ layout.size,
+ ctx.target_pointer_size(),
+ );
+ assert_eq!(
+ layout.align,
+ ctx.target_pointer_size(),
+ "Target platform requires `--no-size_t-is-usize`. The alignment of `{}` ({}) does not match the target pointer size ({})",
+ spelling,
+ layout.align,
+ ctx.target_pointer_size(),
+ );
+ }
return;
}