| //@revisions: trace notrace | |
| //@[trace] only-target: x86_64-unknown-linux-gnu i686-unknown-linux-gnu | |
| //@[trace] compile-flags: -Zmiri-native-lib-enable-tracing | |
| //@compile-flags: -Zmiri-permissive-provenance | |
| use std::ptr::NonNull; | |
| fn main() { | |
| test_access_pointer(); | |
| test_access_simple(); | |
| test_access_nested(); | |
| test_access_static(); | |
| } | |
| /// Test function that dereferences an int pointer and prints its contents from C. | |
| fn test_access_pointer() { | |
| extern "C" { | |
| fn print_pointer(ptr: *const i32); | |
| } | |
| let x = 42; | |
| unsafe { print_pointer(&x) }; | |
| } | |
| /// Test function that dereferences a simple struct pointer and accesses a field. | |
| fn test_access_simple() { | |
| #[repr(C)] | |
| struct Simple { | |
| field: i32, | |
| } | |
| extern "C" { | |
| fn access_simple(s_ptr: *const Simple) -> i32; | |
| fn access_simple2(s_ptr: NonNull<Simple>) -> i32; | |
| fn access_simple3(s_ptr: Option<NonNull<Simple>>) -> i32; | |
| } | |
| let simple = Simple { field: -42 }; | |
| assert_eq!(unsafe { access_simple(&simple) }, -42); | |
| assert_eq!(unsafe { access_simple2(NonNull::from(&simple)) }, -42); | |
| assert_eq!(unsafe { access_simple3(Some(NonNull::from(&simple))) }, -42); | |
| } | |
| /// Test function that dereferences nested struct pointers and accesses fields. | |
| fn test_access_nested() { | |
| use std::ptr::NonNull; | |
| #[derive(Debug, PartialEq, Eq)] | |
| #[repr(C)] | |
| struct Nested { | |
| value: i32, | |
| next: Option<NonNull<Nested>>, | |
| } | |
| extern "C" { | |
| fn access_nested(n_ptr: *const Nested) -> i32; | |
| } | |
| let mut nested_0 = Nested { value: 97, next: None }; | |
| let mut nested_1 = Nested { value: 98, next: NonNull::new(&mut nested_0) }; | |
| let nested_2 = Nested { value: 99, next: NonNull::new(&mut nested_1) }; | |
| assert_eq!(unsafe { access_nested(&nested_2) }, 97); | |
| } | |
| /// Test function that dereferences a static struct pointer and accesses fields. | |
| fn test_access_static() { | |
| #[repr(C)] | |
| struct Static { | |
| value: i32, | |
| recurse: &'static Static, | |
| } | |
| extern "C" { | |
| fn access_static(n_ptr: *const Static) -> i32; | |
| } | |
| static STATIC: Static = Static { value: 9001, recurse: &STATIC }; | |
| assert_eq!(unsafe { access_static(&STATIC) }, 9001); | |
| } |