Skip to content

Commit 5f25162

Browse files
committed
Auto merge of #3292 - rust-lang:rustup-2024-02-08, r=saethlin
Automatic Rustup
2 parents cf71352 + c5c1621 commit 5f25162

13 files changed

+87
-24
lines changed

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
f3b9d47a46c6d237665801155aa3e26c5f49958b
1+
384b02c0825cefa59f2e8a99a33d9a5344959079

src/borrow_tracker/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
382382
// will never cause UB on the pointer itself.
383383
let (_, _, kind) = this.get_alloc_info(*alloc_id);
384384
if matches!(kind, AllocKind::LiveData) {
385-
let alloc_extra = this.get_alloc_extra(*alloc_id).unwrap();
385+
let alloc_extra = this.get_alloc_extra(*alloc_id)?; // can still fail for `extern static`
386386
let alloc_borrow_tracker = &alloc_extra.borrow_tracker.as_ref().unwrap();
387387
alloc_borrow_tracker.release_protector(&this.machine, borrow_tracker, *tag)?;
388388
}

src/machine.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! `Machine` trait.
33
44
use std::borrow::Cow;
5-
use std::cell::{Cell, RefCell};
5+
use std::cell::RefCell;
66
use std::collections::hash_map::Entry;
77
use std::fmt;
88
use std::path::Path;
@@ -336,20 +336,11 @@ pub struct AllocExtra<'tcx> {
336336
/// if this allocation is leakable. The backtrace is not
337337
/// pruned yet; that should be done before printing it.
338338
pub backtrace: Option<Vec<FrameInfo<'tcx>>>,
339-
/// An offset inside this allocation that was deemed aligned even for symbolic alignment checks.
340-
/// Invariant: the promised alignment will never be less than the native alignment of this allocation.
341-
pub symbolic_alignment: Cell<Option<(Size, Align)>>,
342339
}
343340

344341
impl VisitProvenance for AllocExtra<'_> {
345342
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
346-
let AllocExtra {
347-
borrow_tracker,
348-
data_race,
349-
weak_memory,
350-
backtrace: _,
351-
symbolic_alignment: _,
352-
} = self;
343+
let AllocExtra { borrow_tracker, data_race, weak_memory, backtrace: _ } = self;
353344

354345
borrow_tracker.visit_provenance(visit);
355346
data_race.visit_provenance(visit);
@@ -572,6 +563,14 @@ pub struct MiriMachine<'mir, 'tcx> {
572563
/// that is fixed per stack frame; this lets us have sometimes different results for the
573564
/// same const while ensuring consistent results within a single call.
574565
const_cache: RefCell<FxHashMap<(mir::Const<'tcx>, usize), OpTy<'tcx, Provenance>>>,
566+
567+
/// For each allocation, an offset inside that allocation that was deemed aligned even for
568+
/// symbolic alignment checks. This cannot be stored in `AllocExtra` since it needs to be
569+
/// tracked for vtables and function allocations as well as regular allocations.
570+
///
571+
/// Invariant: the promised alignment will never be less than the native alignment of the
572+
/// allocation.
573+
pub(crate) symbolic_alignment: RefCell<FxHashMap<AllocId, (Size, Align)>>,
575574
}
576575

577576
impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
@@ -698,6 +697,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
698697
collect_leak_backtraces: config.collect_leak_backtraces,
699698
allocation_spans: RefCell::new(FxHashMap::default()),
700699
const_cache: RefCell::new(FxHashMap::default()),
700+
symbolic_alignment: RefCell::new(FxHashMap::default()),
701701
}
702702
}
703703

@@ -810,6 +810,7 @@ impl VisitProvenance for MiriMachine<'_, '_> {
810810
collect_leak_backtraces: _,
811811
allocation_spans: _,
812812
const_cache: _,
813+
symbolic_alignment: _,
813814
} = self;
814815

