summaryrefslogtreecommitdiff
path: root/bindgen/codegen
diff options
context:
space:
mode:
authorChristian Poveda Ruiz <31802960+pvdrz@users.noreply.github.com>2022-11-22 11:41:32 -0500
committerGitHub <noreply@github.com>2022-11-22 11:41:32 -0500
commit046d6f9eea1803253c06dd99a0d38f5dcb5ed9c1 (patch)
tree286eeb0d0a9b7c7f2b756e96b01a21253158dc64 /bindgen/codegen
parentf160d11d56007fe1b1125d04f0cb31af0b18fc6e (diff)
Add `--wrap-unsafe-ops` option (#2354)
This reverts commit e8ffb42ab66405ac56d04494a30e54b584f2d4dd and adds a new `--wrap-unsafe-ops` option as a workaround.
Diffstat (limited to 'bindgen/codegen')
-rw-r--r--bindgen/codegen/dyngen.rs38
-rw-r--r--bindgen/codegen/mod.rs64
2 files changed, 58 insertions, 44 deletions
diff --git a/bindgen/codegen/dyngen.rs b/bindgen/codegen/dyngen.rs
index f310f14e..5e734ccd 100644
--- a/bindgen/codegen/dyngen.rs
+++ b/bindgen/codegen/dyngen.rs
@@ -1,4 +1,5 @@
use crate::codegen;
+use crate::ir::context::BindgenContext;
use crate::ir::function::ClangAbi;
use proc_macro2::Ident;
@@ -72,12 +73,22 @@ impl DynamicItems {
Self::default()
}
- pub fn get_tokens(&self, lib_ident: Ident) -> proc_macro2::TokenStream {
+ pub fn get_tokens(
+ &self,
+ lib_ident: Ident,
+ ctx: &BindgenContext,
+ ) -> proc_macro2::TokenStream {
let struct_members = &self.struct_members;
let constructor_inits = &self.constructor_inits;
let init_fields = &self.init_fields;
let struct_implementation = &self.struct_implementation;
+ let from_library = if ctx.options().wrap_unsafe_ops {
+ quote!(unsafe { Self::from_library(library) })
+ } else {
+ quote!(Self::from_library(library))
+ };
+
quote! {
extern crate libloading;
@@ -92,9 +103,7 @@ impl DynamicItems {
) -> Result<Self, ::libloading::Error>
where P: AsRef<::std::ffi::OsStr> {
let library = ::libloading::Library::new(path)?;
- unsafe {
- Self::from_library(library)
- }
+ #from_library
}
pub unsafe fn from_library<L>(
@@ -126,6 +135,7 @@ impl DynamicItems {
ret: proc_macro2::TokenStream,
ret_ty: proc_macro2::TokenStream,
attributes: Vec<proc_macro2::TokenStream>,
+ ctx: &BindgenContext,
) {
if !is_variadic {
assert_eq!(args.len(), args_identifiers.len());
@@ -149,8 +159,10 @@ impl DynamicItems {
} else {
quote! { self.#ident.as_ref().expect("Expected function, got error.") }
};
- let call_body = quote! {
- (#fn_)(#( #args_identifiers ),*)
+ let call_body = if ctx.options().wrap_unsafe_ops {
+ quote!(unsafe { (#fn_)(#( #args_identifiers ),*) })
+ } else {
+ quote!((#fn_)(#( #args_identifiers ),*) )
};
// We can't implement variadic functions from C easily, so we allow to
@@ -159,22 +171,26 @@ impl DynamicItems {
self.struct_implementation.push(quote! {
#(#attributes)*
pub unsafe fn #ident ( &self, #( #args ),* ) -> #ret_ty {
- unsafe {
- #call_body
- }
+ #call_body
}
});
}
// N.B: Unwrap the signature upon construction if it is required to be resolved.
let ident_str = codegen::helpers::ast_ty::cstr_expr(ident.to_string());
+ let library_get = if ctx.options().wrap_unsafe_ops {
+ quote!(unsafe { __library.get(#ident_str) })
+ } else {
+ quote!(__library.get(#ident_str))
+ };
+
self.constructor_inits.push(if is_required {
quote! {
- let #ident = unsafe { __library.get(#ident_str) }.map(|sym| *sym)?;
+ let #ident = #library_get.map(|sym| *sym)?;
}
} else {
quote! {
- let #ident = unsafe { __library.get(#ident_str) }.map(|sym| *sym);
+ let #ident = #library_get.map(|sym| *sym);
}
});
diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs
index c1e92b77..e5372427 100644
--- a/bindgen/codegen/mod.rs
+++ b/bindgen/codegen/mod.rs
@@ -2585,9 +2585,7 @@ impl MethodCodegen for Method {
})
}
- let block = quote! {
- #( #stmts );*
- };
+ let block = ctx.wrap_unsafe_ops(quote! ( #( #stmts );*));
let mut attrs = vec![attributes::inline()];
@@ -2601,9 +2599,7 @@ impl MethodCodegen for Method {
methods.push(quote! {
#(#attrs)*
pub unsafe fn #name ( #( #args ),* ) #ret {
- unsafe {
- #block
- }
+ #block
}
});
}
@@ -4169,6 +4165,7 @@ impl CodeGenerator for Function {
ret,
ret_ty,
attributes,
+ ctx,
);
} else {
result.push(tokens);
@@ -4212,17 +4209,18 @@ fn objc_method_codegen(
let methods_and_args = method.format_method_call(&fn_args);
- let body = if method.is_class_method() {
- let class_name = ctx.rust_ident(
- class_name.expect("Generating a class method without class name?"),
- );
- quote! {
- msg_send!(class!(#class_name), #methods_and_args)
- }
- } else {
- quote! {
- msg_send!(*self, #methods_and_args)
- }
+ let body = {
+ let body = if method.is_class_method() {
+ let class_name = ctx.rust_ident(
+ class_name
+ .expect("Generating a class method without class name?"),
+ );
+ quote!(msg_send!(class!(#class_name), #methods_and_args))
+ } else {
+ quote!(msg_send!(*self, #methods_and_args))
+ };
+
+ ctx.wrap_unsafe_ops(body)
};
let method_name =
@@ -4230,9 +4228,7 @@ fn objc_method_codegen(
methods.push(quote! {
unsafe fn #method_name #sig where <Self as std::ops::Deref>::Target: objc::Message + Sized {
- unsafe {
- #body
- }
+ #body
}
});
}
@@ -4495,7 +4491,7 @@ pub(crate) fn codegen(
if let Some(ref lib_name) = context.options().dynamic_library_name {
let lib_ident = context.rust_ident(lib_name);
let dynamic_items_tokens =
- result.dynamic_items().get_tokens(lib_ident);
+ result.dynamic_items().get_tokens(lib_ident, context);
result.push(dynamic_items_tokens);
}
@@ -4598,6 +4594,9 @@ pub mod utils {
pub struct __BindgenUnionField<T>(::#prefix::marker::PhantomData<T>);
};
+ let transmute =
+ ctx.wrap_unsafe_ops(quote!(::#prefix::mem::transmute(self)));
+
let union_field_impl = quote! {
impl<T> __BindgenUnionField<T> {
#[inline]
@@ -4607,16 +4606,12 @@ pub mod utils {
#[inline]
pub unsafe fn as_ref(&self) -> &T {
- unsafe {
- ::#prefix::mem::transmute(self)
- }
+ #transmute
}
#[inline]
pub unsafe fn as_mut(&mut self) -> &mut T {
- unsafe {
- ::#prefix::mem::transmute(self)
- }
+ #transmute
}
}
};
@@ -4711,6 +4706,13 @@ pub mod utils {
::#prefix::marker::PhantomData<T>, [T; 0]);
};
+ let from_raw_parts = ctx.wrap_unsafe_ops(quote! (
+ ::#prefix::slice::from_raw_parts(self.as_ptr(), len)
+ ));
+ let from_raw_parts_mut = ctx.wrap_unsafe_ops(quote! (
+ ::#prefix::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
+ ));
+
let incomplete_array_impl = quote! {
impl<T> __IncompleteArrayField<T> {
#[inline]
@@ -4730,16 +4732,12 @@ pub mod utils {
#[inline]
pub unsafe fn as_slice(&self, len: usize) -> &[T] {
- unsafe {
- ::#prefix::slice::from_raw_parts(self.as_ptr(), len)
- }
+ #from_raw_parts
}
#[inline]
pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] {
- unsafe {
- ::#prefix::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
- }
+ #from_raw_parts_mut
}
}
};