Skip to content

Commit 245c52e

Browse files
committed
make full field retagging the default
1 parent f4754ed commit 245c52e

File tree

9 files changed

+50
-34
lines changed

9 files changed

+50
-34
lines changed

src/tools/miri/README.md

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -407,15 +407,11 @@ to Miri failing to detect cases of undefined behavior in a program.
407407
application instead of raising an error within the context of Miri (and halting
408408
execution). Note that code might not expect these operations to ever panic, so
409409
this flag can lead to strange (mis)behavior.
410-
* `-Zmiri-retag-fields` changes Stacked Borrows retagging to recurse into *all* fields.
411-
This means that references in fields of structs/enums/tuples/arrays/... are retagged,
412-
and in particular, they are protected when passed as function arguments.
413-
(The default is to recurse only in cases where rustc would actually emit a `noalias` attribute.)
414-
* `-Zmiri-retag-fields=<all|none|scalar>` controls when Stacked Borrows retagging recurses into
415-
fields. `all` means it always recurses (like `-Zmiri-retag-fields`), `none` means it never
416-
recurses, `scalar` (the default) means it only recurses for types where we would also emit
417-
`noalias` annotations in the generated LLVM IR (types passed as individual scalars or pairs of
418-
scalars). Setting this to `none` is **unsound**.
410+
* `-Zmiri-retag-fields[=<all|none|scalar>]` controls when Stacked Borrows retagging recurses into
411+
fields. `all` means it always recurses (the default, and equivalent to `-Zmiri-retag-fields`
412+
without an explicit value), `none` means it never recurses, `scalar` means it only recurses for
413+
types where we would also emit `noalias` annotations in the generated LLVM IR (types passed as
414+
individual scalars or pairs of scalars). Setting this to `none` is **unsound**.
419415
* `-Zmiri-tag-gc=<blocks>` configures how often the pointer tag garbage collector runs. The default
420416
is to search for and remove unreachable tags once every `10000` basic blocks. Setting this to
421417
`0` disables the garbage collector, which causes some programs to have explosive memory usage

src/tools/miri/src/eval.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ impl Default for MiriConfig {
183183
mute_stdout_stderr: false,
184184
preemption_rate: 0.01, // 1%
185185
report_progress: None,
186-
retag_fields: RetagFields::OnlyScalar,
186+
retag_fields: RetagFields::Yes,
187187
external_so_file: None,
188188
gc_interval: 10_000,
189189
num_cpus: 1,

src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ mod safe {
1414
from_raw_parts_mut(ptr, len - mid), // BUG: should be "mid" instead of "len - mid"
1515
from_raw_parts_mut(ptr.offset(mid as isize), len - mid),
1616
)
17+
//~[stack]^^^^ ERROR: /retag .* tag does not exist in the borrow stack/
1718
}
1819
}
1920
}
2021

