@@ -348,6 +348,32 @@ mod generated_tests {
348348 "field size job of Person" ) ;
349349 }
350350
351+ /// Make sure that the offset and size of a field in a struct/union is the same.
352+ pub fn ctest_field_size_offset_Person_favorite_color ( ) {
353+ extern "C" {
354+ fn ctest_offset_of__Person__favorite_color ( ) -> u64 ;
355+ fn ctest_size_of__Person__favorite_color ( ) -> u64 ;
356+ }
357+
358+ let uninit_ty = MaybeUninit :: < Person > :: zeroed ( ) ;
359+ let uninit_ty = uninit_ty. as_ptr ( ) ;
360+
361+ // SAFETY: we assume the field access doesn't wrap
362+ let ty_ptr = unsafe { & raw const ( * uninit_ty) . favorite_color } ;
363+ // SAFETY: we assume that all zeros is a valid bitpattern for `ty_ptr`, otherwise the
364+ // test should be skipped.
365+ let val = unsafe { ty_ptr. read_unaligned ( ) } ;
366+
367+ // SAFETY: FFI call with no preconditions
368+ let ctest_field_offset = unsafe { ctest_offset_of__Person__favorite_color ( ) } ;
369+ check_same ( offset_of ! ( Person , favorite_color) as u64 , ctest_field_offset,
370+ "field offset favorite_color of Person" ) ;
371+ // SAFETY: FFI call with no preconditions
372+ let ctest_field_size = unsafe { ctest_size_of__Person__favorite_color ( ) } ;
373+ check_same ( size_of_val ( & val) as u64 , ctest_field_size,
374+ "field size favorite_color of Person" ) ;
375+ }
376+
351377 /// Make sure that the offset and size of a field in a struct/union is the same.
352378 pub fn ctest_field_size_offset_Word_word ( ) {
353379 extern "C" {
@@ -454,6 +480,24 @@ mod generated_tests {
454480 "field type job of Person" ) ;
455481 }
456482
483+ /// Tests if the pointer to the field is the same in Rust and C.
484+ pub fn ctest_field_ptr_Person_favorite_color ( ) {
485+ extern "C" {
486+ fn ctest_field_ptr__Person__favorite_color ( a : * const Person ) -> * mut u8 ;
487+ }
488+
489+ let uninit_ty = MaybeUninit :: < Person > :: zeroed ( ) ;
490+ let ty_ptr = uninit_ty. as_ptr ( ) ;
491+ // SAFETY: We don't read `field_ptr`, only compare the pointer itself.
492+ // The assumption is made that this does not wrap the address space.
493+ let field_ptr = unsafe { & raw const ( ( * ty_ptr) . favorite_color ) } ;
494+
495+ // SAFETY: FFI call with no preconditions
496+ let ctest_field_ptr = unsafe { ctest_field_ptr__Person__favorite_color ( ty_ptr) } ;
497+ check_same ( field_ptr. cast ( ) , ctest_field_ptr,
498+ "field type favorite_color of Person" ) ;
499+ }
500+
457501 /// Tests if the pointer to the field is the same in Rust and C.
458502 pub fn ctest_field_ptr_Word_word ( ) {
459503 extern "C" {
@@ -720,7 +764,7 @@ mod generated_tests {
720764 /// if there are no fields, then everything is padding, if there are fields, then we have to
721765 /// go through each field and figure out the padding.
722766 fn roundtrip_padding__Person ( ) -> Vec < bool > {
723- if 3 == 0 {
767+ if 4 == 0 {
724768 // FIXME(ctest): What if it's an alias to a struct/union?
725769 return vec ! [ !false ; size_of:: <Person >( ) ]
726770 }
@@ -753,6 +797,13 @@ mod generated_tests {
753797 let size = size_of_val ( & val) ;
754798 let off = offset_of ! ( Person , job) ;
755799 v. push ( ( off, size) ) ;
800+
801+ let ty_ptr = unsafe { & raw const ( ( * bar) . favorite_color ) } ;
802+ let val = unsafe { ty_ptr. read_unaligned ( ) } ;
803+
804+ let size = size_of_val ( & val) ;
805+ let off = offset_of ! ( Person , favorite_color) ;
806+ v. push ( ( off, size) ) ;
756807 // This vector contains `true` if the byte is padding and `false` if the byte is not
757808 // padding. Initialize all bytes as:
758809 // - padding if we have fields, this means that only the fields will be checked
@@ -1007,11 +1058,11 @@ fn main() {
10071058// FIXME(ctest): Maybe consider running the tests in parallel, since everything is independent
10081059// and we already use atomics.
10091060fn run_all ( ) {
1010- ctest_const_cstr_A ( ) ;
1011- ctest_const_cstr_B ( ) ;
10121061 ctest_const_RED ( ) ;
10131062 ctest_const_BLUE ( ) ;
10141063 ctest_const_GREEN ( ) ;
1064+ ctest_const_cstr_A ( ) ;
1065+ ctest_const_cstr_B ( ) ;
10151066 ctest_size_align_Byte ( ) ;
10161067 ctest_size_align_gregset_t ( ) ;
10171068 ctest_size_align_Color ( ) ;
@@ -1021,11 +1072,13 @@ fn run_all() {
10211072 ctest_field_size_offset_Person_name ( ) ;
10221073 ctest_field_size_offset_Person_age ( ) ;
10231074 ctest_field_size_offset_Person_job ( ) ;
1075+ ctest_field_size_offset_Person_favorite_color ( ) ;
10241076 ctest_field_size_offset_Word_word ( ) ;
10251077 ctest_field_size_offset_Word_byte ( ) ;
10261078 ctest_field_ptr_Person_name ( ) ;
10271079 ctest_field_ptr_Person_age ( ) ;
10281080 ctest_field_ptr_Person_job ( ) ;
1081+ ctest_field_ptr_Person_favorite_color ( ) ;
10291082 ctest_field_ptr_Word_word ( ) ;
10301083 ctest_field_ptr_Word_byte ( ) ;
10311084 ctest_roundtrip_Byte ( ) ;
0 commit comments