diff --git a/tests/win_status_access_violation.rs b/tests/win_status_access_violation.rs new file mode 100644 index 0000000..c6ecda2 --- /dev/null +++ b/tests/win_status_access_violation.rs @@ -0,0 +1,28 @@ +use linkme::distributed_slice; + +#[distributed_slice] +static ITEMS: [&'static str] = [..]; + +#[distributed_slice(ITEMS)] +static ITEM1: &'static str = "item1"; + +/// Regression test for https://github.com/dtolnay/linkme/issues/67. +/// +/// Must be run with `--release`. +#[test] +fn win_status_access_violation() { + let mut last_address = None; + for item in ITEMS { + // Do some busy work to push the compiler into optimizing the code + // in a particularly "bad" way. This is entirely derived from + // experimentation. + let address = item as *const &str as usize; + if let Some(last) = last_address { + assert_eq!(address - last, std::mem::size_of::<&str>()); + } + last_address = Some(address); + + // Should not cause STATUS_ACCESS_VIOLATION + println!("{} {:?}", item.len(), item.as_bytes()); + } +} diff --git a/tests/win_status_illegal_instruction.rs b/tests/win_status_illegal_instruction.rs new file mode 100644 index 0000000..cbfbe2f --- /dev/null +++ b/tests/win_status_illegal_instruction.rs @@ -0,0 +1,39 @@ +use linkme::distributed_slice; +pub struct Item { + pub name: &'static str, +} + +impl Item { + #[inline(never)] + fn len(&self) -> usize { + self.name.len() + } +} + +#[distributed_slice] +static ITEMS: [Item] = [..]; + +#[distributed_slice(ITEMS)] +static ITEM1: Item = Item { name: "item1" }; + +/// Regression test for https://github.com/dtolnay/linkme/issues/67. +/// +/// Must be run with `--release`. +#[test] +fn win_status_illegal_instruction() { + let mut last_address = None; + for item in ITEMS { + // Do some busy work to push the compiler into optimizing the code + // in a particularly "bad" way. This is entirely derived from + // experimentation. + let address = item as *const Item as usize; + if let Some(last) = last_address { + assert_eq!(address - last, std::mem::size_of::()); + } + last_address = Some(address); + println!("{} {:?}", item.len(), item.name); + + // Should not cause STATUS_ILLEGAL_INSTRUCTION + assert_eq!(item.len(), 5); + } +}