Skip to content

Commit 01d65d9

Browse files
armohaemilio
authored andcommitted
Fix unnecessary transmute and unsafe warnings on bitfield codegen
1 parent 9098393 commit 01d65d9

1 file changed

Lines changed: 43 additions & 17 deletions

File tree

bindgen/codegen/mod.rs

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,6 +2047,7 @@ impl<'a> FieldCodegen<'a> for Bitfield {
20472047

20482048
let bitfield_ty_item = ctx.resolve_item(self.ty());
20492049
let bitfield_ty = bitfield_ty_item.expect_type();
2050+
let bitfield_ty_kind = bitfield_ty.canonical_type(ctx).kind();
20502051
let bitfield_ty_ident = bitfield_ty.name();
20512052

20522053
let bitfield_ty_layout = bitfield_ty
@@ -2132,36 +2133,61 @@ impl<'a> FieldCodegen<'a> for Bitfield {
21322133
}
21332134
}));
21342135
} else {
2136+
let is_rust_union =
2137+
parent.is_union() && struct_layout.is_rust_union();
2138+
2139+
let get = quote! { self.#unit_field_ident.get_const::<#offset, #width>() as #bitfield_int_ty };
2140+
let raw_get = quote! {
2141+
<#unit_field_ty>::raw_get_const::<#offset, #width>(
2142+
::#prefix::ptr::addr_of!((*this).#unit_field_ident),
2143+
) as #bitfield_int_ty
2144+
};
2145+
2146+
let (getter_inner, raw_getter_inner) = match bitfield_ty_kind {
2147+
TypeKind::Int(IntKind::Bool) => {
2148+
(quote! { #get != 0 }, quote! { #raw_get != 0 })
2149+
}
2150+
TypeKind::Enum(..) => (
2151+
quote! { ::#prefix::mem::transmute(#get) },
2152+
quote! { ::#prefix::mem::transmute(#raw_get) },
2153+
),
2154+
_ => (quote! { #get as _ }, quote! { #raw_get as _ }),
2155+
};
2156+
2157+
let getter_body = if is_rust_union ||
2158+
matches!(bitfield_ty_kind, TypeKind::Enum(..))
2159+
{
2160+
quote! { unsafe { #getter_inner } }
2161+
} else {
2162+
getter_inner
2163+
};
2164+
2165+
let setter_inner = quote! {
2166+
let val: #bitfield_int_ty = val as _;
2167+
self.#unit_field_ident.set_const::<#offset, #width>(val as u64)
2168+
};
2169+
let setter_body = if is_rust_union {
2170+
quote! { unsafe { #setter_inner } }
2171+
} else {
2172+
setter_inner
2173+
};
2174+
21352175
methods.extend(Some(quote! {
21362176
#[inline]
21372177
#access_spec fn #getter_name(&self) -> #bitfield_ty {
2138-
unsafe {
2139-
::#prefix::mem::transmute(
2140-
self.#unit_field_ident.get_const::<#offset, #width>()
2141-
as #bitfield_int_ty
2142-
)
2143-
}
2178+
#getter_body
21442179
}
21452180

21462181
#[inline]
21472182
#access_spec fn #setter_name(&mut self, val: #bitfield_ty) {
2148-
unsafe {
2149-
let val: #bitfield_int_ty = val as _;
2150-
self.#unit_field_ident.set_const::<#offset, #width>(
2151-
val as u64
2152-
)
2153-
}
2183+
#setter_body
21542184
}
21552185
}));
21562186

21572187
methods.extend(Some(quote! {
21582188
#[inline]
21592189
#access_spec unsafe fn #raw_getter_name(this: *const Self) -> #bitfield_ty {
2160-
unsafe {
2161-
::#prefix::mem::transmute(<#unit_field_ty>::raw_get_const::<#offset, #width>(
2162-
::#prefix::ptr::addr_of!((*this).#unit_field_ident),
2163-
) as #bitfield_int_ty)
2164-
}
2190+
unsafe { #raw_getter_inner }
21652191
}
21662192

21672193
#[inline]

0 commit comments

Comments
 (0)