Skip to content

Commit

Permalink
Merge pull request #73 from stphnt/windows-access-violation-regressio…
Browse files Browse the repository at this point in the history
…n-tests

Add regression tests for issue #67
  • Loading branch information
dtolnay authored Oct 7, 2023
2 parents ebafc8b + 3f26bdf commit 9d6d5a8
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
28 changes: 28 additions & 0 deletions tests/win_status_access_violation.rs
Original file line number Diff line number Diff line change
@@ -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());
}
}
39 changes: 39 additions & 0 deletions tests/win_status_illegal_instruction.rs
Original file line number Diff line number Diff line change
@@ -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::<Item>());
}
last_address = Some(address);
println!("{} {:?}", item.len(), item.name);

// Should not cause STATUS_ILLEGAL_INSTRUCTION
assert_eq!(item.len(), 5);
}
}

0 comments on commit 9d6d5a8

Please sign in to comment.