815816
threads.visit_provenance(visit);
@@ -893,9 +894,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
893894
return None;
894895
}
895896
// Let's see which alignment we have been promised for this allocation.
896-
let alloc_info = ecx.get_alloc_extra(alloc_id).unwrap(); // cannot fail since the allocation is live
897-
let (promised_offset, promised_align) =
898-
alloc_info.symbolic_alignment.get().unwrap_or((Size::ZERO, alloc_align));
897+
let (promised_offset, promised_align) = ecx
898+
.machine
899+
.symbolic_alignment
900+
.borrow()
901+
.get(&alloc_id)
902+
.copied()
903+
.unwrap_or((Size::ZERO, alloc_align));
899904
if promised_align < align {
900905
// Definitely not enough.
901906
Some(Misalignment { has: promised_align, required: align })
@@ -1132,7 +1137,6 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
11321137
data_race: race_alloc,
11331138
weak_memory: buffer_alloc,
11341139
backtrace,
1135-
symbolic_alignment: Cell::new(None),
11361140
},
11371141
|ptr| ecx.global_base_pointer(ptr),
11381142
)?;

src/provenance_gc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
196196
let this = self.eval_context_mut();
197197
let allocs = LiveAllocs { ecx: this, collected: allocs };
198198
this.machine.allocation_spans.borrow_mut().retain(|id, _| allocs.is_live(*id));
199+
this.machine.symbolic_alignment.borrow_mut().retain(|id, _| allocs.is_live(*id));
199200
this.machine.intptrcast.borrow_mut().remove_unreachable_allocs(&allocs);
200201
if let Some(borrow_tracker) = &this.machine.borrow_tracker {
201202
borrow_tracker.borrow_mut().remove_unreachable_allocs(&allocs);

src/shims/foreign_items.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -583,17 +583,17 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
583583
}
584584
if let Ok((alloc_id, offset, ..)) = this.ptr_try_get_alloc_id(ptr) {
585585
let (_size, alloc_align, _kind) = this.get_alloc_info(alloc_id);
586-
// Not `get_alloc_extra_mut`, need to handle read-only allocations!
587-
let alloc_extra = this.get_alloc_extra(alloc_id)?;
588586
// If the newly promised alignment is bigger than the native alignment of this
589587
// allocation, and bigger than the previously promised alignment, then set it.
590588
if align > alloc_align
591-
&& !alloc_extra
589+
&& !this
590+
.machine
592591
.symbolic_alignment
593-
.get()
594-
.is_some_and(|(_, old_align)| align <= old_align)
592+
.get_mut()
593+
.get(&alloc_id)
594+
.is_some_and(|&(_, old_align)| align <= old_align)
595595
{
596-
alloc_extra.symbolic_alignment.set(Some((offset, align)));
596+
this.machine.symbolic_alignment.get_mut().insert(alloc_id, (offset, align));
597597
}
598598
}
599599
}

tests/fail/dyn-call-trait-mismatch.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
trait T1 {
2+
#[allow(dead_code)]
23
fn method1(self: Box<Self>);
34
}
45
trait T2 {

tests/fail/dyn-upcast-trait-mismatch.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,36 @@
22
#![allow(incomplete_features)]
33

44
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
5+
#[allow(dead_code)]
56
fn a(&self) -> i32 {
67
10
78
}
89

10+
#[allow(dead_code)]
911
fn z(&self) -> i32 {
1012
11
1113
}
1214

15+
#[allow(dead_code)]
1316
fn y(&self) -> i32 {
1417
12
1518
}
1619
}
1720

1821
trait Bar: Foo {
22+
#[allow(dead_code)]
1923
fn b(&self) -> i32 {
2024
20
2125
}
2226

27+
#[allow(dead_code)]
2328
fn w(&self) -> i32 {
2429
21
2530
}
2631
}
2732

