Skip to content

Commit

Permalink
feat: add build.rs for additional build-time checks of layout
Browse files Browse the repository at this point in the history
  • Loading branch information
nerodono committed Aug 22, 2024
1 parent 5f33267 commit 4dcc205
Showing 1 changed file with 68 additions and 0 deletions.
68 changes: 68 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use std::ptr;

#[allow(dead_code)]
struct Sample(usize);

trait SomeTrait {
fn call_me(&self) -> bool {
true
}
}

impl SomeTrait for Sample {}

fn layout_broken(what: &str) {
panic!(
concat!(
"Assumptions on layout broken, this crate relies on ",
"`unsafe code guidelines` layout specification, ",
"now layout of {:?} is broken, report about it on github"
),
what
);
}

fn test_ptr_layouts() {
// Test for dyn object
{
#[repr(C)]
struct DynObj {
data_ptr: *const u8,
vtable: *const u8,
}

let sample = Box::new(Sample(100));
let data_ptr = Box::into_raw(sample);

let trait_obj: *const dyn SomeTrait = data_ptr;
let dyn_obj_repr: DynObj = unsafe { ptr::read(ptr::addr_of!(trait_obj) as *const DynObj) };

if dyn_obj_repr.data_ptr != data_ptr as *const u8 {
layout_broken("trait objects");
}
let out = unsafe { Box::from_raw(data_ptr) };
out.call_me();
}

// Test for slice object
{
let array = [1, 2, 3];
let slice: &[u8] = &array;

#[repr(C)]
struct Slice {
data_ptr: *const u8,
size: usize,
}

let slice_repr: Slice = unsafe { ptr::read(ptr::addr_of!(slice) as *const Slice) };

if slice_repr.data_ptr != slice.as_ptr() || slice_repr.size != slice.len() {
layout_broken("slices");
}
}
}

fn main() {
test_ptr_layouts();
}

0 comments on commit 4dcc205

Please sign in to comment.