Skip to content

Commit 44122f9

Browse files
committed
Auto merge of #1824 - Pointerbender:strings-test, r=RalfJung
added a strings.rs regression test case for potential future UB This PR adds 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: - rust-lang/unsafe-code-guidelines#258 - rust-lang/unsafe-code-guidelines#262 In the new test case, 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.
2 parents ef99830 + 386863a commit 44122f9

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

tests/run-pass/strings.rs

+29
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// compile-flags: -Zmiri-track-raw-pointers
2+
13
fn empty() -> &'static str {
24
""
35
}
@@ -23,6 +25,32 @@ fn str_indexing() {
2325
let _v = &mut x[..3]; // Test IndexMut on String.
2426
}
2527

28+
fn unique_aliasing() {
29+
// This is a regression test for the aliasing rules of a `Unique<T>` pointer.
30+
// At the time of writing this test case, Miri does not treat `Unique<T>`
31+
// pointers as a special case, these are treated like any other raw pointer.
32+
// However, there are existing Github issues which may lead to `Unique<T>`
33+
// becoming a special case through asserting unique ownership over the pointee:
34+
// - https://github.com/rust-lang/unsafe-code-guidelines/issues/258
35+
// - https://github.com/rust-lang/unsafe-code-guidelines/issues/262
36+
// Below, the calls to `String::remove` and `String::insert[_str]` follow
37+
// code paths that would trigger undefined behavior in case `Unique<T>`
38+
// would ever assert semantic ownership over the pointee. Internally,
39+
// these methods call `self.vec.as_ptr()` and `self.vec.as_mut_ptr()` on
40+
// the vector of bytes that are backing the `String`. That `Vec<u8>` holds a
41+
// `Unique<u8>` internally. The second call to `Vec::as_mut_ptr(&mut self)`
42+
// would then invalidate the pointers derived from `Vec::as_ptr(&self)`.
43+
// Note that as long as `Unique<T>` is treated like any other raw pointer,
44+
// this test case should pass. It is merely here as a canary test for
45+
// potential future undefined behavior.
46+
let mut x = String::from("Hello");
47+
assert_eq!(x.remove(0), 'H');
48+
x.insert(0, 'H');
49+
assert_eq!(x, "Hello");
50+
x.insert_str(x.len(), ", world!");
51+
assert_eq!(x, "Hello, world!");
52+
}
53+
2654
fn main() {
2755
assert_eq!(empty(), "");
2856
assert_eq!(hello(), "Hello, world!");
@@ -31,4 +59,5 @@ fn main() {
3159

3260
fat_pointer_on_32_bit(); // Should run without crashing.
3361
str_indexing();
62+
unique_aliasing();
3463
}

0 commit comments

Comments
 (0)