2833
trait Baz: Bar {
34+
#[allow(dead_code)]
2935
fn c(&self) -> i32 {
3036
30
3137
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//@compile-flags: -Zmiri-symbolic-alignment-check
2+
3+
extern "C" {
4+
static _dispatch_queue_attr_concurrent: [u8; 0];
5+
}
6+
7+
static DISPATCH_QUEUE_CONCURRENT: &'static [u8; 0] = unsafe { &_dispatch_queue_attr_concurrent };
8+
9+
fn main() {
10+
let _val = *DISPATCH_QUEUE_CONCURRENT; //~ERROR: is not supported
11+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: unsupported operation: `extern` static `_dispatch_queue_attr_concurrent` from crate `issue_miri_3288_ice_symbolic_alignment_extern_static` is not supported by Miri
2+
--> $DIR/issue-miri-3288-ice-symbolic-alignment-extern-static.rs:LL:CC
3+
|
4+
LL | let _val = *DISPATCH_QUEUE_CONCURRENT;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ `extern` static `_dispatch_queue_attr_concurrent` from crate `issue_miri_3288_ice_symbolic_alignment_extern_static` is not supported by Miri
6+
|
7+
= help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
8+
= note: BACKTRACE:
9+
= note: inside `main` at $DIR/issue-miri-3288-ice-symbolic-alignment-extern-static.rs:LL:CC
10+
11+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
12+
13+
error: aborting due to 1 previous error
14+

tests/pass/align_offset_symbolic.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//@compile-flags: -Zmiri-symbolic-alignment-check
22
#![feature(strict_provenance)]
33

4+
use std::mem;
5+
46
fn test_align_to() {
57
const N: usize = 4;
68
let d = Box::new([0u32; N]);
@@ -68,7 +70,7 @@ fn test_u64_array() {
6870
#[repr(align(8))]
6971
struct AlignToU64<T>(T);
7072

71-
const BYTE_LEN: usize = std::mem::size_of::<[u64; 4]>();
73+
const BYTE_LEN: usize = mem::size_of::<[u64; 4]>();
7274
type Data = AlignToU64<[u8; BYTE_LEN]>;
7375

7476
fn example(data: &Data) {
@@ -101,10 +103,29 @@ fn huge_align() {
101103
let _ = std::ptr::invalid::<HugeSize>(SIZE).align_offset(SIZE);
102104
}
103105

106+
// This shows that we cannot store the promised alignment info in `AllocExtra`,
107+
// since vtables do not have an `AllocExtra`.
108+
fn vtable() {
109+
#[cfg(target_pointer_width = "64")]
110+
type TWOPTR = u128;
111+
#[cfg(target_pointer_width = "32")]
112+
type TWOPTR = u64;
113+
114+
let ptr: &dyn Send = &0;
115+
let parts: (*const (), *const u8) = unsafe { mem::transmute(ptr) };
116+
let vtable = parts.1;
117+
let offset = vtable.align_offset(mem::align_of::<TWOPTR>());
118+
let _vtable_aligned = vtable.wrapping_add(offset) as *const [TWOPTR; 0];
119+
// FIXME: we can't actually do the access since vtable pointers act like zero-sized allocations.
120+
// Enable the next line once https://github.com/rust-lang/rust/issues/117945 is implemented.
121+
//let _place = unsafe { &*vtable_aligned };
122+
}
123+
104124
fn main() {
105125
test_align_to();
106126
test_from_utf8();
107127
test_u64_array();
108128
test_cstr();
109129
huge_align();
130+
vtable();
110131
}

tests/pass/cast-rfc0401-vtable-kinds.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ trait Foo<T> {
99
}
1010
}
1111

12+
#[allow(dead_code)]
1213
trait Bar {
1314
fn bar(&self) {
1415
println!("Bar!");

tests/pass/dyn-upcast.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,14 +383,17 @@ fn struct_() {
383383

384384
fn replace_vptr() {
385385
trait A {
386+
#[allow(dead_code)]
386387
fn foo_a(&self);
387388
}
388389

389390
trait B {
391+
#[allow(dead_code)]
390392
fn foo_b(&self);
391393
}
392394

393395
trait C: A + B {
396+
#[allow(dead_code)]
394397
fn foo_c(&self);
395398
}
396399

tests/pass/weak_memory/weak.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::sync::atomic::Ordering::*;
1111
use std::sync::atomic::{fence, AtomicUsize};
1212
use std::thread::spawn;
1313

14+
#[allow(dead_code)]
1415
#[derive(Copy, Clone)]
1516
struct EvilSend<T>(pub T);
1617

0 commit comments

Comments
 (0)