Skip to content

Commit

Permalink
Avoid Box invalidation, for tag-raw-pointers
Browse files Browse the repository at this point in the history
It looks like the only outstanding issue aliasing issue in this repo
(with raw pointer tagging) was this one move of a Box after saving a
pointer to the allocation that the Box guards. This is UB according to
the Stacked Borrows with raw pointer tagging in combination with the way
rustc applies noalias to Box. As is often the case, the resolution here
is to convert the Box down to a raw pointer before a pointer into the
allocation is created.
  • Loading branch information
saethlin committed Apr 29, 2022
1 parent ff84ce0 commit 95f242c
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 9 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Expand Up @@ -113,6 +113,8 @@ jobs:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@miri
- run: cargo miri test --all-features
env:
MIRIFLAGS: '-Zmiri-tag-raw-pointers'

clippy:
name: Clippy
Expand Down
18 changes: 9 additions & 9 deletions src/buffer.rs
Expand Up @@ -88,25 +88,25 @@ impl TokenBuffer {
// length of the backing buffer. The backing buffer must remain at a
// constant address after this point, as we are going to store a raw
// pointer into it.
let mut entries = entries.into_boxed_slice();
let entries = entries.into_boxed_slice();
let len = entries.len();
// Convert our boxed slice into a pointer to the first element early,
// to avoid invalidating pointers into this slice when we move the Box
// see https://github.com/rust-lang/unsafe-code-guidelines/issues/326
let entries = Box::into_raw(entries) as *mut Entry;
for (idx, group) in groups {
// We know that this index refers to one of the temporary
// `End(null)` entries, and we know that the last entry is
// `End(up)`, so the next index is also valid.
let group_up = unsafe { entries.as_ptr().add(idx + 1) };
let group_up = unsafe { entries.add(idx + 1) };

// The end entry stored at the end of this Entry::Group should
// point to the Entry which follows the Group in the list.
let inner = Self::inner_new(group.stream(), group_up);
entries[idx] = Entry::Group(group, inner);
unsafe { *entries.add(idx) = Entry::Group(group, inner) };
}

let len = entries.len();
let ptr = Box::into_raw(entries);
TokenBuffer {
ptr: ptr as *const Entry,
len,
}
TokenBuffer { ptr: entries, len }
}

/// Creates a `TokenBuffer` containing all the tokens from the input
Expand Down

0 comments on commit 95f242c

Please sign in to comment.