From 46764bbe725a54d92e8cd8f566db3e65bb821c5e Mon Sep 17 00:00:00 2001 From: Daniil Klimov Date: Tue, 11 Feb 2025 05:59:20 +0300 Subject: [PATCH 1/3] Fixed handling of trait methods containing the unsafe attribute --- src/bindgen/utilities.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bindgen/utilities.rs b/src/bindgen/utilities.rs index 28ae7838..f4058313 100644 --- a/src/bindgen/utilities.rs +++ b/src/bindgen/utilities.rs @@ -50,6 +50,7 @@ impl SynItemHelpers for syn::ImplItemFn { fn exported_name(&self) -> Option { self.attrs .attr_name_value_lookup("export_name") + .or_else(|| self.unsafe_attr_name_value_lookup("export_name")) .or_else(|| { if self.is_no_mangle() { Some(self.sig.ident.unraw().to_string()) From 6f8fa31e48202098d34f8ed7072777252416db2d Mon Sep 17 00:00:00 2001 From: Daniil Klimov Date: Wed, 12 Feb 2025 14:11:51 +0300 Subject: [PATCH 2/3] Added tests for unsafe methotd's atributs --- .../impl_unsafe_attr_method.c.sym | 3 +++ tests/expectations/impl_unsafe_attr_method.c | 10 ++++++++++ .../impl_unsafe_attr_method.compat.c | 18 ++++++++++++++++++ tests/expectations/impl_unsafe_attr_method.cpp | 15 +++++++++++++++ tests/expectations/impl_unsafe_attr_method.pyx | 12 ++++++++++++ .../impl_unsafe_attr_method_both.c | 10 ++++++++++ .../impl_unsafe_attr_method_both.compat.c | 18 ++++++++++++++++++ .../expectations/impl_unsafe_attr_method_tag.c | 10 ++++++++++ .../impl_unsafe_attr_method_tag.compat.c | 18 ++++++++++++++++++ .../impl_unsafe_attr_method_tag.pyx | 12 ++++++++++++ tests/rust/impl_unsafe_attr_method.rs | 14 ++++++++++++++ 11 files changed, 140 insertions(+) create mode 100644 tests/expectations-symbols/impl_unsafe_attr_method.c.sym create mode 100644 tests/expectations/impl_unsafe_attr_method.c create mode 100644 tests/expectations/impl_unsafe_attr_method.compat.c create mode 100644 tests/expectations/impl_unsafe_attr_method.cpp create mode 100644 tests/expectations/impl_unsafe_attr_method.pyx create mode 100644 tests/expectations/impl_unsafe_attr_method_both.c create mode 100644 tests/expectations/impl_unsafe_attr_method_both.compat.c create mode 100644 tests/expectations/impl_unsafe_attr_method_tag.c create mode 100644 tests/expectations/impl_unsafe_attr_method_tag.compat.c create mode 100644 tests/expectations/impl_unsafe_attr_method_tag.pyx create mode 100644 tests/rust/impl_unsafe_attr_method.rs diff --git a/tests/expectations-symbols/impl_unsafe_attr_method.c.sym b/tests/expectations-symbols/impl_unsafe_attr_method.c.sym new file mode 100644 index 00000000..6feb48ef --- /dev/null +++ b/tests/expectations-symbols/impl_unsafe_attr_method.c.sym @@ -0,0 +1,3 @@ +{ +new_dummy; +}; \ No newline at end of file diff --git a/tests/expectations/impl_unsafe_attr_method.c b/tests/expectations/impl_unsafe_attr_method.c new file mode 100644 index 00000000..5e9467c3 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include + +typedef struct { + int32_t dummy_field; +} DummyStruct; + +DummyStruct new_dummy(void); diff --git a/tests/expectations/impl_unsafe_attr_method.compat.c b/tests/expectations/impl_unsafe_attr_method.compat.c new file mode 100644 index 00000000..26aaf31b --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method.compat.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +typedef struct { + int32_t dummy_field; +} DummyStruct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +DummyStruct new_dummy(void); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method.cpp b/tests/expectations/impl_unsafe_attr_method.cpp new file mode 100644 index 00000000..f1e8ea90 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method.cpp @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include + +struct DummyStruct { + int32_t dummy_field; +}; + +extern "C" { + +DummyStruct new_dummy(); + +} // extern "C" diff --git a/tests/expectations/impl_unsafe_attr_method.pyx b/tests/expectations/impl_unsafe_attr_method.pyx new file mode 100644 index 00000000..0d39e71d --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method.pyx @@ -0,0 +1,12 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list + +cdef extern from *: + + ctypedef struct DummyStruct: + int32_t dummy_field; + + DummyStruct new_dummy(); diff --git a/tests/expectations/impl_unsafe_attr_method_both.c b/tests/expectations/impl_unsafe_attr_method_both.c new file mode 100644 index 00000000..175f7f19 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_both.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include + +typedef struct DummyStruct { + int32_t dummy_field; +} DummyStruct; + +struct DummyStruct new_dummy(void); diff --git a/tests/expectations/impl_unsafe_attr_method_both.compat.c b/tests/expectations/impl_unsafe_attr_method_both.compat.c new file mode 100644 index 00000000..ca5396ec --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_both.compat.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +typedef struct DummyStruct { + int32_t dummy_field; +} DummyStruct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +struct DummyStruct new_dummy(void); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method_tag.c b/tests/expectations/impl_unsafe_attr_method_tag.c new file mode 100644 index 00000000..31492fd5 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_tag.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include + +struct DummyStruct { + int32_t dummy_field; +}; + +struct DummyStruct new_dummy(void); diff --git a/tests/expectations/impl_unsafe_attr_method_tag.compat.c b/tests/expectations/impl_unsafe_attr_method_tag.compat.c new file mode 100644 index 00000000..16a8962a --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_tag.compat.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +struct DummyStruct { + int32_t dummy_field; +}; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +struct DummyStruct new_dummy(void); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method_tag.pyx b/tests/expectations/impl_unsafe_attr_method_tag.pyx new file mode 100644 index 00000000..2ef4bd85 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_tag.pyx @@ -0,0 +1,12 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list + +cdef extern from *: + + cdef struct DummyStruct: + int32_t dummy_field; + + DummyStruct new_dummy(); diff --git a/tests/rust/impl_unsafe_attr_method.rs b/tests/rust/impl_unsafe_attr_method.rs new file mode 100644 index 00000000..4ab7e8c0 --- /dev/null +++ b/tests/rust/impl_unsafe_attr_method.rs @@ -0,0 +1,14 @@ +#[repr(C)] +pub struct DummyStruct { + dummy_field: i32, +} + + +impl DummyStruct { + #[unsafe(export_name = "new_dummy")] + pub const extern "C" fn new() -> Self { + Self { + dummy_field: 0, + } + } +} From 602172d0db4315372f1ad84a12db96dbf753f1b6 Mon Sep 17 00:00:00 2001 From: Daniil Klimov Date: Wed, 12 Feb 2025 14:18:52 +0300 Subject: [PATCH 3/3] Added test for unsafe(no_mangle) attribute --- tests/expectations-symbols/impl_unsafe_attr_method.c.sym | 1 + tests/expectations/impl_unsafe_attr_method.c | 2 ++ tests/expectations/impl_unsafe_attr_method.compat.c | 2 ++ tests/expectations/impl_unsafe_attr_method.cpp | 2 ++ tests/expectations/impl_unsafe_attr_method.pyx | 2 ++ tests/expectations/impl_unsafe_attr_method_both.c | 2 ++ tests/expectations/impl_unsafe_attr_method_both.compat.c | 2 ++ tests/expectations/impl_unsafe_attr_method_tag.c | 2 ++ tests/expectations/impl_unsafe_attr_method_tag.compat.c | 2 ++ tests/expectations/impl_unsafe_attr_method_tag.pyx | 2 ++ tests/rust/impl_unsafe_attr_method.rs | 7 +++++++ 11 files changed, 26 insertions(+) diff --git a/tests/expectations-symbols/impl_unsafe_attr_method.c.sym b/tests/expectations-symbols/impl_unsafe_attr_method.c.sym index 6feb48ef..271f7251 100644 --- a/tests/expectations-symbols/impl_unsafe_attr_method.c.sym +++ b/tests/expectations-symbols/impl_unsafe_attr_method.c.sym @@ -1,3 +1,4 @@ { new_dummy; +new_dummy_param; }; \ No newline at end of file diff --git a/tests/expectations/impl_unsafe_attr_method.c b/tests/expectations/impl_unsafe_attr_method.c index 5e9467c3..822c4cea 100644 --- a/tests/expectations/impl_unsafe_attr_method.c +++ b/tests/expectations/impl_unsafe_attr_method.c @@ -8,3 +8,5 @@ typedef struct { } DummyStruct; DummyStruct new_dummy(void); + +DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/expectations/impl_unsafe_attr_method.compat.c b/tests/expectations/impl_unsafe_attr_method.compat.c index 26aaf31b..a4752756 100644 --- a/tests/expectations/impl_unsafe_attr_method.compat.c +++ b/tests/expectations/impl_unsafe_attr_method.compat.c @@ -13,6 +13,8 @@ extern "C" { DummyStruct new_dummy(void); +DummyStruct new_dummy_param(int32_t dummy_field); + #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method.cpp b/tests/expectations/impl_unsafe_attr_method.cpp index f1e8ea90..1f12ee89 100644 --- a/tests/expectations/impl_unsafe_attr_method.cpp +++ b/tests/expectations/impl_unsafe_attr_method.cpp @@ -12,4 +12,6 @@ extern "C" { DummyStruct new_dummy(); +DummyStruct new_dummy_param(int32_t dummy_field); + } // extern "C" diff --git a/tests/expectations/impl_unsafe_attr_method.pyx b/tests/expectations/impl_unsafe_attr_method.pyx index 0d39e71d..c502b519 100644 --- a/tests/expectations/impl_unsafe_attr_method.pyx +++ b/tests/expectations/impl_unsafe_attr_method.pyx @@ -10,3 +10,5 @@ cdef extern from *: int32_t dummy_field; DummyStruct new_dummy(); + + DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/expectations/impl_unsafe_attr_method_both.c b/tests/expectations/impl_unsafe_attr_method_both.c index 175f7f19..9c6a0d7d 100644 --- a/tests/expectations/impl_unsafe_attr_method_both.c +++ b/tests/expectations/impl_unsafe_attr_method_both.c @@ -8,3 +8,5 @@ typedef struct DummyStruct { } DummyStruct; struct DummyStruct new_dummy(void); + +struct DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/expectations/impl_unsafe_attr_method_both.compat.c b/tests/expectations/impl_unsafe_attr_method_both.compat.c index ca5396ec..c933e17d 100644 --- a/tests/expectations/impl_unsafe_attr_method_both.compat.c +++ b/tests/expectations/impl_unsafe_attr_method_both.compat.c @@ -13,6 +13,8 @@ extern "C" { struct DummyStruct new_dummy(void); +struct DummyStruct new_dummy_param(int32_t dummy_field); + #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method_tag.c b/tests/expectations/impl_unsafe_attr_method_tag.c index 31492fd5..d0db9853 100644 --- a/tests/expectations/impl_unsafe_attr_method_tag.c +++ b/tests/expectations/impl_unsafe_attr_method_tag.c @@ -8,3 +8,5 @@ struct DummyStruct { }; struct DummyStruct new_dummy(void); + +struct DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/expectations/impl_unsafe_attr_method_tag.compat.c b/tests/expectations/impl_unsafe_attr_method_tag.compat.c index 16a8962a..40e53fa8 100644 --- a/tests/expectations/impl_unsafe_attr_method_tag.compat.c +++ b/tests/expectations/impl_unsafe_attr_method_tag.compat.c @@ -13,6 +13,8 @@ extern "C" { struct DummyStruct new_dummy(void); +struct DummyStruct new_dummy_param(int32_t dummy_field); + #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method_tag.pyx b/tests/expectations/impl_unsafe_attr_method_tag.pyx index 2ef4bd85..23c9f172 100644 --- a/tests/expectations/impl_unsafe_attr_method_tag.pyx +++ b/tests/expectations/impl_unsafe_attr_method_tag.pyx @@ -10,3 +10,5 @@ cdef extern from *: int32_t dummy_field; DummyStruct new_dummy(); + + DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/rust/impl_unsafe_attr_method.rs b/tests/rust/impl_unsafe_attr_method.rs index 4ab7e8c0..4f604bfb 100644 --- a/tests/rust/impl_unsafe_attr_method.rs +++ b/tests/rust/impl_unsafe_attr_method.rs @@ -11,4 +11,11 @@ impl DummyStruct { dummy_field: 0, } } + + #[unsafe(no_mangle)] + pub extern "C" fn new_dummy_param(dummy_field: i32) -> Self { + Self { + dummy_field, + } + } }