Auto merge of #2403 - RalfJung:rustup, r=RalfJung

rustup
This commit is contained in:
bors 2022-07-20 20:11:10 +00:00
commit 167e5dcad3
42 changed files with 627 additions and 520 deletions

View File

@ -1 +1 @@
29c5a028b0c92aa5da6a8eb6d6585a389fcf1035
a7468c60f8dbf5feb23ad840b174d7e57113a846

View File

@ -439,11 +439,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
/// Atomic variant of read_scalar_at_offset.
fn read_scalar_at_offset_atomic(
&self,
op: &OpTy<'tcx, Tag>,
op: &OpTy<'tcx, Provenance>,
offset: u64,
layout: TyAndLayout<'tcx>,
atomic: AtomicReadOrd,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
) -> InterpResult<'tcx, ScalarMaybeUninit<Provenance>> {
let this = self.eval_context_ref();
let value_place = this.deref_operand_and_offset(op, offset, layout)?;
this.read_scalar_atomic(&value_place, atomic)
@ -452,9 +452,9 @@ fn read_scalar_at_offset_atomic(
/// Atomic variant of write_scalar_at_offset.
fn write_scalar_at_offset_atomic(
&mut self,
op: &OpTy<'tcx, Tag>,
op: &OpTy<'tcx, Provenance>,
offset: u64,
value: impl Into<ScalarMaybeUninit<Tag>>,
value: impl Into<ScalarMaybeUninit<Provenance>>,
layout: TyAndLayout<'tcx>,
atomic: AtomicWriteOrd,
) -> InterpResult<'tcx> {
@ -466,9 +466,9 @@ fn write_scalar_at_offset_atomic(
/// Perform an atomic read operation at the memory location.
fn read_scalar_atomic(
&self,
place: &MPlaceTy<'tcx, Tag>,
place: &MPlaceTy<'tcx, Provenance>,
atomic: AtomicReadOrd,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
) -> InterpResult<'tcx, ScalarMaybeUninit<Provenance>> {
let this = self.eval_context_ref();
// This will read from the last store in the modification order of this location. In case
// weak memory emulation is enabled, this may not be the store we will pick to actually read from and return.
@ -485,8 +485,8 @@ fn read_scalar_atomic(
/// Perform an atomic write operation at the memory location.
fn write_scalar_atomic(
&mut self,
val: ScalarMaybeUninit<Tag>,
dest: &MPlaceTy<'tcx, Tag>,
val: ScalarMaybeUninit<Provenance>,
dest: &MPlaceTy<'tcx, Provenance>,
atomic: AtomicWriteOrd,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
@ -504,12 +504,12 @@ fn write_scalar_atomic(
/// Perform an atomic operation on a memory location.
fn atomic_op_immediate(
&mut self,
place: &MPlaceTy<'tcx, Tag>,
rhs: &ImmTy<'tcx, Tag>,
place: &MPlaceTy<'tcx, Provenance>,
rhs: &ImmTy<'tcx, Provenance>,
op: mir::BinOp,
neg: bool,
atomic: AtomicRwOrd,
) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> {
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
let this = self.eval_context_mut();
this.validate_overlapping_atomic(place)?;
@ -535,10 +535,10 @@ fn atomic_op_immediate(
/// scalar value, the old value is returned.
fn atomic_exchange_scalar(
&mut self,
place: &MPlaceTy<'tcx, Tag>,
new: ScalarMaybeUninit<Tag>,
place: &MPlaceTy<'tcx, Provenance>,
new: ScalarMaybeUninit<Provenance>,
atomic: AtomicRwOrd,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
) -> InterpResult<'tcx, ScalarMaybeUninit<Provenance>> {
let this = self.eval_context_mut();
this.validate_overlapping_atomic(place)?;
@ -555,11 +555,11 @@ fn atomic_exchange_scalar(
/// scalar value, the old value is returned.
fn atomic_min_max_scalar(
&mut self,
place: &MPlaceTy<'tcx, Tag>,
rhs: ImmTy<'tcx, Tag>,
place: &MPlaceTy<'tcx, Provenance>,
rhs: ImmTy<'tcx, Provenance>,
min: bool,
atomic: AtomicRwOrd,
) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> {
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
let this = self.eval_context_mut();
this.validate_overlapping_atomic(place)?;
@ -595,13 +595,13 @@ fn atomic_min_max_scalar(
/// identical.
fn atomic_compare_exchange_scalar(
&mut self,
place: &MPlaceTy<'tcx, Tag>,
expect_old: &ImmTy<'tcx, Tag>,
new: ScalarMaybeUninit<Tag>,
place: &MPlaceTy<'tcx, Provenance>,
expect_old: &ImmTy<'tcx, Provenance>,
new: ScalarMaybeUninit<Provenance>,
success: AtomicRwOrd,
fail: AtomicReadOrd,
can_fail_spuriously: bool,
) -> InterpResult<'tcx, Immediate<Tag>> {
) -> InterpResult<'tcx, Immediate<Provenance>> {
use rand::Rng as _;
let this = self.eval_context_mut();
@ -651,7 +651,7 @@ fn atomic_compare_exchange_scalar(
/// associated memory-place and on the current thread.
fn validate_atomic_load(
&self,
place: &MPlaceTy<'tcx, Tag>,
place: &MPlaceTy<'tcx, Provenance>,
atomic: AtomicReadOrd,
) -> InterpResult<'tcx> {
let this = self.eval_context_ref();
@ -674,7 +674,7 @@ fn validate_atomic_load(
/// associated memory-place and on the current thread.
fn validate_atomic_store(
&mut self,
place: &MPlaceTy<'tcx, Tag>,
place: &MPlaceTy<'tcx, Provenance>,
atomic: AtomicWriteOrd,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
@ -697,7 +697,7 @@ fn validate_atomic_store(
/// at the associated memory place and on the current thread.
fn validate_atomic_rmw(
&mut self,
place: &MPlaceTy<'tcx, Tag>,
place: &MPlaceTy<'tcx, Provenance>,
atomic: AtomicRwOrd,
) -> InterpResult<'tcx> {
use AtomicRwOrd::*;
@ -1047,7 +1047,7 @@ fn allow_data_races_mut<R>(
/// Generic atomic operation implementation
fn validate_atomic_op<A: Debug + Copy>(
&self,
place: &MPlaceTy<'tcx, Tag>,
place: &MPlaceTy<'tcx, Provenance>,
atomic: A,
description: &str,
mut op: impl FnMut(

View File

@ -83,7 +83,8 @@
use rustc_data_structures::fx::FxHashMap;
use crate::{
AtomicReadOrd, AtomicRwOrd, AtomicWriteOrd, Tag, ThreadManager, VClock, VTimestamp, VectorIdx,
AtomicReadOrd, AtomicRwOrd, AtomicWriteOrd, Provenance, ThreadManager, VClock, VTimestamp,
VectorIdx,
};
use super::{
@ -127,7 +128,7 @@ struct StoreElement {
// FIXME: this means the store is either fully initialized or fully uninitialized;
// we will have to change this if we want to support atomics on
// partially initialized data.
val: ScalarMaybeUninit<Tag>,
val: ScalarMaybeUninit<Provenance>,
/// Timestamp of first loads from this store element by each thread
/// Behind a RefCell to keep load op take &self
@ -174,7 +175,7 @@ pub fn memory_accessed(&self, range: AllocRange, global: &DataRaceState) {
fn get_or_create_store_buffer<'tcx>(
&self,
range: AllocRange,
init: ScalarMaybeUninit<Tag>,
init: ScalarMaybeUninit<Provenance>,
) -> InterpResult<'tcx, Ref<'_, StoreBuffer>> {
let access_type = self.store_buffers.borrow().access_type(range);
let pos = match access_type {
@ -199,7 +200,7 @@ fn get_or_create_store_buffer<'tcx>(
fn get_or_create_store_buffer_mut<'tcx>(
&mut self,
range: AllocRange,
init: ScalarMaybeUninit<Tag>,
init: ScalarMaybeUninit<Provenance>,
) -> InterpResult<'tcx, &mut StoreBuffer> {
let buffers = self.store_buffers.get_mut();
let access_type = buffers.access_type(range);
@ -220,7 +221,7 @@ fn get_or_create_store_buffer_mut<'tcx>(
}
impl<'mir, 'tcx: 'mir> StoreBuffer {
fn new(init: ScalarMaybeUninit<Tag>) -> Self {
fn new(init: ScalarMaybeUninit<Provenance>) -> Self {
let mut buffer = VecDeque::new();
buffer.reserve(STORE_BUFFER_LIMIT);
let mut ret = Self { buffer };
@ -253,7 +254,7 @@ fn buffered_read(
is_seqcst: bool,
rng: &mut (impl rand::Rng + ?Sized),
validate: impl FnOnce() -> InterpResult<'tcx>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
) -> InterpResult<'tcx, ScalarMaybeUninit<Provenance>> {
// Having a live borrow to store_buffer while calling validate_atomic_load is fine
// because the race detector doesn't touch store_buffer
@ -278,7 +279,7 @@ fn buffered_read(
fn buffered_write(
&mut self,
val: ScalarMaybeUninit<Tag>,
val: ScalarMaybeUninit<Provenance>,
global: &DataRaceState,
thread_mgr: &ThreadManager<'_, '_>,
is_seqcst: bool,
@ -366,7 +367,7 @@ fn fetch_store<R: rand::Rng + ?Sized>(
/// ATOMIC STORE IMPL in the paper (except we don't need the location's vector clock)
fn store_impl(
&mut self,
val: ScalarMaybeUninit<Tag>,
val: ScalarMaybeUninit<Provenance>,
index: VectorIdx,
thread_clock: &VClock,
is_seqcst: bool,
@ -408,7 +409,11 @@ impl StoreElement {
/// buffer regardless of subsequent loads by the same thread; if the earliest load of another
/// thread doesn't happen before the current one, then no subsequent load by the other thread
/// can happen before the current one.
fn load_impl(&self, index: VectorIdx, clocks: &ThreadClockSet) -> ScalarMaybeUninit<Tag> {
fn load_impl(
&self,
index: VectorIdx,
clocks: &ThreadClockSet,
) -> ScalarMaybeUninit<Provenance> {
let _ = self.loads.borrow_mut().try_insert(index, clocks.clock[index]);
self.val
}
@ -421,7 +426,10 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
// If weak memory emulation is enabled, check if this atomic op imperfectly overlaps with a previous
// atomic read or write. If it does, then we require it to be ordered (non-racy) with all previous atomic
// accesses on all the bytes in range
fn validate_overlapping_atomic(&self, place: &MPlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
fn validate_overlapping_atomic(
&self,
place: &MPlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_ref();
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr)?;
if let crate::AllocExtra {
@ -448,10 +456,10 @@ fn validate_overlapping_atomic(&self, place: &MPlaceTy<'tcx, Tag>) -> InterpResu
fn buffered_atomic_rmw(
&mut self,
new_val: ScalarMaybeUninit<Tag>,
place: &MPlaceTy<'tcx, Tag>,
new_val: ScalarMaybeUninit<Provenance>,
place: &MPlaceTy<'tcx, Provenance>,
atomic: AtomicRwOrd,
init: ScalarMaybeUninit<Tag>,
init: ScalarMaybeUninit<Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr)?;
@ -474,11 +482,11 @@ fn buffered_atomic_rmw(
fn buffered_atomic_read(
&self,
place: &MPlaceTy<'tcx, Tag>,
place: &MPlaceTy<'tcx, Provenance>,
atomic: AtomicReadOrd,
latest_in_mo: ScalarMaybeUninit<Tag>,
latest_in_mo: ScalarMaybeUninit<Provenance>,
validate: impl FnOnce() -> InterpResult<'tcx>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
) -> InterpResult<'tcx, ScalarMaybeUninit<Provenance>> {
let this = self.eval_context_ref();
if let Some(global) = &this.machine.data_race {
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr)?;
@ -510,10 +518,10 @@ fn buffered_atomic_read(
fn buffered_atomic_write(
&mut self,
val: ScalarMaybeUninit<Tag>,
dest: &MPlaceTy<'tcx, Tag>,
val: ScalarMaybeUninit<Provenance>,
dest: &MPlaceTy<'tcx, Provenance>,
atomic: AtomicWriteOrd,
init: ScalarMaybeUninit<Tag>,
init: ScalarMaybeUninit<Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(dest.ptr)?;
@ -555,9 +563,9 @@ fn buffered_atomic_write(
/// to perform load_impl on the latest store element
fn perform_read_on_buffered_latest(
&self,
place: &MPlaceTy<'tcx, Tag>,
place: &MPlaceTy<'tcx, Provenance>,
atomic: AtomicReadOrd,
init: ScalarMaybeUninit<Tag>,
init: ScalarMaybeUninit<Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_ref();

View File

@ -65,7 +65,7 @@ pub enum NonHaltingDiagnostic {
CreatedPointerTag(NonZeroU64, Option<(AllocId, AllocRange)>),
/// This `Item` was popped from the borrow stack, either due to an access with the given tag or
/// a deallocation when the second argument is `None`.
PoppedPointerTag(Item, Option<(SbTagExtra, AccessKind)>),
PoppedPointerTag(Item, Option<(ProvenanceExtra, AccessKind)>),
CreatedCallId(CallId),
CreatedAlloc(AllocId, Size, Align, MemoryKind<MiriMemoryKind>),
FreedAlloc(AllocId),

View File

@ -165,7 +165,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
entry_id: DefId,
entry_type: EntryFnType,
config: &MiriConfig,
) -> InterpResult<'tcx, (InterpCx<'mir, 'tcx, Evaluator<'mir, 'tcx>>, MPlaceTy<'tcx, Tag>)> {
) -> InterpResult<'tcx, (InterpCx<'mir, 'tcx, Evaluator<'mir, 'tcx>>, MPlaceTy<'tcx, Provenance>)> {
let param_env = ty::ParamEnv::reveal_all();
let layout_cx = LayoutCx { tcx, param_env };
let mut ecx = InterpCx::new(
@ -202,7 +202,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
// Third argument (`argv`): created from `config.args`.
let argv = {
// Put each argument in memory, collect pointers.
let mut argvs = Vec::<Immediate<Tag>>::new();
let mut argvs = Vec::<Immediate<Provenance>>::new();
for arg in config.args.iter() {
// Make space for `0` terminator.
let size = u64::try_from(arg.len()).unwrap().checked_add(1).unwrap();

View File

@ -84,7 +84,7 @@ fn resolve_path(&self, path: &[&str]) -> ty::Instance<'tcx> {
/// Evaluates the scalar at the specified path. Returns Some(val)
/// if the path could be resolved, and None otherwise
fn eval_path_scalar(&self, path: &[&str]) -> InterpResult<'tcx, Scalar<Tag>> {
fn eval_path_scalar(&self, path: &[&str]) -> InterpResult<'tcx, Scalar<Provenance>> {
let this = self.eval_context_ref();
let instance = this.resolve_path(path);
let cid = GlobalId { instance, promoted: None };
@ -94,7 +94,7 @@ fn eval_path_scalar(&self, path: &[&str]) -> InterpResult<'tcx, Scalar<Tag>> {
}
/// Helper function to get a `libc` constant as a `Scalar`.
fn eval_libc(&self, name: &str) -> InterpResult<'tcx, Scalar<Tag>> {
fn eval_libc(&self, name: &str) -> InterpResult<'tcx, Scalar<Provenance>> {
self.eval_path_scalar(&["libc", name])
}
@ -105,7 +105,7 @@ fn eval_libc_i32(&self, name: &str) -> InterpResult<'tcx, i32> {
}
/// Helper function to get a `windows` constant as a `Scalar`.
fn eval_windows(&self, module: &str, name: &str) -> InterpResult<'tcx, Scalar<Tag>> {
fn eval_windows(&self, module: &str, name: &str) -> InterpResult<'tcx, Scalar<Provenance>> {
self.eval_context_ref().eval_path_scalar(&["std", "sys", "windows", module, name])
}
@ -134,9 +134,9 @@ fn windows_ty_layout(&self, name: &str) -> InterpResult<'tcx, TyAndLayout<'tcx>>
/// Project to the given *named* field of the mplace (which must be a struct or union type).
fn mplace_field_named(
&self,
mplace: &MPlaceTy<'tcx, Tag>,
mplace: &MPlaceTy<'tcx, Provenance>,
name: &str,
) -> InterpResult<'tcx, MPlaceTy<'tcx, Tag>> {
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
let this = self.eval_context_ref();
let adt = mplace.layout.ty.ty_adt_def().unwrap();
for (idx, field) in adt.non_enum_variant().fields.iter().enumerate() {
@ -150,7 +150,11 @@ fn mplace_field_named(
/// Write an int of the appropriate size to `dest`. The target type may be signed or unsigned,
/// we try to do the right thing anyway. `i128` can fit all integer types except for `u128` so
/// this method is fine for almost all integer types.
fn write_int(&mut self, i: impl Into<i128>, dest: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
fn write_int(
&mut self,
i: impl Into<i128>,
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
assert!(dest.layout.abi.is_scalar(), "write_int on non-scalar type {}", dest.layout.ty);
let val = if dest.layout.abi.is_signed() {
Scalar::from_int(i, dest.layout.size)
@ -164,7 +168,7 @@ fn write_int(&mut self, i: impl Into<i128>, dest: &PlaceTy<'tcx, Tag>) -> Interp
fn write_int_fields(
&mut self,
values: &[i128],
dest: &MPlaceTy<'tcx, Tag>,
dest: &MPlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
for (idx, &val) in values.iter().enumerate() {
@ -178,7 +182,7 @@ fn write_int_fields(
fn write_int_fields_named(
&mut self,
values: &[(&str, i128)],
dest: &MPlaceTy<'tcx, Tag>,
dest: &MPlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
for &(name, val) in values.iter() {
@ -189,24 +193,24 @@ fn write_int_fields_named(
}
/// Write a 0 of the appropriate size to `dest`.
fn write_null(&mut self, dest: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
fn write_null(&mut self, dest: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
self.write_int(0, dest)
}
/// Test if this pointer equals 0.
fn ptr_is_null(&self, ptr: Pointer<Option<Tag>>) -> InterpResult<'tcx, bool> {
fn ptr_is_null(&self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, bool> {
Ok(ptr.addr().bytes() == 0)
}
/// Get the `Place` for a local
fn local_place(&mut self, local: mir::Local) -> InterpResult<'tcx, PlaceTy<'tcx, Tag>> {
fn local_place(&mut self, local: mir::Local) -> InterpResult<'tcx, PlaceTy<'tcx, Provenance>> {
let this = self.eval_context_mut();
let place = mir::Place { local, projection: List::empty() };
this.eval_place(place)
}
/// Generate some random bytes, and write them to `dest`.
fn gen_random(&mut self, ptr: Pointer<Option<Tag>>, len: u64) -> InterpResult<'tcx> {
fn gen_random(&mut self, ptr: Pointer<Option<Provenance>>, len: u64) -> InterpResult<'tcx> {
// Some programs pass in a null pointer and a length of 0
// to their platform's random-generation function (e.g. getrandom())
// on Linux. For compatibility with these programs, we don't perform
@ -240,8 +244,8 @@ fn call_function(
&mut self,
f: ty::Instance<'tcx>,
caller_abi: Abi,
args: &[Immediate<Tag>],
dest: Option<&PlaceTy<'tcx, Tag>>,
args: &[Immediate<Provenance>],
dest: Option<&PlaceTy<'tcx, Provenance>>,
stack_pop: StackPopCleanup,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
@ -285,7 +289,7 @@ fn call_function(
/// The range is relative to `place`.
fn visit_freeze_sensitive(
&self,
place: &MPlaceTy<'tcx, Tag>,
place: &MPlaceTy<'tcx, Provenance>,
size: Size,
mut action: impl FnMut(AllocRange, bool) -> InterpResult<'tcx>,
) -> InterpResult<'tcx> {
@ -304,7 +308,7 @@ fn visit_freeze_sensitive(
let mut cur_addr = start_addr;
// Called when we detected an `UnsafeCell` at the given offset and size.
// Calls `action` and advances `cur_ptr`.
let mut unsafe_cell_action = |unsafe_cell_ptr: &Pointer<Option<Tag>>,
let mut unsafe_cell_action = |unsafe_cell_ptr: &Pointer<Option<Provenance>>,
unsafe_cell_size: Size| {
// We assume that we are given the fields in increasing offset order,
// and nothing else changes.
@ -359,7 +363,7 @@ fn visit_freeze_sensitive(
/// whether we are inside an `UnsafeCell` or not.
struct UnsafeCellVisitor<'ecx, 'mir, 'tcx, F>
where
F: FnMut(&MPlaceTy<'tcx, Tag>) -> InterpResult<'tcx>,
F: FnMut(&MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx>,
{
ecx: &'ecx MiriEvalContext<'mir, 'tcx>,
unsafe_cell_action: F,
@ -368,9 +372,9 @@ struct UnsafeCellVisitor<'ecx, 'mir, 'tcx, F>
impl<'ecx, 'mir, 'tcx: 'mir, F> ValueVisitor<'mir, 'tcx, Evaluator<'mir, 'tcx>>
for UnsafeCellVisitor<'ecx, 'mir, 'tcx, F>
where
F: FnMut(&MPlaceTy<'tcx, Tag>) -> InterpResult<'tcx>,
F: FnMut(&MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx>,
{
type V = MPlaceTy<'tcx, Tag>;
type V = MPlaceTy<'tcx, Provenance>;
#[inline(always)]
fn ecx(&self) -> &MiriEvalContext<'mir, 'tcx> {
@ -378,7 +382,7 @@ fn ecx(&self) -> &MiriEvalContext<'mir, 'tcx> {
}
// Hook to detect `UnsafeCell`.
fn visit_value(&mut self, v: &MPlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
fn visit_value(&mut self, v: &MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
trace!("UnsafeCellVisitor: {:?} {:?}", *v, v.layout.ty);
let is_unsafe_cell = match v.layout.ty.kind() {
ty::Adt(adt, _) =>
@ -421,8 +425,8 @@ fn visit_value(&mut self, v: &MPlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
// Make sure we visit aggregrates in increasing offset order.
fn visit_aggregate(
&mut self,
place: &MPlaceTy<'tcx, Tag>,
fields: impl Iterator<Item = InterpResult<'tcx, MPlaceTy<'tcx, Tag>>>,
place: &MPlaceTy<'tcx, Provenance>,
fields: impl Iterator<Item = InterpResult<'tcx, MPlaceTy<'tcx, Provenance>>>,
) -> InterpResult<'tcx> {
match place.layout.fields {
FieldsShape::Array { .. } => {
@ -432,8 +436,8 @@ fn visit_aggregate(
}
FieldsShape::Arbitrary { .. } => {
// Gather the subplaces and sort them before visiting.
let mut places =
fields.collect::<InterpResult<'tcx, Vec<MPlaceTy<'tcx, Tag>>>>()?;
let mut places = fields
.collect::<InterpResult<'tcx, Vec<MPlaceTy<'tcx, Provenance>>>>()?;
// we just compare offsets, the abs. value never matters
places.sort_by_key(|place| place.ptr.addr());
self.walk_aggregate(place, places.into_iter().map(Ok))
@ -447,7 +451,7 @@ fn visit_aggregate(
fn visit_union(
&mut self,
_v: &MPlaceTy<'tcx, Tag>,
_v: &MPlaceTy<'tcx, Provenance>,
_fields: NonZeroUsize,
) -> InterpResult<'tcx> {
bug!("we should have already handled unions in `visit_value`")
@ -511,7 +515,7 @@ fn assert_target_os_is_unix(&self, name: &str) {
/// Get last error variable as a place, lazily allocating thread-local storage for it if
/// necessary.
fn last_error_place(&mut self) -> InterpResult<'tcx, MPlaceTy<'tcx, Tag>> {
fn last_error_place(&mut self) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
let this = self.eval_context_mut();
if let Some(errno_place) = this.active_thread_ref().last_error {
Ok(errno_place)
@ -526,14 +530,14 @@ fn last_error_place(&mut self) -> InterpResult<'tcx, MPlaceTy<'tcx, Tag>> {
}
/// Sets the last error variable.
fn set_last_error(&mut self, scalar: Scalar<Tag>) -> InterpResult<'tcx> {
fn set_last_error(&mut self, scalar: Scalar<Provenance>) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let errno_place = this.last_error_place()?;
this.write_scalar(scalar, &errno_place.into())
}
/// Gets the last error variable.
fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Tag>> {
fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Provenance>> {
let this = self.eval_context_mut();
let errno_place = this.last_error_place()?;
this.read_scalar(&errno_place.into())?.check_init()
@ -541,7 +545,10 @@ fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Tag>> {
/// This function tries to produce the most similar OS error from the `std::io::ErrorKind`
/// as a platform-specific errnum.
fn io_error_to_errnum(&self, err_kind: std::io::ErrorKind) -> InterpResult<'tcx, Scalar<Tag>> {
fn io_error_to_errnum(
&self,
err_kind: std::io::ErrorKind,
) -> InterpResult<'tcx, Scalar<Provenance>> {
let this = self.eval_context_ref();
let target = &this.tcx.sess.target;
if target.families.iter().any(|f| f == "unix") {
@ -575,7 +582,10 @@ fn io_error_to_errnum(&self, err_kind: std::io::ErrorKind) -> InterpResult<'tcx,
}
/// The inverse of `io_error_to_errnum`.
fn errnum_to_io_error(&self, errnum: Scalar<Tag>) -> InterpResult<'tcx, std::io::ErrorKind> {
fn errnum_to_io_error(
&self,
errnum: Scalar<Provenance>,
) -> InterpResult<'tcx, std::io::ErrorKind> {
let this = self.eval_context_ref();
let target = &this.tcx.sess.target;
if target.families.iter().any(|f| f == "unix") {
@ -621,10 +631,10 @@ fn try_unwrap_io_result<T: From<i32>>(
/// Calculates the MPlaceTy given the offset and layout of an access on an operand
fn deref_operand_and_offset(
&self,
op: &OpTy<'tcx, Tag>,
op: &OpTy<'tcx, Provenance>,
offset: u64,
layout: TyAndLayout<'tcx>,
) -> InterpResult<'tcx, MPlaceTy<'tcx, Tag>> {
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
let this = self.eval_context_ref();
let op_place = this.deref_operand(op)?;
let offset = Size::from_bytes(offset);
@ -637,10 +647,10 @@ fn deref_operand_and_offset(
fn read_scalar_at_offset(
&self,
op: &OpTy<'tcx, Tag>,
op: &OpTy<'tcx, Provenance>,
offset: u64,
layout: TyAndLayout<'tcx>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
) -> InterpResult<'tcx, ScalarMaybeUninit<Provenance>> {
let this = self.eval_context_ref();
let value_place = this.deref_operand_and_offset(op, offset, layout)?;
this.read_scalar(&value_place.into())
@ -648,9 +658,9 @@ fn read_scalar_at_offset(
fn write_scalar_at_offset(
&mut self,
op: &OpTy<'tcx, Tag>,
op: &OpTy<'tcx, Provenance>,
offset: u64,
value: impl Into<ScalarMaybeUninit<Tag>>,
value: impl Into<ScalarMaybeUninit<Provenance>>,
layout: TyAndLayout<'tcx>,
) -> InterpResult<'tcx, ()> {
let this = self.eval_context_mut();
@ -661,7 +671,10 @@ fn write_scalar_at_offset(
/// Parse a `timespec` struct and return it as a `std::time::Duration`. It returns `None`
/// if the value in the `timespec` struct is invalid. Some libc functions will return
/// `EINVAL` in this case.
fn read_timespec(&mut self, tp: &MPlaceTy<'tcx, Tag>) -> InterpResult<'tcx, Option<Duration>> {
fn read_timespec(
&mut self,
tp: &MPlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, Option<Duration>> {
let this = self.eval_context_mut();
let seconds_place = this.mplace_field(tp, 0)?;
let seconds_scalar = this.read_scalar(&seconds_place.into())?;
@ -683,7 +696,7 @@ fn read_timespec(&mut self, tp: &MPlaceTy<'tcx, Tag>) -> InterpResult<'tcx, Opti
})
}
fn read_c_str<'a>(&'a self, ptr: Pointer<Option<Tag>>) -> InterpResult<'tcx, &'a [u8]>
fn read_c_str<'a>(&'a self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, &'a [u8]>
where
'tcx: 'a,
'mir: 'a,
@ -709,7 +722,7 @@ fn read_c_str<'a>(&'a self, ptr: Pointer<Option<Tag>>) -> InterpResult<'tcx, &'a
this.read_bytes_ptr(ptr, len)
}
fn read_wide_str(&self, mut ptr: Pointer<Option<Tag>>) -> InterpResult<'tcx, Vec<u16>> {
fn read_wide_str(&self, mut ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, Vec<u16>> {
let this = self.eval_context_ref();
let size2 = Size::from_bytes(2);
let align2 = Align::from_bytes(2).unwrap();
@ -801,17 +814,17 @@ fn check_shim<'a, const N: usize>(
abi: Abi,
exp_abi: Abi,
link_name: Symbol,
args: &'a [OpTy<'tcx, Tag>],
) -> InterpResult<'tcx, &'a [OpTy<'tcx, Tag>; N]>
args: &'a [OpTy<'tcx, Provenance>],
) -> InterpResult<'tcx, &'a [OpTy<'tcx, Provenance>; N]>
where
&'a [OpTy<'tcx, Tag>; N]: TryFrom<&'a [OpTy<'tcx, Tag>]>,
&'a [OpTy<'tcx, Provenance>; N]: TryFrom<&'a [OpTy<'tcx, Provenance>]>,
{
self.check_abi_and_shim_symbol_clash(abi, exp_abi, link_name)?;
check_arg_count(args)
}
/// Mark a machine allocation that was just created as immutable.
fn mark_immutable(&mut self, mplace: &MemPlace<Tag>) {
fn mark_immutable(&mut self, mplace: &MemPlace<Provenance>) {
let this = self.eval_context_mut();
// This got just allocated, so there definitely is a pointer here.
let provenance = mplace.ptr.into_pointer_or_addr().unwrap().provenance;
@ -866,10 +879,10 @@ fn current_span(machine: &Evaluator<'_, '_>) -> Span {
/// Check that the number of args is what we expect.
pub fn check_arg_count<'a, 'tcx, const N: usize>(
args: &'a [OpTy<'tcx, Tag>],
) -> InterpResult<'tcx, &'a [OpTy<'tcx, Tag>; N]>
args: &'a [OpTy<'tcx, Provenance>],
) -> InterpResult<'tcx, &'a [OpTy<'tcx, Provenance>; N]>
where
&'a [OpTy<'tcx, Tag>; N]: TryFrom<&'a [OpTy<'tcx, Tag>]>,
&'a [OpTy<'tcx, Provenance>; N]: TryFrom<&'a [OpTy<'tcx, Provenance>]>,
{
if let Ok(ops) = args.try_into() {
return Ok(ops);

View File

@ -109,7 +109,7 @@ pub fn expose_ptr(ecx: &mut MiriEvalContext<'mir, 'tcx>, alloc_id: AllocId, sb:
pub fn ptr_from_addr_transmute(
_ecx: &MiriEvalContext<'mir, 'tcx>,
addr: u64,
) -> Pointer<Option<Tag>> {
) -> Pointer<Option<Provenance>> {
trace!("Transmuting {:#x} to a pointer", addr);
// We consider transmuted pointers to be "invalid" (`None` provenance).
@ -119,7 +119,7 @@ pub fn ptr_from_addr_transmute(
pub fn ptr_from_addr_cast(
ecx: &MiriEvalContext<'mir, 'tcx>,
addr: u64,
) -> InterpResult<'tcx, Pointer<Option<Tag>>> {
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
trace!("Casting {:#x} to a pointer", addr);
let global_state = ecx.machine.intptrcast.borrow();
@ -146,7 +146,7 @@ pub fn ptr_from_addr_cast(
}
// This is how wildcard pointers are born.
Ok(Pointer::new(Some(Tag::Wildcard), Size::from_bytes(addr)))
Ok(Pointer::new(Some(Provenance::Wildcard), Size::from_bytes(addr)))
}
fn alloc_base_addr(ecx: &MiriEvalContext<'mir, 'tcx>, alloc_id: AllocId) -> u64 {
@ -208,11 +208,11 @@ pub fn rel_ptr_to_addr(ecx: &MiriEvalContext<'mir, 'tcx>, ptr: Pointer<AllocId>)
/// access is going.
pub fn abs_ptr_to_rel(
ecx: &MiriEvalContext<'mir, 'tcx>,
ptr: Pointer<Tag>,
ptr: Pointer<Provenance>,
) -> Option<(AllocId, Size)> {
let (tag, addr) = ptr.into_parts(); // addr is absolute (Tag provenance)
let alloc_id = if let Tag::Concrete { alloc_id, .. } = tag {
let alloc_id = if let Provenance::Concrete { alloc_id, .. } = tag {
alloc_id
} else {
// A wildcard pointer.

View File

@ -57,7 +57,7 @@
// Make all those symbols available in the same place as our own.
pub use rustc_const_eval::interpret::*;
// Resolve ambiguity.
pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy};
pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy, Provenance as _};
pub use crate::shims::dlsym::{Dlsym, EvalContextExt as _};
pub use crate::shims::env::{EnvVars, EvalContextExt as _};
@ -83,15 +83,14 @@
pub use crate::helpers::{CurrentSpan, EvalContextExt as HelpersEvalContextExt};
pub use crate::intptrcast::ProvenanceMode;
pub use crate::machine::{
AllocExtra, Evaluator, FrameData, MiriEvalContext, MiriEvalContextExt, MiriMemoryKind, Tag,
NUM_CPUS, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
AllocExtra, Evaluator, FrameData, MiriEvalContext, MiriEvalContextExt, MiriMemoryKind,
Provenance, ProvenanceExtra, NUM_CPUS, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
};
pub use crate::mono_hash_map::MonoHashMap;
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
pub use crate::range_map::RangeMap;
pub use crate::stacked_borrows::{
CallId, EvalContextExt as StackedBorEvalContextExt, Item, Permission, SbTag, SbTagExtra, Stack,
Stacks,
CallId, EvalContextExt as StackedBorEvalContextExt, Item, Permission, SbTag, Stack, Stacks,
};
pub use crate::sync::{CondvarId, EvalContextExt as SyncEvalContextExt, MutexId, RwLockId};
pub use crate::thread::{

View File

@ -126,9 +126,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
/// Pointer provenance (tag).
/// Pointer provenance.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Tag {
pub enum Provenance {
Concrete {
alloc_id: AllocId,
/// Stacked Borrows tag.
@ -137,27 +137,34 @@ pub enum Tag {
Wildcard,
}
/// The "extra" information a pointer has over a regular AllocId.
#[derive(Copy, Clone)]
pub enum ProvenanceExtra {
Concrete(SbTag),
Wildcard,
}
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(Pointer<Tag>, 24);
static_assert_size!(Pointer<Provenance>, 24);
// FIXME: this would with in 24bytes but layout optimizations are not smart enough
// #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
//static_assert_size!(Pointer<Option<Tag>>, 24);
//static_assert_size!(Pointer<Option<Provenance>>, 24);
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(ScalarMaybeUninit<Tag>, 32);
static_assert_size!(ScalarMaybeUninit<Provenance>, 32);
impl Provenance for Tag {
/// We use absolute addresses in the `offset` of a `Pointer<Tag>`.
impl interpret::Provenance for Provenance {
/// We use absolute addresses in the `offset` of a `Pointer<Provenance>`.
const OFFSET_IS_ADDR: bool = true;
/// We cannot err on partial overwrites, it happens too often in practice (due to unions).
const ERR_ON_PARTIAL_PTR_OVERWRITE: bool = false;
fn fmt(ptr: &Pointer<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let (tag, addr) = ptr.into_parts(); // address is absolute
let (prov, addr) = ptr.into_parts(); // address is absolute
write!(f, "{:#x}", addr.bytes())?;
match tag {
Tag::Concrete { alloc_id, sb } => {
match prov {
Provenance::Concrete { alloc_id, sb } => {
// Forward `alternate` flag to `alloc_id` printing.
if f.alternate() {
write!(f, "[{:#?}]", alloc_id)?;
@ -167,7 +174,7 @@ fn fmt(ptr: &Pointer<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Print Stacked Borrows tag.
write!(f, "{:?}", sb)?;
}
Tag::Wildcard => {
Provenance::Wildcard => {
write!(f, "[wildcard]")?;
}
}
@ -177,8 +184,26 @@ fn fmt(ptr: &Pointer<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fn get_alloc_id(self) -> Option<AllocId> {
match self {
Tag::Concrete { alloc_id, .. } => Some(alloc_id),
Tag::Wildcard => None,
Provenance::Concrete { alloc_id, .. } => Some(alloc_id),
Provenance::Wildcard => None,
}
}
}
impl fmt::Debug for ProvenanceExtra {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ProvenanceExtra::Concrete(pid) => write!(f, "{pid:?}"),
ProvenanceExtra::Wildcard => write!(f, "<wildcard>"),
}
}
}
impl ProvenanceExtra {
pub fn and_then<T>(self, f: impl FnOnce(SbTag) -> Option<T>) -> Option<T> {
match self {
ProvenanceExtra::Concrete(pid) => f(pid),
ProvenanceExtra::Wildcard => None,
}
}
}
@ -244,9 +269,9 @@ pub struct Evaluator<'mir, 'tcx> {
/// Program arguments (`Option` because we can only initialize them after creating the ecx).
/// These are *pointers* to argc/argv because macOS.
/// We also need the full command line as one string because of Windows.
pub(crate) argc: Option<MemPlace<Tag>>,
pub(crate) argv: Option<MemPlace<Tag>>,
pub(crate) cmd_line: Option<MemPlace<Tag>>,
pub(crate) argc: Option<MemPlace<Provenance>>,
pub(crate) argv: Option<MemPlace<Provenance>>,
pub(crate) cmd_line: Option<MemPlace<Provenance>>,
/// TLS state.
pub(crate) tls: TlsData<'tcx>,
@ -302,7 +327,7 @@ pub struct Evaluator<'mir, 'tcx> {
pub(crate) local_crates: Vec<CrateNum>,
/// Mapping extern static names to their base pointer.
extern_statics: FxHashMap<Symbol, Pointer<Tag>>,
extern_statics: FxHashMap<Symbol, Pointer<Provenance>>,
/// The random number generator used for resolving non-determinism.
/// Needs to be queried by ptr_to_int, hence needs interior mutability.
@ -403,7 +428,7 @@ pub(crate) fn late_init(
fn add_extern_static(
this: &mut MiriEvalContext<'mir, 'tcx>,
name: &str,
ptr: Pointer<Option<Tag>>,
ptr: Pointer<Option<Provenance>>,
) {
// This got just allocated, so there definitely is a pointer here.
let ptr = ptr.into_pointer_or_addr().unwrap();
@ -491,11 +516,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
type FrameExtra = FrameData<'tcx>;
type AllocExtra = AllocExtra;
type PointerTag = Tag;
type TagExtra = SbTagExtra;
type Provenance = Provenance;
type ProvenanceExtra = ProvenanceExtra;
type MemoryMap =
MonoHashMap<AllocId, (MemoryKind<MiriMemoryKind>, Allocation<Tag, Self::AllocExtra>)>;
type MemoryMap = MonoHashMap<
AllocId,
(MemoryKind<MiriMemoryKind>, Allocation<Provenance, Self::AllocExtra>),
>;
const GLOBAL_KIND: Option<MiriMemoryKind> = Some(MiriMemoryKind::Global);
@ -541,8 +568,8 @@ fn find_mir_or_eval_fn(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
instance: ty::Instance<'tcx>,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
unwind: StackPopUnwind,
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
@ -554,8 +581,8 @@ fn call_extra_fn(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
fn_val: Dlsym,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
_unwind: StackPopUnwind,
) -> InterpResult<'tcx> {
@ -566,8 +593,8 @@ fn call_extra_fn(
fn call_intrinsic(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
unwind: StackPopUnwind,
) -> InterpResult<'tcx> {
@ -592,23 +619,23 @@ fn abort(_ecx: &mut MiriEvalContext<'mir, 'tcx>, msg: String) -> InterpResult<'t
fn binary_ptr_op(
ecx: &MiriEvalContext<'mir, 'tcx>,
bin_op: mir::BinOp,
left: &ImmTy<'tcx, Tag>,
right: &ImmTy<'tcx, Tag>,
) -> InterpResult<'tcx, (Scalar<Tag>, bool, ty::Ty<'tcx>)> {
left: &ImmTy<'tcx, Provenance>,
right: &ImmTy<'tcx, Provenance>,
) -> InterpResult<'tcx, (Scalar<Provenance>, bool, ty::Ty<'tcx>)> {
ecx.binary_ptr_op(bin_op, left, right)
}
fn thread_local_static_base_pointer(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
def_id: DefId,
) -> InterpResult<'tcx, Pointer<Tag>> {
) -> InterpResult<'tcx, Pointer<Provenance>> {
ecx.get_or_create_thread_local_alloc(def_id)
}
fn extern_static_base_pointer(
ecx: &MiriEvalContext<'mir, 'tcx>,
def_id: DefId,
) -> InterpResult<'tcx, Pointer<Tag>> {
) -> InterpResult<'tcx, Pointer<Provenance>> {
let link_name = ecx.item_link_name(def_id);
if let Some(&ptr) = ecx.machine.extern_statics.get(&link_name) {
Ok(ptr)
@ -621,12 +648,12 @@ fn extern_static_base_pointer(
}
}
fn init_allocation_extra<'b>(
fn adjust_allocation<'b>(
ecx: &MiriEvalContext<'mir, 'tcx>,
id: AllocId,
alloc: Cow<'b, Allocation>,
kind: Option<MemoryKind<Self::MemoryKind>>,
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>> {
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra>>> {
let kind = kind.expect("we set our STATIC_KIND so this cannot be None");
if ecx.machine.tracked_alloc_ids.contains(&id) {
register_diagnostic(NonHaltingDiagnostic::CreatedAlloc(
@ -664,7 +691,7 @@ fn init_allocation_extra<'b>(
} else {
None
};
let alloc: Allocation<Tag, Self::AllocExtra> = alloc.convert_tag_add_extra(
let alloc: Allocation<Provenance, Self::AllocExtra> = alloc.adjust_from_tcx(
&ecx.tcx,
AllocExtra {
stacked_borrows: stacks.map(RefCell::new),
@ -676,19 +703,19 @@ fn init_allocation_extra<'b>(
Ok(Cow::Owned(alloc))
}
fn tag_alloc_base_pointer(
fn adjust_alloc_base_pointer(
ecx: &MiriEvalContext<'mir, 'tcx>,
ptr: Pointer<AllocId>,
) -> Pointer<Tag> {
) -> Pointer<Provenance> {
if cfg!(debug_assertions) {
// The machine promises to never call us on thread-local or extern statics.
let alloc_id = ptr.provenance;
match ecx.tcx.get_global_alloc(alloc_id) {
Some(GlobalAlloc::Static(def_id)) if ecx.tcx.is_thread_local_static(def_id) => {
panic!("tag_alloc_base_pointer called on thread-local static")
panic!("adjust_alloc_base_pointer called on thread-local static")
}
Some(GlobalAlloc::Static(def_id)) if ecx.tcx.is_foreign_item(def_id) => {
panic!("tag_alloc_base_pointer called on extern static")
panic!("adjust_alloc_base_pointer called on extern static")
}
_ => {}
}
@ -701,7 +728,7 @@ fn tag_alloc_base_pointer(
SbTag::default()
};
Pointer::new(
Tag::Concrete { alloc_id: ptr.provenance, sb: sb_tag },
Provenance::Concrete { alloc_id: ptr.provenance, sb: sb_tag },
Size::from_bytes(absolute_addr),
)
}
@ -710,7 +737,7 @@ fn tag_alloc_base_pointer(
fn ptr_from_addr_cast(
ecx: &MiriEvalContext<'mir, 'tcx>,
addr: u64,
) -> InterpResult<'tcx, Pointer<Option<Self::PointerTag>>> {
) -> InterpResult<'tcx, Pointer<Option<Self::Provenance>>> {
intptrcast::GlobalStateInner::ptr_from_addr_cast(ecx, addr)
}
@ -718,19 +745,19 @@ fn ptr_from_addr_cast(
fn ptr_from_addr_transmute(
ecx: &MiriEvalContext<'mir, 'tcx>,
addr: u64,
) -> Pointer<Option<Self::PointerTag>> {
) -> Pointer<Option<Self::Provenance>> {
intptrcast::GlobalStateInner::ptr_from_addr_transmute(ecx, addr)
}
fn expose_ptr(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
ptr: Pointer<Self::PointerTag>,
ptr: Pointer<Self::Provenance>,
) -> InterpResult<'tcx> {
match ptr.provenance {
Tag::Concrete { alloc_id, sb } => {
Provenance::Concrete { alloc_id, sb } => {
intptrcast::GlobalStateInner::expose_ptr(ecx, alloc_id, sb);
}
Tag::Wildcard => {
Provenance::Wildcard => {
// No need to do anything for wildcard pointers as
// their provenances have already been previously exposed.
}
@ -742,14 +769,14 @@ fn expose_ptr(
/// or a `None` with an absolute address if that conversion is not possible.
fn ptr_get_alloc(
ecx: &MiriEvalContext<'mir, 'tcx>,
ptr: Pointer<Self::PointerTag>,
) -> Option<(AllocId, Size, Self::TagExtra)> {
ptr: Pointer<Self::Provenance>,
) -> Option<(AllocId, Size, Self::ProvenanceExtra)> {
let rel = intptrcast::GlobalStateInner::abs_ptr_to_rel(ecx, ptr);
rel.map(|(alloc_id, size)| {
let sb = match ptr.provenance {
Tag::Concrete { sb, .. } => SbTagExtra::Concrete(sb),
Tag::Wildcard => SbTagExtra::Wildcard,
Provenance::Concrete { sb, .. } => ProvenanceExtra::Concrete(sb),
Provenance::Wildcard => ProvenanceExtra::Wildcard,
};
(alloc_id, size, sb)
})
@ -760,7 +787,7 @@ fn memory_read(
_tcx: TyCtxt<'tcx>,
machine: &Self,
alloc_extra: &AllocExtra,
(alloc_id, tag): (AllocId, Self::TagExtra),
(alloc_id, prov_extra): (AllocId, Self::ProvenanceExtra),
range: AllocRange,
) -> InterpResult<'tcx> {
if let Some(data_race) = &alloc_extra.data_race {
@ -774,7 +801,7 @@ fn memory_read(
if let Some(stacked_borrows) = &alloc_extra.stacked_borrows {
stacked_borrows.borrow_mut().memory_read(
alloc_id,
tag,
prov_extra,
range,
machine.stacked_borrows.as_ref().unwrap(),
machine.current_span(),
@ -792,7 +819,7 @@ fn memory_written(
_tcx: TyCtxt<'tcx>,
machine: &mut Self,
alloc_extra: &mut AllocExtra,
(alloc_id, tag): (AllocId, Self::TagExtra),
(alloc_id, prov_extra): (AllocId, Self::ProvenanceExtra),
range: AllocRange,
) -> InterpResult<'tcx> {
if let Some(data_race) = &mut alloc_extra.data_race {
@ -806,7 +833,7 @@ fn memory_written(
if let Some(stacked_borrows) = &mut alloc_extra.stacked_borrows {
stacked_borrows.get_mut().memory_written(
alloc_id,
tag,
prov_extra,
range,
machine.stacked_borrows.as_ref().unwrap(),
machine.current_span(),
@ -824,7 +851,7 @@ fn memory_deallocated(
_tcx: TyCtxt<'tcx>,
machine: &mut Self,
alloc_extra: &mut AllocExtra,
(alloc_id, tag): (AllocId, Self::TagExtra),
(alloc_id, prove_extra): (AllocId, Self::ProvenanceExtra),
range: AllocRange,
) -> InterpResult<'tcx> {
if machine.tracked_alloc_ids.contains(&alloc_id) {
@ -841,7 +868,7 @@ fn memory_deallocated(
if let Some(stacked_borrows) = &mut alloc_extra.stacked_borrows {
stacked_borrows.get_mut().memory_deallocated(
alloc_id,
tag,
prove_extra,
range,
machine.stacked_borrows.as_ref().unwrap(),
&machine.threads,
@ -855,7 +882,7 @@ fn memory_deallocated(
fn retag(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
kind: mir::RetagKind,
place: &PlaceTy<'tcx, Tag>,
place: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
if ecx.machine.stacked_borrows.is_some() { ecx.retag(kind, place) } else { Ok(()) }
}
@ -863,8 +890,8 @@ fn retag(
#[inline(always)]
fn init_frame_extra(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
frame: Frame<'mir, 'tcx, Tag>,
) -> InterpResult<'tcx, Frame<'mir, 'tcx, Tag, FrameData<'tcx>>> {
frame: Frame<'mir, 'tcx, Provenance>,
) -> InterpResult<'tcx, Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>> {
// Start recording our event before doing anything else
let timing = if let Some(profiler) = ecx.machine.profiler.as_ref() {
let fn_name = frame.instance.to_string();
@ -892,13 +919,13 @@ fn init_frame_extra(
fn stack<'a>(
ecx: &'a InterpCx<'mir, 'tcx, Self>,
) -> &'a [Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>] {
) -> &'a [Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>] {
ecx.active_thread_stack()
}
fn stack_mut<'a>(
ecx: &'a mut InterpCx<'mir, 'tcx, Self>,
) -> &'a mut Vec<Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>> {
) -> &'a mut Vec<Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>> {
ecx.active_thread_stack_mut()
}
@ -925,7 +952,7 @@ fn after_stack_push(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>
#[inline(always)]
fn after_stack_pop(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
mut frame: Frame<'mir, 'tcx, Tag, FrameData<'tcx>>,
mut frame: Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>,
unwinding: bool,
) -> InterpResult<'tcx, StackPopJump> {
let timing = frame.extra.timing.take();

View File

@ -9,18 +9,18 @@ pub trait EvalContextExt<'tcx> {
fn binary_ptr_op(
&self,
bin_op: mir::BinOp,
left: &ImmTy<'tcx, Tag>,
right: &ImmTy<'tcx, Tag>,
) -> InterpResult<'tcx, (Scalar<Tag>, bool, Ty<'tcx>)>;
left: &ImmTy<'tcx, Provenance>,
right: &ImmTy<'tcx, Provenance>,
) -> InterpResult<'tcx, (Scalar<Provenance>, bool, Ty<'tcx>)>;
}
impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
fn binary_ptr_op(
&self,
bin_op: mir::BinOp,
left: &ImmTy<'tcx, Tag>,
right: &ImmTy<'tcx, Tag>,
) -> InterpResult<'tcx, (Scalar<Tag>, bool, Ty<'tcx>)> {
left: &ImmTy<'tcx, Provenance>,
right: &ImmTy<'tcx, Provenance>,
) -> InterpResult<'tcx, (Scalar<Provenance>, bool, Ty<'tcx>)> {
use rustc_middle::mir::BinOp::*;
trace!("ptr_op: {:?} {:?} {:?}", *left, bin_op, *right);

View File

@ -11,8 +11,8 @@ fn handle_miri_backtrace_size(
&mut self,
abi: Abi,
link_name: Symbol,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let [flags] = this.check_shim(abi, Abi::Rust, link_name, args)?;
@ -31,8 +31,8 @@ fn handle_miri_get_backtrace(
&mut self,
abi: Abi,
link_name: Symbol,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let tcx = this.tcx;
@ -117,7 +117,7 @@ fn handle_miri_get_backtrace(
fn resolve_frame_pointer(
&mut self,
ptr: &OpTy<'tcx, Tag>,
ptr: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, (Instance<'tcx>, Loc, String, String)> {
let this = self.eval_context_mut();
@ -145,8 +145,8 @@ fn handle_miri_resolve_frame(
&mut self,
abi: Abi,
link_name: Symbol,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let [ptr, flags] = this.check_shim(abi, Abi::Rust, link_name, args)?;
@ -228,7 +228,7 @@ fn handle_miri_resolve_frame_names(
&mut self,
abi: Abi,
link_name: Symbol,
args: &[OpTy<'tcx, Tag>],
args: &[OpTy<'tcx, Provenance>],
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();

View File

@ -33,8 +33,8 @@ fn call_dlsym(
&mut self,
dlsym: Dlsym,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();

View File

@ -30,10 +30,10 @@ fn windows_check_buffer_size((success, len): (bool, u64)) -> u32 {
pub struct EnvVars<'tcx> {
/// Stores pointers to the environment variables. These variables must be stored as
/// null-terminated target strings (c_str or wide_str) with the `"{name}={value}"` format.
map: FxHashMap<OsString, Pointer<Option<Tag>>>,
map: FxHashMap<OsString, Pointer<Option<Provenance>>>,
/// Place where the `environ` static is stored. Lazily initialized, but then never changes.
pub(crate) environ: Option<MPlaceTy<'tcx, Tag>>,
pub(crate) environ: Option<MPlaceTy<'tcx, Provenance>>,
}
impl<'tcx> EnvVars<'tcx> {
@ -92,7 +92,7 @@ fn alloc_env_var_as_c_str<'mir, 'tcx>(
name: &OsStr,
value: &OsStr,
ecx: &mut InterpCx<'mir, 'tcx, Evaluator<'mir, 'tcx>>,
) -> InterpResult<'tcx, Pointer<Option<Tag>>> {
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let mut name_osstring = name.to_os_string();
name_osstring.push("=");
name_osstring.push(value);
@ -103,7 +103,7 @@ fn alloc_env_var_as_wide_str<'mir, 'tcx>(
name: &OsStr,
value: &OsStr,
ecx: &mut InterpCx<'mir, 'tcx, Evaluator<'mir, 'tcx>>,
) -> InterpResult<'tcx, Pointer<Option<Tag>>> {
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let mut name_osstring = name.to_os_string();
name_osstring.push("=");
name_osstring.push(value);
@ -112,7 +112,10 @@ fn alloc_env_var_as_wide_str<'mir, 'tcx>(
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn getenv(&mut self, name_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, Pointer<Option<Tag>>> {
fn getenv(
&mut self,
name_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let this = self.eval_context_mut();
this.assert_target_os_is_unix("getenv");
@ -133,9 +136,9 @@ fn getenv(&mut self, name_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, Pointer<Op
#[allow(non_snake_case)]
fn GetEnvironmentVariableW(
&mut self,
name_op: &OpTy<'tcx, Tag>, // LPCWSTR
buf_op: &OpTy<'tcx, Tag>, // LPWSTR
size_op: &OpTy<'tcx, Tag>, // DWORD
name_op: &OpTy<'tcx, Provenance>, // LPCWSTR
buf_op: &OpTy<'tcx, Provenance>, // LPWSTR
size_op: &OpTy<'tcx, Provenance>, // DWORD
) -> InterpResult<'tcx, u32> {
// ^ Returns DWORD (u32 on Windows)
@ -168,7 +171,7 @@ fn GetEnvironmentVariableW(
}
#[allow(non_snake_case)]
fn GetEnvironmentStringsW(&mut self) -> InterpResult<'tcx, Pointer<Option<Tag>>> {
fn GetEnvironmentStringsW(&mut self) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let this = self.eval_context_mut();
this.assert_target_os("windows", "GetEnvironmentStringsW");
@ -191,7 +194,7 @@ fn GetEnvironmentStringsW(&mut self) -> InterpResult<'tcx, Pointer<Option<Tag>>>
#[allow(non_snake_case)]
fn FreeEnvironmentStringsW(
&mut self,
env_block_op: &OpTy<'tcx, Tag>,
env_block_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
this.assert_target_os("windows", "FreeEnvironmentStringsW");
@ -204,8 +207,8 @@ fn FreeEnvironmentStringsW(
fn setenv(
&mut self,
name_op: &OpTy<'tcx, Tag>,
value_op: &OpTy<'tcx, Tag>,
name_op: &OpTy<'tcx, Provenance>,
value_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
this.assert_target_os_is_unix("setenv");
@ -239,8 +242,8 @@ fn setenv(
#[allow(non_snake_case)]
fn SetEnvironmentVariableW(
&mut self,
name_op: &OpTy<'tcx, Tag>, // LPCWSTR
value_op: &OpTy<'tcx, Tag>, // LPCWSTR
name_op: &OpTy<'tcx, Provenance>, // LPCWSTR
value_op: &OpTy<'tcx, Provenance>, // LPCWSTR
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
this.assert_target_os("windows", "SetEnvironmentVariableW");
@ -276,7 +279,7 @@ fn SetEnvironmentVariableW(
}
}
fn unsetenv(&mut self, name_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn unsetenv(&mut self, name_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
this.assert_target_os_is_unix("unsetenv");
@ -304,9 +307,9 @@ fn unsetenv(&mut self, name_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn getcwd(
&mut self,
buf_op: &OpTy<'tcx, Tag>,
size_op: &OpTy<'tcx, Tag>,
) -> InterpResult<'tcx, Pointer<Option<Tag>>> {
buf_op: &OpTy<'tcx, Provenance>,
size_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let this = self.eval_context_mut();
this.assert_target_os_is_unix("getcwd");
@ -337,8 +340,8 @@ fn getcwd(
#[allow(non_snake_case)]
fn GetCurrentDirectoryW(
&mut self,
size_op: &OpTy<'tcx, Tag>, // DWORD
buf_op: &OpTy<'tcx, Tag>, // LPTSTR
size_op: &OpTy<'tcx, Provenance>, // DWORD
buf_op: &OpTy<'tcx, Provenance>, // LPTSTR
) -> InterpResult<'tcx, u32> {
let this = self.eval_context_mut();
this.assert_target_os("windows", "GetCurrentDirectoryW");
@ -361,7 +364,7 @@ fn GetCurrentDirectoryW(
Ok(0)
}
fn chdir(&mut self, path_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn chdir(&mut self, path_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
this.assert_target_os_is_unix("chdir");
@ -386,7 +389,7 @@ fn chdir(&mut self, path_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
#[allow(non_snake_case)]
fn SetCurrentDirectoryW(
&mut self,
path_op: &OpTy<'tcx, Tag>, // LPCTSTR
path_op: &OpTy<'tcx, Provenance>, // LPCTSTR
) -> InterpResult<'tcx, i32> {
// ^ Returns BOOL (i32 on Windows)
@ -428,7 +431,7 @@ fn update_environ(&mut self) -> InterpResult<'tcx> {
}
// Collect all the pointers to each variable in a vector.
let mut vars: Vec<Pointer<Option<Tag>>> =
let mut vars: Vec<Pointer<Option<Provenance>>> =
this.machine.env_vars.map.values().copied().collect();
// Add the trailing null pointer.
vars.push(Pointer::null());

View File

@ -74,7 +74,7 @@ fn malloc(
size: u64,
zero_init: bool,
kind: MiriMemoryKind,
) -> InterpResult<'tcx, Pointer<Option<Tag>>> {
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let this = self.eval_context_mut();
if size == 0 {
Ok(Pointer::null())
@ -89,7 +89,11 @@ fn malloc(
}
}
fn free(&mut self, ptr: Pointer<Option<Tag>>, kind: MiriMemoryKind) -> InterpResult<'tcx> {
fn free(
&mut self,
ptr: Pointer<Option<Provenance>>,
kind: MiriMemoryKind,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
if !this.ptr_is_null(ptr)? {
this.deallocate_ptr(ptr, None, kind.into())?;
@ -99,10 +103,10 @@ fn free(&mut self, ptr: Pointer<Option<Tag>>, kind: MiriMemoryKind) -> InterpRes
fn realloc(
&mut self,
old_ptr: Pointer<Option<Tag>>,
old_ptr: Pointer<Option<Provenance>>,
new_size: u64,
kind: MiriMemoryKind,
) -> InterpResult<'tcx, Pointer<Option<Tag>>> {
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let this = self.eval_context_mut();
let new_align = this.min_align(new_size, kind);
if this.ptr_is_null(old_ptr)? {
@ -231,8 +235,8 @@ fn emulate_foreign_item(
&mut self,
def_id: DefId,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
unwind: StackPopUnwind,
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
@ -353,8 +357,8 @@ fn emulate_foreign_item_by_name(
&mut self,
link_name: Symbol,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
let this = self.eval_context_mut();

View File

@ -18,8 +18,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn emulate_atomic_intrinsic(
&mut self,
intrinsic_name: &str,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
@ -121,8 +121,8 @@ fn fence_ord<'tcx>(ord: &str) -> InterpResult<'tcx, AtomicFenceOrd> {
fn atomic_load(
&mut self,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
atomic: AtomicReadOrd,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
@ -150,7 +150,7 @@ fn atomic_load(
fn atomic_store(
&mut self,
args: &[OpTy<'tcx, Tag>],
args: &[OpTy<'tcx, Provenance>],
atomic: AtomicWriteOrd,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
@ -177,7 +177,7 @@ fn atomic_store(
fn compiler_fence(
&mut self,
args: &[OpTy<'tcx, Tag>],
args: &[OpTy<'tcx, Provenance>],
atomic: AtomicFenceOrd,
) -> InterpResult<'tcx> {
let [] = check_arg_count(args)?;
@ -188,7 +188,7 @@ fn compiler_fence(
fn atomic_fence(
&mut self,
args: &[OpTy<'tcx, Tag>],
args: &[OpTy<'tcx, Provenance>],
atomic: AtomicFenceOrd,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
@ -199,8 +199,8 @@ fn atomic_fence(
fn atomic_op(
&mut self,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
atomic_op: AtomicOp,
atomic: AtomicRwOrd,
) -> InterpResult<'tcx> {
@ -252,8 +252,8 @@ fn atomic_op(
fn atomic_exchange(
&mut self,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
atomic: AtomicRwOrd,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
@ -280,8 +280,8 @@ fn atomic_exchange(
fn atomic_compare_exchange_impl(
&mut self,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
success: AtomicRwOrd,
fail: AtomicReadOrd,
can_fail_spuriously: bool,
@ -320,8 +320,8 @@ fn atomic_compare_exchange_impl(
fn atomic_compare_exchange(
&mut self,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
success: AtomicRwOrd,
fail: AtomicReadOrd,
) -> InterpResult<'tcx> {
@ -330,8 +330,8 @@ fn atomic_compare_exchange(
fn atomic_compare_exchange_weak(
&mut self,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
success: AtomicRwOrd,
fail: AtomicReadOrd,
) -> InterpResult<'tcx> {

View File

@ -20,8 +20,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn call_intrinsic(
&mut self,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
_unwind: StackPopUnwind,
) -> InterpResult<'tcx> {
@ -58,8 +58,8 @@ fn call_intrinsic(
fn emulate_intrinsic_by_name(
&mut self,
intrinsic_name: &str,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
@ -375,9 +375,9 @@ fn float_to_int_unchecked<F>(
&self,
f: F,
dest_ty: ty::Ty<'tcx>,
) -> InterpResult<'tcx, Scalar<Tag>>
) -> InterpResult<'tcx, Scalar<Provenance>>
where
F: Float + Into<Scalar<Tag>>,
F: Float + Into<Scalar<Provenance>>,
{
let this = self.eval_context_ref();

View File

@ -12,8 +12,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn emulate_simd_intrinsic(
&mut self,
intrinsic_name: &str,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
match intrinsic_name {
@ -557,13 +557,13 @@ enum Op {
}
}
fn bool_to_simd_element(b: bool, size: Size) -> Scalar<Tag> {
fn bool_to_simd_element(b: bool, size: Size) -> Scalar<Provenance> {
// SIMD uses all-1 as pattern for "true"
let val = if b { -1 } else { 0 };
Scalar::from_int(val, size)
}
fn simd_element_to_bool(elem: ImmTy<'_, Tag>) -> InterpResult<'_, bool> {
fn simd_element_to_bool(elem: ImmTy<'_, Provenance>) -> InterpResult<'_, bool> {
let val = elem.to_scalar()?.to_int(elem.layout.size)?;
Ok(match val {
0 => false,
@ -581,9 +581,9 @@ fn simd_bitmask_index(idx: u64, vec_len: u64, endianess: Endian) -> u64 {
}
fn fmax_op<'tcx>(
left: &ImmTy<'tcx, Tag>,
right: &ImmTy<'tcx, Tag>,
) -> InterpResult<'tcx, Scalar<Tag>> {
left: &ImmTy<'tcx, Provenance>,
right: &ImmTy<'tcx, Provenance>,
) -> InterpResult<'tcx, Scalar<Provenance>> {
assert_eq!(left.layout.ty, right.layout.ty);
let ty::Float(float_ty) = left.layout.ty.kind() else {
bug!("fmax operand is not a float")
@ -597,9 +597,9 @@ fn fmax_op<'tcx>(
}
fn fmin_op<'tcx>(
left: &ImmTy<'tcx, Tag>,
right: &ImmTy<'tcx, Tag>,
) -> InterpResult<'tcx, Scalar<Tag>> {
left: &ImmTy<'tcx, Provenance>,
right: &ImmTy<'tcx, Provenance>,
) -> InterpResult<'tcx, Scalar<Provenance>> {
assert_eq!(left.layout.ty, right.layout.ty);
let ty::Float(float_ty) = left.layout.ty.kind() else {
bug!("fmin operand is not a float")

View File

@ -27,8 +27,8 @@ fn find_mir_or_eval_fn(
&mut self,
instance: ty::Instance<'tcx>,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
unwind: StackPopUnwind,
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
@ -62,9 +62,9 @@ fn find_mir_or_eval_fn(
/// the actual MIR of `align_offset`.
fn align_offset(
&mut self,
ptr_op: &OpTy<'tcx, Tag>,
align_op: &OpTy<'tcx, Tag>,
dest: &PlaceTy<'tcx, Tag>,
ptr_op: &OpTy<'tcx, Provenance>,
align_op: &OpTy<'tcx, Provenance>,
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
unwind: StackPopUnwind,
) -> InterpResult<'tcx, bool> {

View File

@ -52,7 +52,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
/// the Unix APIs usually handle.
fn read_os_str_from_c_str<'a>(
&'a self,
ptr: Pointer<Option<Tag>>,
ptr: Pointer<Option<Provenance>>,
) -> InterpResult<'tcx, &'a OsStr>
where
'tcx: 'a,
@ -67,7 +67,7 @@ fn read_os_str_from_c_str<'a>(
/// which is what the Windows APIs usually handle.
fn read_os_str_from_wide_str<'a>(
&'a self,
ptr: Pointer<Option<Tag>>,
ptr: Pointer<Option<Provenance>>,
) -> InterpResult<'tcx, OsString>
where
'tcx: 'a,
@ -96,7 +96,7 @@ pub fn u16vec_to_osstring<'tcx>(u16_vec: Vec<u16>) -> InterpResult<'tcx, OsStrin
fn write_os_str_to_c_str(
&mut self,
os_str: &OsStr,
ptr: Pointer<Option<Tag>>,
ptr: Pointer<Option<Provenance>>,
size: u64,
) -> InterpResult<'tcx, (bool, u64)> {
let bytes = os_str_to_bytes(os_str)?;
@ -119,7 +119,7 @@ fn write_os_str_to_c_str(
fn write_os_str_to_wide_str(
&mut self,
os_str: &OsStr,
ptr: Pointer<Option<Tag>>,
ptr: Pointer<Option<Provenance>>,
size: u64,
) -> InterpResult<'tcx, (bool, u64)> {
#[cfg(windows)]
@ -165,7 +165,7 @@ fn alloc_os_str_as_c_str(
&mut self,
os_str: &OsStr,
memkind: MemoryKind<MiriMemoryKind>,
) -> InterpResult<'tcx, Pointer<Option<Tag>>> {
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0` terminator.
let this = self.eval_context_mut();
@ -180,7 +180,7 @@ fn alloc_os_str_as_wide_str(
&mut self,
os_str: &OsStr,
memkind: MemoryKind<MiriMemoryKind>,
) -> InterpResult<'tcx, Pointer<Option<Tag>>> {
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0x0000` terminator.
let this = self.eval_context_mut();
@ -193,7 +193,7 @@ fn alloc_os_str_as_wide_str(
/// Read a null-terminated sequence of bytes, and perform path separator conversion if needed.
fn read_path_from_c_str<'a>(
&'a self,
ptr: Pointer<Option<Tag>>,
ptr: Pointer<Option<Provenance>>,
) -> InterpResult<'tcx, Cow<'a, Path>>
where
'tcx: 'a,
@ -209,7 +209,10 @@ fn read_path_from_c_str<'a>(
}
/// Read a null-terminated sequence of `u16`s, and perform path separator conversion if needed.
fn read_path_from_wide_str(&self, ptr: Pointer<Option<Tag>>) -> InterpResult<'tcx, PathBuf> {
fn read_path_from_wide_str(
&self,
ptr: Pointer<Option<Provenance>>,
) -> InterpResult<'tcx, PathBuf> {
let this = self.eval_context_ref();
let os_str = this.read_os_str_from_wide_str(ptr)?;
@ -224,7 +227,7 @@ fn read_path_from_wide_str(&self, ptr: Pointer<Option<Tag>>) -> InterpResult<'tc
fn write_path_to_c_str(
&mut self,
path: &Path,
ptr: Pointer<Option<Tag>>,
ptr: Pointer<Option<Provenance>>,
size: u64,
) -> InterpResult<'tcx, (bool, u64)> {
let this = self.eval_context_mut();
@ -238,7 +241,7 @@ fn write_path_to_c_str(
fn write_path_to_wide_str(
&mut self,
path: &Path,
ptr: Pointer<Option<Tag>>,
ptr: Pointer<Option<Provenance>>,
size: u64,
) -> InterpResult<'tcx, (bool, u64)> {
let this = self.eval_context_mut();

View File

@ -26,11 +26,11 @@
#[derive(Debug)]
pub struct CatchUnwindData<'tcx> {
/// The `catch_fn` callback to call in case of a panic.
catch_fn: Scalar<Tag>,
catch_fn: Scalar<Provenance>,
/// The `data` argument for that callback.
data: Scalar<Tag>,
data: Scalar<Provenance>,
/// The return place from the original call to `try`.
dest: PlaceTy<'tcx, Tag>,
dest: PlaceTy<'tcx, Provenance>,
/// The return block from the original call to `try`.
ret: mir::BasicBlock,
}
@ -43,7 +43,7 @@ fn handle_miri_start_panic(
&mut self,
abi: Abi,
link_name: Symbol,
args: &[OpTy<'tcx, Tag>],
args: &[OpTy<'tcx, Provenance>],
unwind: StackPopUnwind,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
@ -65,8 +65,8 @@ fn handle_miri_start_panic(
/// Handles the `try` intrinsic, the underlying implementation of `std::panicking::try`.
fn handle_try(
&mut self,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: mir::BasicBlock,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();

View File

@ -13,8 +13,8 @@ impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mi
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn clock_gettime(
&mut self,
clk_id_op: &OpTy<'tcx, Tag>,
tp_op: &OpTy<'tcx, Tag>,
clk_id_op: &OpTy<'tcx, Provenance>,
tp_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
// This clock support is deliberately minimal because a lot of clock types have fiddly
// properties (is it possible for Miri to be suspended independently of the host?). If you
@ -59,8 +59,8 @@ fn clock_gettime(
fn gettimeofday(
&mut self,
tv_op: &OpTy<'tcx, Tag>,
tz_op: &OpTy<'tcx, Tag>,
tv_op: &OpTy<'tcx, Provenance>,
tz_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -85,7 +85,10 @@ fn gettimeofday(
}
#[allow(non_snake_case)]
fn GetSystemTimeAsFileTime(&mut self, LPFILETIME_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx> {
fn GetSystemTimeAsFileTime(
&mut self,
LPFILETIME_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
this.assert_target_os("windows", "GetSystemTimeAsFileTime");
@ -115,7 +118,7 @@ fn GetSystemTimeAsFileTime(&mut self, LPFILETIME_op: &OpTy<'tcx, Tag>) -> Interp
#[allow(non_snake_case)]
fn QueryPerformanceCounter(
&mut self,
lpPerformanceCount_op: &OpTy<'tcx, Tag>,
lpPerformanceCount_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -138,7 +141,7 @@ fn QueryPerformanceCounter(
#[allow(non_snake_case)]
fn QueryPerformanceFrequency(
&mut self,
lpFrequency_op: &OpTy<'tcx, Tag>,
lpFrequency_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -172,7 +175,7 @@ fn mach_absolute_time(&self) -> InterpResult<'tcx, u64> {
})
}
fn mach_timebase_info(&mut self, info_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn mach_timebase_info(&mut self, info_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
this.assert_target_os("macos", "mach_timebase_info");
@ -190,8 +193,8 @@ fn mach_timebase_info(&mut self, info_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx
fn nanosleep(
&mut self,
req_op: &OpTy<'tcx, Tag>,
_rem: &OpTy<'tcx, Tag>,
req_op: &OpTy<'tcx, Provenance>,
_rem: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
// Signal handlers are not supported, so rem will never be written to.

View File

@ -19,7 +19,7 @@
pub struct TlsEntry<'tcx> {
/// The data for this key. None is used to represent NULL.
/// (We normalize this early to avoid having to do a NULL-ptr-test each time we access the data.)
data: BTreeMap<ThreadId, Scalar<Tag>>,
data: BTreeMap<ThreadId, Scalar<Provenance>>,
dtor: Option<ty::Instance<'tcx>>,
}
@ -41,7 +41,7 @@ pub struct TlsData<'tcx> {
/// A single per thread destructor of the thread local storage (that's how
/// things work on macOS) with a data argument.
macos_thread_dtors: BTreeMap<ThreadId, (ty::Instance<'tcx>, Scalar<Tag>)>,
macos_thread_dtors: BTreeMap<ThreadId, (ty::Instance<'tcx>, Scalar<Provenance>)>,
/// State for currently running TLS dtors. If this map contains a key for a
/// specific thread, it means that we are in the "destruct" phase, during
@ -94,7 +94,7 @@ pub fn load_tls(
key: TlsKey,
thread_id: ThreadId,
cx: &impl HasDataLayout,
) -> InterpResult<'tcx, Scalar<Tag>> {
) -> InterpResult<'tcx, Scalar<Provenance>> {
match self.keys.get(&key) {
Some(TlsEntry { data, .. }) => {
let value = data.get(&thread_id).copied();
@ -109,7 +109,7 @@ pub fn store_tls(
&mut self,
key: TlsKey,
thread_id: ThreadId,
new_data: Scalar<Tag>,
new_data: Scalar<Provenance>,
cx: &impl HasDataLayout,
) -> InterpResult<'tcx> {
match self.keys.get_mut(&key) {
@ -140,7 +140,7 @@ pub fn set_macos_thread_dtor(
&mut self,
thread: ThreadId,
dtor: ty::Instance<'tcx>,
data: Scalar<Tag>,
data: Scalar<Provenance>,
) -> InterpResult<'tcx> {
if self.dtors_running.contains_key(&thread) {
// UB, according to libstd docs.
@ -179,7 +179,7 @@ fn fetch_tls_dtor(
&mut self,
key: Option<TlsKey>,
thread_id: ThreadId,
) -> Option<(ty::Instance<'tcx>, Scalar<Tag>, TlsKey)> {
) -> Option<(ty::Instance<'tcx>, Scalar<Provenance>, TlsKey)> {
use std::ops::Bound::*;
let thread_local = &mut self.keys;

View File

@ -32,8 +32,8 @@ fn call_dlsym(
&mut self,
dlsym: Dlsym,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();

View File

@ -19,8 +19,8 @@ fn emulate_foreign_item_by_name(
&mut self,
link_name: Symbol,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
let this = self.eval_context_mut();

View File

@ -19,8 +19,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn call_dlsym(
&mut self,
dlsym: Dlsym,
_args: &[OpTy<'tcx, Tag>],
_dest: &PlaceTy<'tcx, Tag>,
_args: &[OpTy<'tcx, Provenance>],
_dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();

View File

@ -11,8 +11,8 @@ fn emulate_foreign_item_by_name(
&mut self,
link_name: Symbol,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
let this = self.eval_context_mut();
match link_name.as_str() {

View File

@ -386,7 +386,7 @@ trait EvalContextExtPrivate<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, '
fn macos_stat_write_buf(
&mut self,
metadata: FileMetadata,
buf_op: &OpTy<'tcx, Tag>,
buf_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -493,7 +493,7 @@ pub struct OpenDir {
/// The directory reader on the host.
read_dir: ReadDir,
/// The most recent entry returned by readdir()
entry: Pointer<Option<Tag>>,
entry: Pointer<Option<Provenance>>,
}
impl OpenDir {
@ -556,7 +556,7 @@ fn maybe_sync_file(
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn open(&mut self, args: &[OpTy<'tcx, Tag>]) -> InterpResult<'tcx, i32> {
fn open(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> {
if args.len() < 2 {
throw_ub_format!(
"incorrect number of arguments for `open`: got {}, expected at least 2",
@ -667,7 +667,7 @@ fn open(&mut self, args: &[OpTy<'tcx, Tag>]) -> InterpResult<'tcx, i32> {
this.try_unwrap_io_result(fd)
}
fn fcntl(&mut self, args: &[OpTy<'tcx, Tag>]) -> InterpResult<'tcx, i32> {
fn fcntl(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
if args.len() < 2 {
@ -741,7 +741,7 @@ fn fcntl(&mut self, args: &[OpTy<'tcx, Tag>]) -> InterpResult<'tcx, i32> {
}
}
fn close(&mut self, fd_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn close(&mut self, fd_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let fd = this.read_scalar(fd_op)?.to_i32()?;
@ -754,7 +754,12 @@ fn close(&mut self, fd_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
}
}
fn read(&mut self, fd: i32, buf: Pointer<Option<Tag>>, count: u64) -> InterpResult<'tcx, i64> {
fn read(
&mut self,
fd: i32,
buf: Pointer<Option<Provenance>>,
count: u64,
) -> InterpResult<'tcx, i64> {
let this = self.eval_context_mut();
// Isolation check is done via `FileDescriptor` trait.
@ -802,7 +807,12 @@ fn read(&mut self, fd: i32, buf: Pointer<Option<Tag>>, count: u64) -> InterpResu
}
}
fn write(&mut self, fd: i32, buf: Pointer<Option<Tag>>, count: u64) -> InterpResult<'tcx, i64> {
fn write(
&mut self,
fd: i32,
buf: Pointer<Option<Provenance>>,
count: u64,
) -> InterpResult<'tcx, i64> {
let this = self.eval_context_mut();
// Isolation check is done via `FileDescriptor` trait.
@ -832,9 +842,9 @@ fn write(&mut self, fd: i32, buf: Pointer<Option<Tag>>, count: u64) -> InterpRes
fn lseek64(
&mut self,
fd_op: &OpTy<'tcx, Tag>,
offset_op: &OpTy<'tcx, Tag>,
whence_op: &OpTy<'tcx, Tag>,
fd_op: &OpTy<'tcx, Provenance>,
offset_op: &OpTy<'tcx, Provenance>,
whence_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i64> {
let this = self.eval_context_mut();
@ -867,7 +877,7 @@ fn lseek64(
}
}
fn unlink(&mut self, path_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn unlink(&mut self, path_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let path = this.read_path_from_c_str(this.read_pointer(path_op)?)?;
@ -885,8 +895,8 @@ fn unlink(&mut self, path_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn symlink(
&mut self,
target_op: &OpTy<'tcx, Tag>,
linkpath_op: &OpTy<'tcx, Tag>,
target_op: &OpTy<'tcx, Provenance>,
linkpath_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
#[cfg(unix)]
fn create_link(src: &Path, dst: &Path) -> std::io::Result<()> {
@ -916,8 +926,8 @@ fn create_link(src: &Path, dst: &Path) -> std::io::Result<()> {
fn macos_stat(
&mut self,
path_op: &OpTy<'tcx, Tag>,
buf_op: &OpTy<'tcx, Tag>,
path_op: &OpTy<'tcx, Provenance>,
buf_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
this.assert_target_os("macos", "stat");
@ -945,8 +955,8 @@ fn macos_stat(
// `lstat` is used to get symlink metadata.
fn macos_lstat(
&mut self,
path_op: &OpTy<'tcx, Tag>,
buf_op: &OpTy<'tcx, Tag>,
path_op: &OpTy<'tcx, Provenance>,
buf_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
this.assert_target_os("macos", "lstat");
@ -972,8 +982,8 @@ fn macos_lstat(
fn macos_fstat(
&mut self,
fd_op: &OpTy<'tcx, Tag>,
buf_op: &OpTy<'tcx, Tag>,
fd_op: &OpTy<'tcx, Provenance>,
buf_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -997,11 +1007,11 @@ fn macos_fstat(
fn linux_statx(
&mut self,
dirfd_op: &OpTy<'tcx, Tag>, // Should be an `int`
pathname_op: &OpTy<'tcx, Tag>, // Should be a `const char *`
flags_op: &OpTy<'tcx, Tag>, // Should be an `int`
mask_op: &OpTy<'tcx, Tag>, // Should be an `unsigned int`
statxbuf_op: &OpTy<'tcx, Tag>, // Should be a `struct statx *`
dirfd_op: &OpTy<'tcx, Provenance>, // Should be an `int`
pathname_op: &OpTy<'tcx, Provenance>, // Should be a `const char *`
flags_op: &OpTy<'tcx, Provenance>, // Should be an `int`
mask_op: &OpTy<'tcx, Provenance>, // Should be an `unsigned int`
statxbuf_op: &OpTy<'tcx, Provenance>, // Should be a `struct statx *`
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -1188,8 +1198,8 @@ fn linux_statx(
fn rename(
&mut self,
oldpath_op: &OpTy<'tcx, Tag>,
newpath_op: &OpTy<'tcx, Tag>,
oldpath_op: &OpTy<'tcx, Provenance>,
newpath_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -1219,8 +1229,8 @@ fn rename(
fn mkdir(
&mut self,
path_op: &OpTy<'tcx, Tag>,
mode_op: &OpTy<'tcx, Tag>,
path_op: &OpTy<'tcx, Provenance>,
mode_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -1256,7 +1266,7 @@ fn mkdir(
this.try_unwrap_io_result(result)
}
fn rmdir(&mut self, path_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn rmdir(&mut self, path_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let path = this.read_path_from_c_str(this.read_pointer(path_op)?)?;
@ -1273,7 +1283,10 @@ fn rmdir(&mut self, path_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
this.try_unwrap_io_result(result)
}
fn opendir(&mut self, name_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, Scalar<Tag>> {
fn opendir(
&mut self,
name_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, Scalar<Provenance>> {
let this = self.eval_context_mut();
let name = this.read_path_from_c_str(this.read_pointer(name_op)?)?;
@ -1304,7 +1317,10 @@ fn opendir(&mut self, name_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, Scalar<Ta
}
}
fn linux_readdir64(&mut self, dirp_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, Scalar<Tag>> {
fn linux_readdir64(
&mut self,
dirp_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, Scalar<Provenance>> {
let this = self.eval_context_mut();
this.assert_target_os("linux", "readdir64");
@ -1393,9 +1409,9 @@ fn linux_readdir64(&mut self, dirp_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, S
fn macos_readdir_r(
&mut self,
dirp_op: &OpTy<'tcx, Tag>,
entry_op: &OpTy<'tcx, Tag>,
result_op: &OpTy<'tcx, Tag>,
dirp_op: &OpTy<'tcx, Provenance>,
entry_op: &OpTy<'tcx, Provenance>,
result_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -1490,7 +1506,7 @@ fn macos_readdir_r(
}
}
fn closedir(&mut self, dirp_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn closedir(&mut self, dirp_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let dirp = this.read_scalar(dirp_op)?.to_machine_usize(this)?;
@ -1513,8 +1529,8 @@ fn closedir(&mut self, dirp_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn ftruncate64(
&mut self,
fd_op: &OpTy<'tcx, Tag>,
length_op: &OpTy<'tcx, Tag>,
fd_op: &OpTy<'tcx, Provenance>,
length_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -1551,7 +1567,7 @@ fn ftruncate64(
}
}
fn fsync(&mut self, fd_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn fsync(&mut self, fd_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
// On macOS, `fsync` (unlike `fcntl(F_FULLFSYNC)`) does not wait for the
// underlying disk to finish writing. In the interest of host compatibility,
// we conservatively implement this with `sync_all`, which
@ -1578,7 +1594,7 @@ fn fsync(&mut self, fd_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
}
}
fn fdatasync(&mut self, fd_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn fdatasync(&mut self, fd_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let fd = this.read_scalar(fd_op)?.to_i32()?;
@ -1602,10 +1618,10 @@ fn fdatasync(&mut self, fd_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn sync_file_range(
&mut self,
fd_op: &OpTy<'tcx, Tag>,
offset_op: &OpTy<'tcx, Tag>,
nbytes_op: &OpTy<'tcx, Tag>,
flags_op: &OpTy<'tcx, Tag>,
fd_op: &OpTy<'tcx, Provenance>,
offset_op: &OpTy<'tcx, Provenance>,
nbytes_op: &OpTy<'tcx, Provenance>,
flags_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -1647,9 +1663,9 @@ fn sync_file_range(
fn readlink(
&mut self,
pathname_op: &OpTy<'tcx, Tag>,
buf_op: &OpTy<'tcx, Tag>,
bufsize_op: &OpTy<'tcx, Tag>,
pathname_op: &OpTy<'tcx, Provenance>,
buf_op: &OpTy<'tcx, Provenance>,
bufsize_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i64> {
let this = self.eval_context_mut();
@ -1691,7 +1707,7 @@ fn readlink(
}
#[cfg_attr(not(unix), allow(unused))]
fn isatty(&mut self, miri_fd: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn isatty(&mut self, miri_fd: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
#[cfg(unix)]
if matches!(this.machine.isolated_op, IsolatedOp::Allow) {
@ -1740,7 +1756,7 @@ fn extract_sec_and_nsec<'tcx>(
/// Stores a file's metadata in order to avoid code duplication in the different metadata related
/// shims.
struct FileMetadata {
mode: Scalar<Tag>,
mode: Scalar<Provenance>,
size: u64,
created: Option<(u64, u32)>,
accessed: Option<(u64, u32)>,

View File

@ -23,8 +23,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn call_dlsym(
&mut self,
dlsym: Dlsym,
_args: &[OpTy<'tcx, Tag>],
_dest: &PlaceTy<'tcx, Tag>,
_args: &[OpTy<'tcx, Provenance>],
_dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();

View File

@ -14,8 +14,8 @@ fn emulate_foreign_item_by_name(
&mut self,
link_name: Symbol,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
let this = self.eval_context_mut();
@ -165,10 +165,10 @@ fn emulate_foreign_item_by_name(
// Shims the linux `getrandom` syscall.
fn getrandom<'tcx>(
this: &mut MiriEvalContext<'_, 'tcx>,
ptr: &OpTy<'tcx, Tag>,
len: &OpTy<'tcx, Tag>,
flags: &OpTy<'tcx, Tag>,
dest: &PlaceTy<'tcx, Tag>,
ptr: &OpTy<'tcx, Provenance>,
len: &OpTy<'tcx, Provenance>,
flags: &OpTy<'tcx, Provenance>,
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let ptr = this.read_pointer(ptr)?;
let len = this.read_scalar(len)?.to_machine_usize(this)?;

View File

@ -7,8 +7,8 @@
/// `args` is the arguments *after* the syscall number.
pub fn futex<'tcx>(
this: &mut MiriEvalContext<'_, 'tcx>,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
// The amount of arguments used depends on the type of futex operation.
// The full futex syscall takes six arguments (excluding the syscall

View File

@ -27,8 +27,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn call_dlsym(
&mut self,
dlsym: Dlsym,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();

View File

@ -12,8 +12,8 @@ fn emulate_foreign_item_by_name(
&mut self,
link_name: Symbol,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
let this = self.eval_context_mut();

View File

@ -21,14 +21,14 @@
fn is_mutex_kind_default<'mir, 'tcx: 'mir>(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
kind: Scalar<Tag>,
kind: Scalar<Provenance>,
) -> InterpResult<'tcx, bool> {
Ok(kind == ecx.eval_libc("PTHREAD_MUTEX_DEFAULT")?)
}
fn is_mutex_kind_normal<'mir, 'tcx: 'mir>(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
kind: Scalar<Tag>,
kind: Scalar<Provenance>,
) -> InterpResult<'tcx, bool> {
let kind = kind.to_i32()?;
let mutex_normal_kind = ecx.eval_libc("PTHREAD_MUTEX_NORMAL")?.to_i32()?;
@ -37,15 +37,15 @@ fn is_mutex_kind_normal<'mir, 'tcx: 'mir>(
fn mutexattr_get_kind<'mir, 'tcx: 'mir>(
ecx: &MiriEvalContext<'mir, 'tcx>,
attr_op: &OpTy<'tcx, Tag>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
attr_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Provenance>> {
ecx.read_scalar_at_offset(attr_op, 0, ecx.machine.layouts.i32)
}
fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
attr_op: &OpTy<'tcx, Tag>,
kind: impl Into<ScalarMaybeUninit<Tag>>,
attr_op: &OpTy<'tcx, Provenance>,
kind: impl Into<ScalarMaybeUninit<Provenance>>,
) -> InterpResult<'tcx, ()> {
ecx.write_scalar_at_offset(attr_op, 0, kind, layout_of_maybe_uninit(ecx.tcx, ecx.tcx.types.i32))
}
@ -61,8 +61,8 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
fn mutex_get_kind<'mir, 'tcx: 'mir>(
ecx: &MiriEvalContext<'mir, 'tcx>,
mutex_op: &OpTy<'tcx, Tag>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
mutex_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Provenance>> {
let offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 };
ecx.read_scalar_at_offset_atomic(
mutex_op,
@ -74,8 +74,8 @@ fn mutex_get_kind<'mir, 'tcx: 'mir>(
fn mutex_set_kind<'mir, 'tcx: 'mir>(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
mutex_op: &OpTy<'tcx, Tag>,
kind: impl Into<ScalarMaybeUninit<Tag>>,
mutex_op: &OpTy<'tcx, Provenance>,
kind: impl Into<ScalarMaybeUninit<Provenance>>,
) -> InterpResult<'tcx, ()> {
let offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 };
ecx.write_scalar_at_offset_atomic(
@ -89,15 +89,15 @@ fn mutex_set_kind<'mir, 'tcx: 'mir>(
fn mutex_get_id<'mir, 'tcx: 'mir>(
ecx: &MiriEvalContext<'mir, 'tcx>,
mutex_op: &OpTy<'tcx, Tag>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
mutex_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Provenance>> {
ecx.read_scalar_at_offset_atomic(mutex_op, 4, ecx.machine.layouts.u32, AtomicReadOrd::Relaxed)
}
fn mutex_set_id<'mir, 'tcx: 'mir>(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
mutex_op: &OpTy<'tcx, Tag>,
id: impl Into<ScalarMaybeUninit<Tag>>,
mutex_op: &OpTy<'tcx, Provenance>,
id: impl Into<ScalarMaybeUninit<Provenance>>,
) -> InterpResult<'tcx, ()> {
ecx.write_scalar_at_offset_atomic(
mutex_op,
@ -110,7 +110,7 @@ fn mutex_set_id<'mir, 'tcx: 'mir>(
fn mutex_get_or_create_id<'mir, 'tcx: 'mir>(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
mutex_op: &OpTy<'tcx, Tag>,
mutex_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, MutexId> {
let value_place = ecx.deref_operand_and_offset(mutex_op, 4, ecx.machine.layouts.u32)?;
@ -145,15 +145,15 @@ fn mutex_get_or_create_id<'mir, 'tcx: 'mir>(
fn rwlock_get_id<'mir, 'tcx: 'mir>(
ecx: &MiriEvalContext<'mir, 'tcx>,
rwlock_op: &OpTy<'tcx, Tag>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
rwlock_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Provenance>> {
ecx.read_scalar_at_offset_atomic(rwlock_op, 4, ecx.machine.layouts.u32, AtomicReadOrd::Relaxed)
}
fn rwlock_set_id<'mir, 'tcx: 'mir>(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
rwlock_op: &OpTy<'tcx, Tag>,
id: impl Into<ScalarMaybeUninit<Tag>>,
rwlock_op: &OpTy<'tcx, Provenance>,
id: impl Into<ScalarMaybeUninit<Provenance>>,
) -> InterpResult<'tcx, ()> {
ecx.write_scalar_at_offset_atomic(
rwlock_op,
@ -166,7 +166,7 @@ fn rwlock_set_id<'mir, 'tcx: 'mir>(
fn rwlock_get_or_create_id<'mir, 'tcx: 'mir>(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
rwlock_op: &OpTy<'tcx, Tag>,
rwlock_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, RwLockId> {
let value_place = ecx.deref_operand_and_offset(rwlock_op, 4, ecx.machine.layouts.u32)?;
@ -200,15 +200,15 @@ fn rwlock_get_or_create_id<'mir, 'tcx: 'mir>(
fn condattr_get_clock_id<'mir, 'tcx: 'mir>(
ecx: &MiriEvalContext<'mir, 'tcx>,
attr_op: &OpTy<'tcx, Tag>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
attr_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Provenance>> {
ecx.read_scalar_at_offset(attr_op, 0, ecx.machine.layouts.i32)
}
fn condattr_set_clock_id<'mir, 'tcx: 'mir>(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
attr_op: &OpTy<'tcx, Tag>,
clock_id: impl Into<ScalarMaybeUninit<Tag>>,
attr_op: &OpTy<'tcx, Provenance>,
clock_id: impl Into<ScalarMaybeUninit<Provenance>>,
) -> InterpResult<'tcx, ()> {
ecx.write_scalar_at_offset(
attr_op,
@ -229,15 +229,15 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>(
fn cond_get_id<'mir, 'tcx: 'mir>(
ecx: &MiriEvalContext<'mir, 'tcx>,
cond_op: &OpTy<'tcx, Tag>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
cond_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Provenance>> {
ecx.read_scalar_at_offset_atomic(cond_op, 4, ecx.machine.layouts.u32, AtomicReadOrd::Relaxed)
}
fn cond_set_id<'mir, 'tcx: 'mir>(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
cond_op: &OpTy<'tcx, Tag>,
id: impl Into<ScalarMaybeUninit<Tag>>,
cond_op: &OpTy<'tcx, Provenance>,
id: impl Into<ScalarMaybeUninit<Provenance>>,
) -> InterpResult<'tcx, ()> {
ecx.write_scalar_at_offset_atomic(
cond_op,
@ -250,7 +250,7 @@ fn cond_set_id<'mir, 'tcx: 'mir>(
fn cond_get_or_create_id<'mir, 'tcx: 'mir>(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
cond_op: &OpTy<'tcx, Tag>,
cond_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, CondvarId> {
let value_place = ecx.deref_operand_and_offset(cond_op, 4, ecx.machine.layouts.u32)?;
@ -278,15 +278,15 @@ fn cond_get_or_create_id<'mir, 'tcx: 'mir>(
fn cond_get_clock_id<'mir, 'tcx: 'mir>(
ecx: &MiriEvalContext<'mir, 'tcx>,
cond_op: &OpTy<'tcx, Tag>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
cond_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, ScalarMaybeUninit<Provenance>> {
ecx.read_scalar_at_offset(cond_op, 8, ecx.machine.layouts.i32)
}
fn cond_set_clock_id<'mir, 'tcx: 'mir>(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
cond_op: &OpTy<'tcx, Tag>,
clock_id: impl Into<ScalarMaybeUninit<Tag>>,
cond_op: &OpTy<'tcx, Provenance>,
clock_id: impl Into<ScalarMaybeUninit<Provenance>>,
) -> InterpResult<'tcx, ()> {
ecx.write_scalar_at_offset(
cond_op,
@ -347,7 +347,10 @@ fn release_cond_mutex_and_block<'mir, 'tcx: 'mir>(
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn pthread_mutexattr_init(&mut self, attr_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_mutexattr_init(
&mut self,
attr_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let default_kind = this.eval_libc("PTHREAD_MUTEX_DEFAULT")?;
@ -358,8 +361,8 @@ fn pthread_mutexattr_init(&mut self, attr_op: &OpTy<'tcx, Tag>) -> InterpResult<
fn pthread_mutexattr_settype(
&mut self,
attr_op: &OpTy<'tcx, Tag>,
kind_op: &OpTy<'tcx, Tag>,
attr_op: &OpTy<'tcx, Provenance>,
kind_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -397,7 +400,10 @@ fn pthread_mutexattr_settype(
Ok(0)
}
fn pthread_mutexattr_destroy(&mut self, attr_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_mutexattr_destroy(
&mut self,
attr_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
// Destroying an uninit pthread_mutexattr is UB, so check to make sure it's not uninit.
@ -423,8 +429,8 @@ fn pthread_mutexattr_destroy(&mut self, attr_op: &OpTy<'tcx, Tag>) -> InterpResu
fn pthread_mutex_init(
&mut self,
mutex_op: &OpTy<'tcx, Tag>,
attr_op: &OpTy<'tcx, Tag>,
mutex_op: &OpTy<'tcx, Provenance>,
attr_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -443,7 +449,7 @@ fn pthread_mutex_init(
Ok(0)
}
fn pthread_mutex_lock(&mut self, mutex_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_mutex_lock(&mut self, mutex_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let kind = mutex_get_kind(this, mutex_op)?.check_init()?;
@ -480,7 +486,10 @@ fn pthread_mutex_lock(&mut self, mutex_op: &OpTy<'tcx, Tag>) -> InterpResult<'tc
}
}
fn pthread_mutex_trylock(&mut self, mutex_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_mutex_trylock(
&mut self,
mutex_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let kind = mutex_get_kind(this, mutex_op)?.check_init()?;
@ -513,7 +522,10 @@ fn pthread_mutex_trylock(&mut self, mutex_op: &OpTy<'tcx, Tag>) -> InterpResult<
}
}
fn pthread_mutex_unlock(&mut self, mutex_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_mutex_unlock(
&mut self,
mutex_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let kind = mutex_get_kind(this, mutex_op)?.check_init()?;
@ -545,7 +557,10 @@ fn pthread_mutex_unlock(&mut self, mutex_op: &OpTy<'tcx, Tag>) -> InterpResult<'
}
}
fn pthread_mutex_destroy(&mut self, mutex_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_mutex_destroy(
&mut self,
mutex_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let id = mutex_get_or_create_id(this, mutex_op)?;
@ -566,7 +581,10 @@ fn pthread_mutex_destroy(&mut self, mutex_op: &OpTy<'tcx, Tag>) -> InterpResult<
Ok(0)
}
fn pthread_rwlock_rdlock(&mut self, rwlock_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_rwlock_rdlock(
&mut self,
rwlock_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let id = rwlock_get_or_create_id(this, rwlock_op)?;
@ -581,7 +599,10 @@ fn pthread_rwlock_rdlock(&mut self, rwlock_op: &OpTy<'tcx, Tag>) -> InterpResult
}
}
fn pthread_rwlock_tryrdlock(&mut self, rwlock_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_rwlock_tryrdlock(
&mut self,
rwlock_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let id = rwlock_get_or_create_id(this, rwlock_op)?;
@ -595,7 +616,10 @@ fn pthread_rwlock_tryrdlock(&mut self, rwlock_op: &OpTy<'tcx, Tag>) -> InterpRes
}
}
fn pthread_rwlock_wrlock(&mut self, rwlock_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_rwlock_wrlock(
&mut self,
rwlock_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let id = rwlock_get_or_create_id(this, rwlock_op)?;
@ -622,7 +646,10 @@ fn pthread_rwlock_wrlock(&mut self, rwlock_op: &OpTy<'tcx, Tag>) -> InterpResult
Ok(0)
}
fn pthread_rwlock_trywrlock(&mut self, rwlock_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_rwlock_trywrlock(
&mut self,
rwlock_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let id = rwlock_get_or_create_id(this, rwlock_op)?;
@ -636,7 +663,10 @@ fn pthread_rwlock_trywrlock(&mut self, rwlock_op: &OpTy<'tcx, Tag>) -> InterpRes
}
}
fn pthread_rwlock_unlock(&mut self, rwlock_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_rwlock_unlock(
&mut self,
rwlock_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let id = rwlock_get_or_create_id(this, rwlock_op)?;
@ -652,7 +682,10 @@ fn pthread_rwlock_unlock(&mut self, rwlock_op: &OpTy<'tcx, Tag>) -> InterpResult
}
}
fn pthread_rwlock_destroy(&mut self, rwlock_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_rwlock_destroy(
&mut self,
rwlock_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let id = rwlock_get_or_create_id(this, rwlock_op)?;
@ -671,7 +704,10 @@ fn pthread_rwlock_destroy(&mut self, rwlock_op: &OpTy<'tcx, Tag>) -> InterpResul
Ok(0)
}
fn pthread_condattr_init(&mut self, attr_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_condattr_init(
&mut self,
attr_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
// The default value of the clock attribute shall refer to the system
@ -685,8 +721,8 @@ fn pthread_condattr_init(&mut self, attr_op: &OpTy<'tcx, Tag>) -> InterpResult<'
fn pthread_condattr_setclock(
&mut self,
attr_op: &OpTy<'tcx, Tag>,
clock_id_op: &OpTy<'tcx, Tag>,
attr_op: &OpTy<'tcx, Provenance>,
clock_id_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -705,8 +741,8 @@ fn pthread_condattr_setclock(
fn pthread_condattr_getclock(
&mut self,
attr_op: &OpTy<'tcx, Tag>,
clk_id_op: &OpTy<'tcx, Tag>,
attr_op: &OpTy<'tcx, Provenance>,
clk_id_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -716,7 +752,10 @@ fn pthread_condattr_getclock(
Ok(0)
}
fn pthread_condattr_destroy(&mut self, attr_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_condattr_destroy(
&mut self,
attr_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
// Destroying an uninit pthread_condattr is UB, so check to make sure it's not uninit.
@ -730,8 +769,8 @@ fn pthread_condattr_destroy(&mut self, attr_op: &OpTy<'tcx, Tag>) -> InterpResul
fn pthread_cond_init(
&mut self,
cond_op: &OpTy<'tcx, Tag>,
attr_op: &OpTy<'tcx, Tag>,
cond_op: &OpTy<'tcx, Provenance>,
attr_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -750,7 +789,7 @@ fn pthread_cond_init(
Ok(0)
}
fn pthread_cond_signal(&mut self, cond_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_cond_signal(&mut self, cond_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let id = cond_get_or_create_id(this, cond_op)?;
if let Some((thread, mutex)) = this.condvar_signal(id) {
@ -760,7 +799,10 @@ fn pthread_cond_signal(&mut self, cond_op: &OpTy<'tcx, Tag>) -> InterpResult<'tc
Ok(0)
}
fn pthread_cond_broadcast(&mut self, cond_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_cond_broadcast(
&mut self,
cond_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let id = cond_get_or_create_id(this, cond_op)?;
@ -773,8 +815,8 @@ fn pthread_cond_broadcast(&mut self, cond_op: &OpTy<'tcx, Tag>) -> InterpResult<
fn pthread_cond_wait(
&mut self,
cond_op: &OpTy<'tcx, Tag>,
mutex_op: &OpTy<'tcx, Tag>,
cond_op: &OpTy<'tcx, Provenance>,
mutex_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -790,10 +832,10 @@ fn pthread_cond_wait(
fn pthread_cond_timedwait(
&mut self,
cond_op: &OpTy<'tcx, Tag>,
mutex_op: &OpTy<'tcx, Tag>,
abstime_op: &OpTy<'tcx, Tag>,
dest: &PlaceTy<'tcx, Tag>,
cond_op: &OpTy<'tcx, Provenance>,
mutex_op: &OpTy<'tcx, Provenance>,
abstime_op: &OpTy<'tcx, Provenance>,
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
@ -852,7 +894,10 @@ fn pthread_cond_timedwait(
Ok(())
}
fn pthread_cond_destroy(&mut self, cond_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_cond_destroy(
&mut self,
cond_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let id = cond_get_or_create_id(this, cond_op)?;

View File

@ -6,10 +6,10 @@ impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tc
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn pthread_create(
&mut self,
thread: &OpTy<'tcx, Tag>,
_attr: &OpTy<'tcx, Tag>,
start_routine: &OpTy<'tcx, Tag>,
arg: &OpTy<'tcx, Tag>,
thread: &OpTy<'tcx, Provenance>,
_attr: &OpTy<'tcx, Provenance>,
start_routine: &OpTy<'tcx, Provenance>,
arg: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -59,8 +59,8 @@ fn pthread_create(
fn pthread_join(
&mut self,
thread: &OpTy<'tcx, Tag>,
retval: &OpTy<'tcx, Tag>,
thread: &OpTy<'tcx, Provenance>,
retval: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
@ -75,7 +75,7 @@ fn pthread_join(
Ok(0)
}
fn pthread_detach(&mut self, thread: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
fn pthread_detach(&mut self, thread: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let thread_id = this.read_scalar(thread)?.to_machine_usize(this)?;
@ -84,14 +84,14 @@ fn pthread_detach(&mut self, thread: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32
Ok(0)
}
fn pthread_self(&mut self, dest: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
fn pthread_self(&mut self, dest: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let thread_id = this.get_active_thread();
this.write_scalar(Scalar::from_uint(thread_id.to_u32(), dest.layout.size), dest)
}
fn prctl(&mut self, args: &[OpTy<'tcx, Tag>]) -> InterpResult<'tcx, i32> {
fn prctl(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
this.assert_target_os("linux", "prctl");
@ -138,7 +138,7 @@ fn prctl(&mut self, args: &[OpTy<'tcx, Tag>]) -> InterpResult<'tcx, i32> {
Ok(0)
}
fn pthread_setname_np(&mut self, name: Pointer<Option<Tag>>) -> InterpResult<'tcx> {
fn pthread_setname_np(&mut self, name: Pointer<Option<Provenance>>) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
this.assert_target_os("macos", "pthread_setname_np");

View File

@ -31,8 +31,8 @@ fn call_dlsym(
&mut self,
dlsym: Dlsym,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();

View File

@ -15,8 +15,8 @@ fn emulate_foreign_item_by_name(
&mut self,
link_name: Symbol,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
let this = self.eval_context_mut();

View File

@ -5,7 +5,7 @@
fn srwlock_get_or_create_id<'mir, 'tcx: 'mir>(
ecx: &mut MiriEvalContext<'mir, 'tcx>,
lock_op: &OpTy<'tcx, Tag>,
lock_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, RwLockId> {
let value_place = ecx.deref_operand_and_offset(lock_op, 0, ecx.machine.layouts.u32)?;
@ -34,7 +34,7 @@ fn srwlock_get_or_create_id<'mir, 'tcx: 'mir>(
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
#[allow(non_snake_case)]
fn AcquireSRWLockExclusive(&mut self, lock_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx> {
fn AcquireSRWLockExclusive(&mut self, lock_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let id = srwlock_get_or_create_id(this, lock_op)?;
let active_thread = this.get_active_thread();
@ -56,7 +56,10 @@ fn AcquireSRWLockExclusive(&mut self, lock_op: &OpTy<'tcx, Tag>) -> InterpResult
}
#[allow(non_snake_case)]
fn TryAcquireSRWLockExclusive(&mut self, lock_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, u8> {
fn TryAcquireSRWLockExclusive(
&mut self,
lock_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, u8> {
let this = self.eval_context_mut();
let id = srwlock_get_or_create_id(this, lock_op)?;
let active_thread = this.get_active_thread();
@ -71,7 +74,7 @@ fn TryAcquireSRWLockExclusive(&mut self, lock_op: &OpTy<'tcx, Tag>) -> InterpRes
}
#[allow(non_snake_case)]
fn ReleaseSRWLockExclusive(&mut self, lock_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx> {
fn ReleaseSRWLockExclusive(&mut self, lock_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let id = srwlock_get_or_create_id(this, lock_op)?;
let active_thread = this.get_active_thread();
@ -87,7 +90,7 @@ fn ReleaseSRWLockExclusive(&mut self, lock_op: &OpTy<'tcx, Tag>) -> InterpResult
}
#[allow(non_snake_case)]
fn AcquireSRWLockShared(&mut self, lock_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx> {
fn AcquireSRWLockShared(&mut self, lock_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let id = srwlock_get_or_create_id(this, lock_op)?;
let active_thread = this.get_active_thread();
@ -102,7 +105,10 @@ fn AcquireSRWLockShared(&mut self, lock_op: &OpTy<'tcx, Tag>) -> InterpResult<'t
}
#[allow(non_snake_case)]
fn TryAcquireSRWLockShared(&mut self, lock_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx, u8> {
fn TryAcquireSRWLockShared(
&mut self,
lock_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, u8> {
let this = self.eval_context_mut();
let id = srwlock_get_or_create_id(this, lock_op)?;
let active_thread = this.get_active_thread();
@ -116,7 +122,7 @@ fn TryAcquireSRWLockShared(&mut self, lock_op: &OpTy<'tcx, Tag>) -> InterpResult
}
#[allow(non_snake_case)]
fn ReleaseSRWLockShared(&mut self, lock_op: &OpTy<'tcx, Tag>) -> InterpResult<'tcx> {
fn ReleaseSRWLockShared(&mut self, lock_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let id = srwlock_get_or_create_id(this, lock_op)?;
let active_thread = this.get_active_thread();

View File

@ -5,11 +5,8 @@
use rustc_target::abi::Size;
use crate::helpers::CurrentSpan;
use crate::stacked_borrows::{err_sb_ub, AccessKind, Permission};
use crate::Item;
use crate::SbTag;
use crate::SbTagExtra;
use crate::Stack;
use crate::stacked_borrows::{err_sb_ub, AccessKind};
use crate::*;
use rustc_middle::mir::interpret::InterpError;
@ -132,7 +129,7 @@ pub fn get_logs_relevant_to(
/// Report a descriptive error when `new` could not be granted from `derived_from`.
pub fn grant_error<'tcx>(
&self,
derived_from: SbTagExtra,
derived_from: ProvenanceExtra,
new: Item,
alloc_id: AllocId,
alloc_range: AllocRange,
@ -155,7 +152,7 @@ pub fn grant_error<'tcx>(
pub fn access_error<'tcx>(
&self,
access: AccessKind,
tag: SbTagExtra,
tag: ProvenanceExtra,
alloc_id: AllocId,
alloc_range: AllocRange,
error_offset: Size,
@ -181,8 +178,8 @@ fn operation_summary(
format!("this error occurs as part of {operation} at {alloc_id:?}{alloc_range:?}")
}
fn error_cause(stack: &Stack, tag: SbTagExtra) -> &'static str {
if let SbTagExtra::Concrete(tag) = tag {
fn error_cause(stack: &Stack, prov_extra: ProvenanceExtra) -> &'static str {
if let ProvenanceExtra::Concrete(tag) = prov_extra {
if (0..stack.len())
.map(|i| stack.get(i).unwrap())
.any(|item| item.tag() == tag && item.perm() != Permission::Disabled)

View File

@ -55,32 +55,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
/// The "extra" information an SB pointer has over a regular AllocId.
/// Newtype for `Option<SbTag>`.
#[derive(Copy, Clone)]
pub enum SbTagExtra {
Concrete(SbTag),
Wildcard,
}
impl fmt::Debug for SbTagExtra {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SbTagExtra::Concrete(pid) => write!(f, "{pid:?}"),
SbTagExtra::Wildcard => write!(f, "<wildcard>"),
}
}
}
impl SbTagExtra {
fn and_then<T>(self, f: impl FnOnce(SbTag) -> Option<T>) -> Option<T> {
match self {
SbTagExtra::Concrete(pid) => f(pid),
SbTagExtra::Wildcard => None,
}
}
}
#[derive(Debug)]
pub struct FrameExtra {
/// The ID of the call this frame corresponds to.
@ -311,7 +285,7 @@ fn find_first_write_incompatible(&self, granting: usize) -> usize {
/// currently checking.
fn item_popped(
item: &Item,
provoking_access: Option<(SbTagExtra, AllocRange, Size, AccessKind)>, // just for debug printing and error messages
provoking_access: Option<(ProvenanceExtra, AllocRange, Size, AccessKind)>, // just for debug printing and error messages
global: &GlobalStateInner,
alloc_history: &mut AllocHistory,
threads: &ThreadManager<'_, 'tcx>,
@ -322,7 +296,7 @@ fn item_popped(
#[inline(never)] // cold path
fn check_tracked(
item: &Item,
provoking_access: &Option<(SbTagExtra, AllocRange, Size, AccessKind)>,
provoking_access: &Option<(ProvenanceExtra, AllocRange, Size, AccessKind)>,
global: &GlobalStateInner,
) {
if global.tracked_pointer_tags.contains(&item.tag()) {
@ -357,7 +331,7 @@ fn check_tracked(
#[inline(never)] // cold path
fn protector_error<'tcx>(
item: &Item,
provoking_access: &Option<(SbTagExtra, AllocRange, Size, AccessKind)>,
provoking_access: &Option<(ProvenanceExtra, AllocRange, Size, AccessKind)>,
alloc_history: &mut AllocHistory,
threads: &ThreadManager<'_, 'tcx>,
) -> InterpErrorInfo<'tcx> {
@ -410,7 +384,7 @@ fn protector_error<'tcx>(
fn access(
&mut self,
access: AccessKind,
tag: SbTagExtra,
tag: ProvenanceExtra,
(alloc_id, alloc_range, offset): (AllocId, AllocRange, Size), // just for debug printing and error messages
global: &mut GlobalStateInner,
current_span: &mut CurrentSpan<'_, '_, 'tcx>,
@ -482,7 +456,7 @@ fn access(
}
// If this was an approximate action, we now collapse everything into an unknown.
if granting_idx.is_none() || matches!(tag, SbTagExtra::Wildcard) {
if granting_idx.is_none() || matches!(tag, ProvenanceExtra::Wildcard) {
// Compute the upper bound of the items that remain.
// (This is why we did all the work above: to reduce the items we have to consider here.)
let mut max = NonZeroU64::new(1).unwrap();
@ -512,7 +486,7 @@ fn access(
/// active protectors at all because we will remove all items.
fn dealloc(
&mut self,
tag: SbTagExtra,
tag: ProvenanceExtra,
(alloc_id, _alloc_range, _offset): (AllocId, AllocRange, Size), // just for debug printing and error messages
global: &GlobalStateInner,
alloc_history: &mut AllocHistory,
@ -546,7 +520,7 @@ fn dealloc(
/// `range` that we are currently checking.
fn grant(
&mut self,
derived_from: SbTagExtra,
derived_from: ProvenanceExtra,
new: Item,
(alloc_id, alloc_range, offset): (AllocId, AllocRange, Size), // just for debug printing and error messages
global: &mut GlobalStateInner,
@ -575,7 +549,7 @@ fn grant(
"this case only makes sense for stack-like accesses"
);
let (Some(granting_idx), SbTagExtra::Concrete(_)) = (granting_idx, derived_from) else {
let (Some(granting_idx), ProvenanceExtra::Concrete(_)) = (granting_idx, derived_from) else {
// The parent is a wildcard pointer or matched the unknown bottom.
// This is approximate. Nobody knows what happened, so forget everything.
// The new thing is SRW anyway, so we cannot push it "on top of the unkown part"
@ -686,7 +660,7 @@ pub fn new_allocation(
pub fn memory_read<'tcx>(
&mut self,
alloc_id: AllocId,
tag: SbTagExtra,
tag: ProvenanceExtra,
range: AllocRange,
state: &GlobalState,
mut current_span: CurrentSpan<'_, '_, 'tcx>,
@ -717,7 +691,7 @@ pub fn memory_read<'tcx>(
pub fn memory_written<'tcx>(
&mut self,
alloc_id: AllocId,
tag: SbTagExtra,
tag: ProvenanceExtra,
range: AllocRange,
state: &GlobalState,
mut current_span: CurrentSpan<'_, '_, 'tcx>,
@ -748,7 +722,7 @@ pub fn memory_written<'tcx>(
pub fn memory_deallocated<'tcx>(
&mut self,
alloc_id: AllocId,
tag: SbTagExtra,
tag: ProvenanceExtra,
range: AllocRange,
state: &GlobalState,
threads: &ThreadManager<'_, 'tcx>,
@ -770,7 +744,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
/// happened.
fn reborrow(
&mut self,
place: &MPlaceTy<'tcx, Tag>,
place: &MPlaceTy<'tcx, Provenance>,
size: Size,
kind: RefKind,
new_tag: SbTag,
@ -782,7 +756,7 @@ fn reborrow(
// It is crucial that this gets called on all code paths, to ensure we track tag creation.
let log_creation = |this: &MiriEvalContext<'mir, 'tcx>,
current_span: &mut CurrentSpan<'_, 'mir, 'tcx>,
loc: Option<(AllocId, Size, SbTagExtra)>| // alloc_id, base_offset, orig_tag
loc: Option<(AllocId, Size, ProvenanceExtra)>| // alloc_id, base_offset, orig_tag
-> InterpResult<'tcx> {
let global = this.machine.stacked_borrows.as_ref().unwrap().borrow();
if global.tracked_pointer_tags.contains(&new_tag) {
@ -798,7 +772,7 @@ fn reborrow(
};
// The SB history tracking needs a parent tag, so skip if we come from a wildcard.
let SbTagExtra::Concrete(orig_tag) = orig_tag else {
let ProvenanceExtra::Concrete(orig_tag) = orig_tag else {
// FIXME: should we log this?
return Ok(())
};
@ -972,10 +946,10 @@ fn reborrow(
/// `mutbl` can be `None` to make this a raw pointer.
fn retag_reference(
&mut self,
val: &ImmTy<'tcx, Tag>,
val: &ImmTy<'tcx, Provenance>,
kind: RefKind,
protect: bool,
) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> {
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
let this = self.eval_context_mut();
// We want a place for where the ptr *points to*, so we get one.
let place = this.ref_to_mplace(val)?;
@ -1001,12 +975,12 @@ fn retag_reference(
Some(alloc_id) => {
// If `reborrow` could figure out the AllocId of this ptr, hard-code it into the new one.
// Even if we started out with a wildcard, this newly retagged pointer is tied to that allocation.
Tag::Concrete { alloc_id, sb: new_tag }
Provenance::Concrete { alloc_id, sb: new_tag }
}
None => {
// Looks like this has to stay a wildcard pointer.
assert!(matches!(prov, Tag::Wildcard));
Tag::Wildcard
assert!(matches!(prov, Provenance::Wildcard));
Provenance::Wildcard
}
}
})
@ -1019,7 +993,7 @@ fn retag_reference(
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn retag(&mut self, kind: RetagKind, place: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
fn retag(&mut self, kind: RetagKind, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let retag_fields = this.machine.stacked_borrows.as_mut().unwrap().get_mut().retag_fields;
let mut visitor = RetagVisitor { ecx: this, kind, retag_fields };
@ -1057,7 +1031,7 @@ impl<'ecx, 'mir, 'tcx> RetagVisitor<'ecx, 'mir, 'tcx> {
#[inline(always)] // yes this helps in our benchmarks
fn retag_place(
&mut self,
place: &PlaceTy<'tcx, Tag>,
place: &PlaceTy<'tcx, Provenance>,
ref_kind: RefKind,
protector: bool,
) -> InterpResult<'tcx> {
@ -1070,14 +1044,14 @@ fn retag_place(
impl<'ecx, 'mir, 'tcx> MutValueVisitor<'mir, 'tcx, Evaluator<'mir, 'tcx>>
for RetagVisitor<'ecx, 'mir, 'tcx>
{
type V = PlaceTy<'tcx, Tag>;
type V = PlaceTy<'tcx, Provenance>;
#[inline(always)]
fn ecx(&mut self) -> &mut MiriEvalContext<'mir, 'tcx> {
self.ecx
}
fn visit_box(&mut self, place: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
fn visit_box(&mut self, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
// Boxes do not get a protector: protectors reflect that references outlive the call
// they were passed in to; that's just not the case for boxes.
self.retag_place(
@ -1087,7 +1061,7 @@ fn visit_box(&mut self, place: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
)
}
fn visit_value(&mut self, place: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
fn visit_value(&mut self, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
if let Some((ref_kind, protector)) = qualify(place.layout.ty, self.kind) {
self.retag_place(place, ref_kind, protector)?;
} else if matches!(place.layout.ty.kind(), ty::RawPtr(..)) {

View File

@ -1,8 +1,11 @@
use crate::stacked_borrows::{AccessKind, Item, Permission, SbTag, SbTagExtra};
use rustc_data_structures::fx::FxHashSet;
#[cfg(feature = "stack-cache")]
use std::ops::Range;
use rustc_data_structures::fx::FxHashSet;
use crate::stacked_borrows::{AccessKind, Item, Permission, SbTag};
use crate::ProvenanceExtra;
/// Exactly what cache size we should use is a difficult tradeoff. There will always be some
/// workload which has a `SbTag` working set which exceeds the size of the cache, and ends up
/// falling back to linear searches of the borrow stack very often.
@ -126,13 +129,13 @@ fn verify_cache_consistency(&self) {
pub(super) fn find_granting(
&mut self,
access: AccessKind,
tag: SbTagExtra,
tag: ProvenanceExtra,
exposed_tags: &FxHashSet<SbTag>,
) -> Result<Option<usize>, ()> {
#[cfg(debug_assertions)]
self.verify_cache_consistency();
let SbTagExtra::Concrete(tag) = tag else {
let ProvenanceExtra::Concrete(tag) = tag else {
// Handle the wildcard case.
// Go search the stack for an exposed tag.
if let Some(idx) =

View File

@ -42,7 +42,7 @@ fn index(self) -> usize {
}
impl $name {
pub fn to_u32_scalar<'tcx>(&self) -> Scalar<Tag> {
pub fn to_u32_scalar<'tcx>(&self) -> Scalar<Provenance> {
Scalar::from_u32(self.0.get())
}
}

View File

@ -70,7 +70,7 @@ fn from(id: u32) -> Self {
}
impl ThreadId {
pub fn to_u32_scalar(&self) -> Scalar<Tag> {
pub fn to_u32_scalar(&self) -> Scalar<Provenance> {
Scalar::from_u32(self.0)
}
}
@ -112,7 +112,7 @@ pub struct Thread<'mir, 'tcx> {
thread_name: Option<Vec<u8>>,
/// The virtual call stack.
stack: Vec<Frame<'mir, 'tcx, Tag, FrameData<'tcx>>>,
stack: Vec<Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>>,
/// The join status.
join_status: ThreadJoinStatus,
@ -120,10 +120,10 @@ pub struct Thread<'mir, 'tcx> {
/// The temporary used for storing the argument of
/// the call to `miri_start_panic` (the panic payload) when unwinding.
/// This is pointer-sized, and matches the `Payload` type in `src/libpanic_unwind/miri.rs`.
pub(crate) panic_payload: Option<Scalar<Tag>>,
pub(crate) panic_payload: Option<Scalar<Provenance>>,
/// Last OS error location in memory. It is a 32-bit integer.
pub(crate) last_error: Option<MPlaceTy<'tcx, Tag>>,
pub(crate) last_error: Option<MPlaceTy<'tcx, Provenance>>,
}
impl<'mir, 'tcx> Thread<'mir, 'tcx> {
@ -227,7 +227,7 @@ pub struct ThreadManager<'mir, 'tcx> {
pub(crate) sync: SynchronizationState,
/// A mapping from a thread-local static to an allocation id of a thread
/// specific allocation.
thread_local_alloc_ids: RefCell<FxHashMap<(DefId, ThreadId), Pointer<Tag>>>,
thread_local_alloc_ids: RefCell<FxHashMap<(DefId, ThreadId), Pointer<Provenance>>>,
/// A flag that indicates that we should change the active thread.
yield_active_thread: bool,
/// Callbacks that are called once the specified time passes.
@ -256,7 +256,7 @@ fn default() -> Self {
impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
/// Check if we have an allocation for the given thread local static for the
/// active thread.
fn get_thread_local_alloc_id(&self, def_id: DefId) -> Option<Pointer<Tag>> {
fn get_thread_local_alloc_id(&self, def_id: DefId) -> Option<Pointer<Provenance>> {
self.thread_local_alloc_ids.borrow().get(&(def_id, self.active_thread)).cloned()
}
@ -264,7 +264,7 @@ fn get_thread_local_alloc_id(&self, def_id: DefId) -> Option<Pointer<Tag>> {
/// static for the active thread.
///
/// Panics if a thread local is initialized twice for the same thread.
fn set_thread_local_alloc(&self, def_id: DefId, ptr: Pointer<Tag>) {
fn set_thread_local_alloc(&self, def_id: DefId, ptr: Pointer<Provenance>) {
self.thread_local_alloc_ids
.borrow_mut()
.try_insert((def_id, self.active_thread), ptr)
@ -272,16 +272,20 @@ fn set_thread_local_alloc(&self, def_id: DefId, ptr: Pointer<Tag>) {
}
/// Borrow the stack of the active thread.
pub fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Tag, FrameData<'tcx>>] {
pub fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>] {
&self.threads[self.active_thread].stack
}
/// Mutably borrow the stack of the active thread.
fn active_thread_stack_mut(&mut self) -> &mut Vec<Frame<'mir, 'tcx, Tag, FrameData<'tcx>>> {
fn active_thread_stack_mut(
&mut self,
) -> &mut Vec<Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>> {
&mut self.threads[self.active_thread].stack
}
pub fn all_stacks(&self) -> impl Iterator<Item = &[Frame<'mir, 'tcx, Tag, FrameData<'tcx>>]> {
pub fn all_stacks(
&self,
) -> impl Iterator<Item = &[Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>]> {
self.threads.iter().map(|t| &t.stack[..])
}
@ -468,7 +472,7 @@ fn get_ready_callback(&mut self) -> Option<(ThreadId, TimeoutCallback<'mir, 'tcx
fn thread_terminated(
&mut self,
mut data_race: Option<&mut data_race::GlobalState>,
) -> Vec<Pointer<Tag>> {
) -> Vec<Pointer<Provenance>> {
let mut free_tls_statics = Vec::new();
{
let mut thread_local_statics = self.thread_local_alloc_ids.borrow_mut();
@ -589,7 +593,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn get_or_create_thread_local_alloc(
&mut self,
def_id: DefId,
) -> InterpResult<'tcx, Pointer<Tag>> {
) -> InterpResult<'tcx, Pointer<Provenance>> {
let this = self.eval_context_mut();
let tcx = this.tcx;
if let Some(old_alloc) = this.machine.threads.get_thread_local_alloc_id(def_id) {
@ -686,13 +690,15 @@ fn enable_thread(&mut self, thread_id: ThreadId) {
}
#[inline]
fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Tag, FrameData<'tcx>>] {
fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>] {
let this = self.eval_context_ref();
this.machine.threads.active_thread_stack()
}
#[inline]
fn active_thread_stack_mut(&mut self) -> &mut Vec<Frame<'mir, 'tcx, Tag, FrameData<'tcx>>> {
fn active_thread_stack_mut(
&mut self,
) -> &mut Vec<Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>> {
let this = self.eval_context_mut();
this.machine.threads.active_thread_stack_mut()
}