diff --git a/CHANGELOG.md b/CHANGELOG.md index c8b1bf894..52ab524d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## Unreleased + +### Changed + +* `msg_send!` no longer dereferences it's first argument, which would invoke + undefined behaviour when called with a null pointer. So if you were passing + `objc_id::Id` or similar directly, you now have to manually dereference it + like this: `msg_send![&*obj, ...]`. + ## 0.2.7 ### Fixed diff --git a/src/declare.rs b/src/declare.rs index 729a650aa..d6d193a6c 100644 --- a/src/declare.rs +++ b/src/declare.rs @@ -322,8 +322,8 @@ mod tests { // Registering the custom class is in test_utils let obj = test_utils::custom_object(); unsafe { - let _: () = msg_send![obj, setFoo:13u32]; - let result: u32 = msg_send![obj, foo]; + let _: () = msg_send![&*obj, setFoo:13u32]; + let result: u32 = msg_send![&*obj, foo]; assert!(result == 13); } } diff --git a/src/macros.rs b/src/macros.rs index f0e9fabc0..1c33fd2b8 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -57,8 +57,9 @@ macro_rules! sel { /** Sends a message to an object. -The first argument can be any type that dereferences to a type that implements -`Message`, like a reference, pointer, or an `Id`. +The first argument can be any reference or pointer to a type that implements +[`Message`]. + The syntax is similar to the message syntax in Objective-C. Variadic arguments are not currently supported. @@ -81,7 +82,7 @@ macro_rules! msg_send { (super($obj:expr, $superclass:expr), $name:ident) => ({ let sel = $crate::sel!($name); let result; - match $crate::__send_super_message(&*$obj, $superclass, sel, ()) { + match $crate::__send_super_message($obj, $superclass, sel, ()) { Err(s) => panic!("{}", s), Ok(r) => result = r, } @@ -90,7 +91,7 @@ macro_rules! msg_send { (super($obj:expr, $superclass:expr), $($name:ident : $arg:expr)+) => ({ let sel = $crate::sel!($($name:)+); let result; - match $crate::__send_super_message(&*$obj, $superclass, sel, ($($arg,)*)) { + match $crate::__send_super_message($obj, $superclass, sel, ($($arg,)*)) { Err(s) => panic!("{}", s), Ok(r) => result = r, } @@ -99,7 +100,7 @@ macro_rules! msg_send { ($obj:expr, $name:ident) => ({ let sel = $crate::sel!($name); let result; - match $crate::__send_message(&*$obj, sel, ()) { + match $crate::__send_message($obj, sel, ()) { Err(s) => panic!("{}", s), Ok(r) => result = r, } @@ -108,7 +109,7 @@ macro_rules! msg_send { ($obj:expr, $($name:ident : $arg:expr)+) => ({ let sel = $crate::sel!($($name:)+); let result; - match $crate::__send_message(&*$obj, sel, ($($arg,)*)) { + match $crate::__send_message($obj, sel, ($($arg,)*)) { Err(s) => panic!("{}", s), Ok(r) => result = r, } diff --git a/src/message/mod.rs b/src/message/mod.rs index 86f80dcee..298f323dd 100644 --- a/src/message/mod.rs +++ b/src/message/mod.rs @@ -236,8 +236,8 @@ mod tests { fn test_send_message() { let obj = test_utils::custom_object(); let result: u32 = unsafe { - let _: () = msg_send![obj, setFoo:4u32]; - msg_send![obj, foo] + let _: () = msg_send![&*obj, setFoo:4u32]; + msg_send![&*obj, foo] }; assert!(result == 4); } @@ -246,7 +246,7 @@ mod tests { fn test_send_message_stret() { let obj = test_utils::custom_object(); let result: test_utils::CustomStruct = unsafe { - msg_send![obj, customStruct] + msg_send![&*obj, customStruct] }; let expected = test_utils::CustomStruct { a: 1, b:2, c: 3, d: 4 }; assert!(result == expected); @@ -277,12 +277,12 @@ mod tests { let obj = test_utils::custom_subclass_object(); let superclass = test_utils::custom_class(); unsafe { - let _: () = msg_send![obj, setFoo:4u32]; - let foo: u32 = msg_send![super(obj, superclass), foo]; + let _: () = msg_send![&*obj, setFoo:4u32]; + let foo: u32 = msg_send![super(&*obj, superclass), foo]; assert!(foo == 4); // The subclass is overriden to return foo + 2 - let foo: u32 = msg_send![obj, foo]; + let foo: u32 = msg_send![&*obj, foo]; assert!(foo == 6); } }