diff options
| author | bors <bors@rust-lang.org> | 2022-10-19 14:54:23 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-10-19 14:54:23 +0000 |
| commit | 43de83e02d50c85ccf427ca64c2a0ca2f77161ad (patch) | |
| tree | bb2c9b50e6954a833c95f6c914e0da070c379ef4 | |
| parent | 4207f9e088dd574827aa35c3273cceee712820a9 (diff) | |
| parent | e7faf046c0aca0438d948461b8a39046281248ea (diff) | |
| download | rust-43de83e02d50c85ccf427ca64c2a0ca2f77161ad.tar.gz rust-43de83e02d50c85ccf427ca64c2a0ca2f77161ad.zip | |
Auto merge of #2600 - saethlin:ice, r=RalfJung
Fix ICE when trying to GC a Stack with an unknown bottom Fixes https://github.com/rust-lang/rust/issues/103167 `@RalfJung` I prefer this approach because the whole GC system is sloppy already in order to be efficient (doesn't run often, ignores small stacks) so a bit more imprecision for a simple implementation seems worth it to me. But I'm of course willing to be convinced otherwise.
| -rw-r--r-- | src/tools/miri/src/stacked_borrows/stack.rs | 12 | ||||
| -rw-r--r-- | src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs | 21 |
2 files changed, 29 insertions, 4 deletions
diff --git a/src/tools/miri/src/stacked_borrows/stack.rs b/src/tools/miri/src/stacked_borrows/stack.rs index 07c211512f8..aa549e34c5f 100644 --- a/src/tools/miri/src/stacked_borrows/stack.rs +++ b/src/tools/miri/src/stacked_borrows/stack.rs @@ -43,10 +43,14 @@ impl Stack { pub fn retain(&mut self, tags: &FxHashSet<SbTag>) { let mut first_removed = None; - // For stacks with a known bottom, we never consider removing the bottom-most tag, because - // that is the base tag which exists whether or not there are any pointers to the - // allocation. - let mut read_idx = if self.unknown_bottom.is_some() { 0 } else { 1 }; + // We never consider removing the bottom-most tag. For stacks without an unknown + // bottom this preserves the base tag. + // Note that the algorithm below is based on considering the tag at read_idx - 1, + // so precisely considering the tag at index 0 for removal when we have an unknown + // bottom would complicate the implementation. The simplification of not considering + // it does not have a significant impact on the degree to which the GC mititages + // memory growth. + let mut read_idx = 1; let mut write_idx = read_idx; while read_idx < self.borrows.len() { let left = self.borrows[read_idx - 1]; diff --git a/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs b/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs new file mode 100644 index 00000000000..e62ee528686 --- /dev/null +++ b/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs @@ -0,0 +1,21 @@ +//@compile-flags: -Zmiri-permissive-provenance +#![feature(strict_provenance)] + +use std::ptr; + +fn main() { + let mut v = 1u8; + let ptr = &mut v as *mut u8; + + // Expose the allocation and use the exposed pointer, creating an unknown bottom + unsafe { + let p: *mut u8 = ptr::from_exposed_addr::<u8>(ptr.expose_addr()) as *mut u8; + *p = 1; + } + + // Pile on a lot of SharedReadOnly at the top of the stack + let r = &v; + for _ in 0..1024 { + let _x = &*r; + } +} |