2122
fn main() {
2223
let mut array = [1, 2, 3, 4];
2324
let (a, b) = safe::split_at_mut(&mut array, 0);
24-
//~[stack]^ ERROR: /retag .* tag does not exist in the borrow stack/
2525
a[1] = 5;
2626
b[1] = 6;
2727
//~[tree]^ ERROR: /write access through .* is forbidden/

src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.stack.stderr

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
error: Undefined Behavior: trying to retag from <TAG> for Unique permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location
22
--> $DIR/buggy_split_at_mut.rs:LL:CC
33
|
4-
LL | let (a, b) = safe::split_at_mut(&mut array, 0);
5-
| ^
6-
| |
7-
| trying to retag from <TAG> for Unique permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location
8-
| this error occurs as part of retag at ALLOC[0x0..0x10]
4+
LL | / (
5+
LL | | from_raw_parts_mut(ptr, len - mid), // BUG: should be "mid" instead of "len - mid"
6+
LL | | from_raw_parts_mut(ptr.offset(mid as isize), len - mid),
7+
LL | | )
8+
| | ^
9+
| | |
10+
| |_____________trying to retag from <TAG> for Unique permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location
11+
| this error occurs as part of retag at ALLOC[0x0..0x10]
912
|
1013
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
1114
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
@@ -20,7 +23,12 @@ help: <TAG> was later invalidated at offsets [0x0..0x10] by a Unique retag
2023
LL | from_raw_parts_mut(ptr.offset(mid as isize), len - mid),
2124
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2225
= note: BACKTRACE (of the first span):
23-
= note: inside `main` at $DIR/buggy_split_at_mut.rs:LL:CC
26+
= note: inside `safe::split_at_mut::<i32>` at $DIR/buggy_split_at_mut.rs:LL:CC
27+
note: inside `main`
28+
--> $DIR/buggy_split_at_mut.rs:LL:CC
29+
|
30+
LL | let (a, b) = safe::split_at_mut(&mut array, 0);
31+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2432

2533
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
2634

src/tools/miri/tests/fail/generator-pinned-moved.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//@compile-flags: -Zmiri-disable-validation
1+
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
22
#![feature(generators, generator_trait)]
33

44
use std::{
@@ -10,9 +10,10 @@ fn firstn() -> impl Generator<Yield = u64, Return = ()> {
1010
static move || {
1111
let mut num = 0;
1212
let num = &mut num;
13+
*num += 0;
1314

1415
yield *num;
15-
*num += 1; //~ ERROR: dereferenced after this allocation got freed
16+
*num += 1; //~ERROR: dereferenced after this allocation got freed
1617
}
1718
}
1819

src/tools/miri/tests/pass/generator.rs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::ptr;
1313
use std::sync::atomic::{AtomicUsize, Ordering};
1414

1515
fn basic() {
16-
fn finish<T>(mut amt: usize, mut t: T) -> T::Return
16+
fn finish<T>(mut amt: usize, self_referential: bool, mut t: T) -> T::Return
1717
where
1818
T: Generator<Yield = usize>,
1919
{
@@ -22,7 +22,10 @@ fn basic() {
2222
loop {
2323
let state = t.as_mut().resume(());
2424
// Test if the generator is valid (according to type invariants).
25-
let _ = unsafe { ManuallyDrop::new(ptr::read(t.as_mut().get_unchecked_mut())) };
25+
// For self-referential generators however this is UB!
26+
if !self_referential {
27+
let _ = unsafe { ManuallyDrop::new(ptr::read(t.as_mut().get_unchecked_mut())) };
28+
}
2629
match state {
2730
GeneratorState::Yielded(y) => {
2831
amt -= y;
@@ -40,9 +43,9 @@ fn basic() {
4043
panic!()
4144
}
4245

43-
finish(1, || yield 1);
46+
finish(1, false, || yield 1);
4447

45-
finish(3, || {
48+
finish(3, false, || {
4649
let mut x = 0;
4750
yield 1;
4851
x += 1;
@@ -52,27 +55,27 @@ fn basic() {
5255
assert_eq!(x, 2);
5356
});
5457

55-
finish(7 * 8 / 2, || {
58+
finish(7 * 8 / 2, false, || {
5659
for i in 0..8 {
5760
yield i;
5861
}
5962
});
6063

61-
finish(1, || {
64+
finish(1, false, || {
6265
if true {
6366
yield 1;
6467
} else {
6568
}
6669
});
6770

68-
finish(1, || {
71+
finish(1, false, || {
6972
if false {
7073
} else {
7174
yield 1;
7275
}
7376
});
7477

75-
finish(2, || {
78+
finish(2, false, || {
7679
if {
7780
yield 1;
7881
false
@@ -83,9 +86,20 @@ fn basic() {
8386
yield 1;
8487
});
8588

86-
// also test a self-referential generator
89+
// also test self-referential generators
90+
assert_eq!(
91+
finish(5, true, static || {
92+
let mut x = 5;
93+
let y = &mut x;
94+
*y = 5;
95+
yield *y;
96+
*y = 10;
97+
x
98+
}),
99+
10
100+
);
87101
assert_eq!(
88-
finish(5, || {
102+
finish(5, true, || {
89103
let mut x = Box::new(5);
90104
let y = &mut *x;
91105
*y = 5;
@@ -97,7 +111,7 @@ fn basic() {
97111
);
98112

99113
let b = true;
100-
finish(1, || {
114+
finish(1, false, || {
101115
yield 1;
102116
if b {
103117
return;
@@ -109,7 +123,7 @@ fn basic() {
109123
drop(x);
110124
});
111125

112-
finish(3, || {
126+
finish(3, false, || {
113127
yield 1;
114128
#[allow(unreachable_code)]
115129
let _x: (String, !) = (String::new(), {

src/tools/miri/tests/pass/stacked-borrows/interior_mutability.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//@compile-flags: -Zmiri-retag-fields
21
use std::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell};
32
use std::mem::{self, MaybeUninit};
43

src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//@compile-flags: -Zmiri-retag-fields
21
#![feature(allocator_api)]
32
use std::ptr;
43

src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//@compile-flags: -Zmiri-retag-fields
21
// Checks that the test does not run forever (which relies on a fast path).
32

43
#![allow(dropping_copy_types)]

0 commit comments

Comments
 (0)