Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added a strings.rs regression test case for potential future UB #1824

Merged
merged 1 commit into from
Jun 3, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions tests/run-pass/strings.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// compile-flags: -Zmiri-track-raw-pointers

fn empty() -> &'static str {
""
}
Expand All @@ -23,6 +25,32 @@ fn str_indexing() {
let _v = &mut x[..3]; // Test IndexMut on String.
}

fn unique_aliasing() {
// This is a regression test for the aliasing rules of a `Unique<T>` pointer.
// At the time of writing this test case, Miri does not treat `Unique<T>`
// pointers as a special case, these are treated like any other raw pointer.
// However, there are existing Github issues which may lead to `Unique<T>`
// becoming a special case through asserting unique ownership over the pointee:
// - https://github.com/rust-lang/unsafe-code-guidelines/issues/258
// - https://github.com/rust-lang/unsafe-code-guidelines/issues/262
// Below, the calls to `String::remove` and `String::insert[_str]` follow
// code paths that would trigger undefined behavior in case `Unique<T>`
// would ever assert semantic ownership over the pointee. Internally,
// these methods call `self.vec.as_ptr()` and `self.vec.as_mut_ptr()` on
// the vector of bytes that are backing the `String`. That `Vec<u8>` holds a
// `Unique<u8>` internally. The second call to `Vec::as_mut_ptr(&mut self)`
// would then invalidate the pointers derived from `Vec::as_ptr(&self)`.
// Note that as long as `Unique<T>` is treated like any other raw pointer,
// this test case should pass. It is merely here as a canary test for
// potential future undefined behavior.
let mut x = String::from("Hello");
assert_eq!(x.remove(0), 'H');
x.insert(0, 'H');
assert_eq!(x, "Hello");
x.insert_str(x.len(), ", world!");
assert_eq!(x, "Hello, world!");
}

fn main() {
assert_eq!(empty(), "");
assert_eq!(hello(), "Hello, world!");
Expand All @@ -31,4 +59,5 @@ fn main() {

fat_pointer_on_32_bit(); // Should run without crashing.
str_indexing();
unique_aliasing();
}