diff --git a/src/tools/miri/src/concurrency/init_once.rs b/src/tools/miri/src/concurrency/init_once.rs index d709e4e6eaedb..9c2c6ae133023 100644 --- a/src/tools/miri/src/concurrency/init_once.rs +++ b/src/tools/miri/src/concurrency/init_once.rs @@ -1,7 +1,6 @@ use std::collections::VecDeque; use rustc_index::Idx; -use rustc_middle::ty::layout::TyAndLayout; use super::sync::EvalContextExtPriv as _; use super::vector_clock::VClock; @@ -30,14 +29,12 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn init_once_get_or_create_id( &mut self, - lock_op: &OpTy<'tcx>, - lock_layout: TyAndLayout<'tcx>, + lock: &MPlaceTy<'tcx>, offset: u64, ) -> InterpResult<'tcx, InitOnceId> { let this = self.eval_context_mut(); this.get_or_create_id( - lock_op, - lock_layout, + lock, offset, |ecx| &mut ecx.machine.sync.init_onces, |_| Ok(Default::default()), diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index a6a2a03b1b080..7098cc5b95bef 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -1,10 +1,11 @@ +use std::any::Any; use std::collections::{hash_map::Entry, VecDeque}; use std::ops::Not; use std::time::Duration; use rustc_data_structures::fx::FxHashMap; use rustc_index::{Idx, IndexVec}; -use rustc_middle::ty::layout::TyAndLayout; +use rustc_target::abi::Size; use super::init_once::InitOnce; use super::vector_clock::VClock; @@ -66,27 +67,6 @@ pub(super) use declare_id; declare_id!(MutexId); -/// The mutex kind. -#[derive(Debug, Clone, Copy)] -#[non_exhaustive] -pub enum MutexKind { - Invalid, - Normal, - Default, - Recursive, - ErrorCheck, -} - -#[derive(Debug)] -/// Additional data that may be used by shim implementations. -pub struct AdditionalMutexData { - /// The mutex kind, used by some mutex implementations like pthreads mutexes. - pub kind: MutexKind, - - /// The address of the mutex. - pub address: u64, -} - /// The mutex state. #[derive(Default, Debug)] struct Mutex { @@ -100,18 +80,11 @@ struct Mutex { clock: VClock, /// Additional data that can be set by shim implementations. - data: Option, + data: Option>, } declare_id!(RwLockId); -#[derive(Debug)] -/// Additional data that may be used by shim implementations. -pub struct AdditionalRwLockData { - /// The address of the rwlock. - pub address: u64, -} - /// The read-write lock state. #[derive(Default, Debug)] struct RwLock { @@ -146,7 +119,7 @@ struct RwLock { clock_current_readers: VClock, /// Additional data that can be set by shim implementations. - data: Option, + data: Option>, } declare_id!(CondvarId); @@ -206,21 +179,21 @@ pub(super) trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { #[inline] fn get_or_create_id( &mut self, - lock_op: &OpTy<'tcx>, - lock_layout: TyAndLayout<'tcx>, + lock: &MPlaceTy<'tcx>, offset: u64, get_objs: impl for<'a> Fn(&'a mut MiriInterpCx<'tcx>) -> &'a mut IndexVec, create_obj: impl for<'a> FnOnce(&'a mut MiriInterpCx<'tcx>) -> InterpResult<'tcx, T>, ) -> InterpResult<'tcx, Option> { let this = self.eval_context_mut(); - let value_place = - this.deref_pointer_and_offset(lock_op, offset, lock_layout, this.machine.layouts.u32)?; + let offset = Size::from_bytes(offset); + assert!(lock.layout.size >= offset + this.machine.layouts.u32.size); + let id_place = lock.offset(offset, this.machine.layouts.u32, this)?; let next_index = get_objs(this).next_index(); // Since we are lazy, this update has to be atomic. let (old, success) = this .atomic_compare_exchange_scalar( - &value_place, + &id_place, &ImmTy::from_uint(0u32, this.machine.layouts.u32), Scalar::from_u32(next_index.to_u32()), AtomicRwOrd::Relaxed, // deliberately *no* synchronization @@ -258,18 +231,18 @@ pub(super) trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { /// - `obj` must be the new sync object. fn create_id( &mut self, - lock_op: &OpTy<'tcx>, - lock_layout: TyAndLayout<'tcx>, + lock: &MPlaceTy<'tcx>, offset: u64, get_objs: impl for<'a> Fn(&'a mut MiriInterpCx<'tcx>) -> &'a mut IndexVec, obj: T, ) -> InterpResult<'tcx, Id> { let this = self.eval_context_mut(); - let value_place = - this.deref_pointer_and_offset(lock_op, offset, lock_layout, this.machine.layouts.u32)?; + let offset = Size::from_bytes(offset); + assert!(lock.layout.size >= offset + this.machine.layouts.u32.size); + let id_place = lock.offset(offset, this.machine.layouts.u32, this)?; let new_index = get_objs(this).push(obj); - this.write_scalar(Scalar::from_u32(new_index.to_u32()), &value_place)?; + this.write_scalar(Scalar::from_u32(new_index.to_u32()), &id_place)?; Ok(new_index) } @@ -302,15 +275,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Eagerly create and initialize a new mutex. fn mutex_create( &mut self, - lock_op: &OpTy<'tcx>, - lock_layout: TyAndLayout<'tcx>, + lock: &MPlaceTy<'tcx>, offset: u64, - data: Option, + data: Option>, ) -> InterpResult<'tcx, MutexId> { let this = self.eval_context_mut(); this.create_id( - lock_op, - lock_layout, + lock, offset, |ecx| &mut ecx.machine.sync.mutexes, Mutex { data, ..Default::default() }, @@ -321,17 +292,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// `initialize_data` must return any additional data that a user wants to associate with the mutex. fn mutex_get_or_create_id( &mut self, - lock_op: &OpTy<'tcx>, - lock_layout: TyAndLayout<'tcx>, + lock: &MPlaceTy<'tcx>, offset: u64, initialize_data: impl for<'a> FnOnce( &'a mut MiriInterpCx<'tcx>, - ) -> InterpResult<'tcx, Option>, + ) -> InterpResult<'tcx, Option>>, ) -> InterpResult<'tcx, MutexId> { let this = self.eval_context_mut(); this.get_or_create_id( - lock_op, - lock_layout, + lock, offset, |ecx| &mut ecx.machine.sync.mutexes, |ecx| initialize_data(ecx).map(|data| Mutex { data, ..Default::default() }), @@ -340,28 +309,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } /// Retrieve the additional data stored for a mutex. - fn mutex_get_data<'a>(&'a mut self, id: MutexId) -> Option<&'a AdditionalMutexData> + fn mutex_get_data<'a, T: 'static>(&'a mut self, id: MutexId) -> Option<&'a T> where 'tcx: 'a, { let this = self.eval_context_ref(); - this.machine.sync.mutexes[id].data.as_ref() + this.machine.sync.mutexes[id].data.as_deref().and_then(|p| p.downcast_ref::()) } fn rwlock_get_or_create_id( &mut self, - lock_op: &OpTy<'tcx>, - lock_layout: TyAndLayout<'tcx>, + lock: &MPlaceTy<'tcx>, offset: u64, initialize_data: impl for<'a> FnOnce( &'a mut MiriInterpCx<'tcx>, - ) - -> InterpResult<'tcx, Option>, + ) -> InterpResult<'tcx, Option>>, ) -> InterpResult<'tcx, RwLockId> { let this = self.eval_context_mut(); this.get_or_create_id( - lock_op, - lock_layout, + lock, offset, |ecx| &mut ecx.machine.sync.rwlocks, |ecx| initialize_data(ecx).map(|data| RwLock { data, ..Default::default() }), @@ -370,24 +336,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } /// Retrieve the additional data stored for a rwlock. - fn rwlock_get_data<'a>(&'a mut self, id: RwLockId) -> Option<&'a AdditionalRwLockData> + fn rwlock_get_data<'a, T: 'static>(&'a mut self, id: RwLockId) -> Option<&'a T> where 'tcx: 'a, { let this = self.eval_context_ref(); - this.machine.sync.rwlocks[id].data.as_ref() + this.machine.sync.rwlocks[id].data.as_deref().and_then(|p| p.downcast_ref::()) } fn condvar_get_or_create_id( &mut self, - lock_op: &OpTy<'tcx>, - lock_layout: TyAndLayout<'tcx>, + lock: &MPlaceTy<'tcx>, offset: u64, ) -> InterpResult<'tcx, CondvarId> { let this = self.eval_context_mut(); this.get_or_create_id( - lock_op, - lock_layout, + lock, offset, |ecx| &mut ecx.machine.sync.condvars, |_| Ok(Default::default()), diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 273b1107ed0b9..8a59206943d18 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -133,10 +133,7 @@ pub use crate::concurrency::{ cpu_affinity::MAX_CPUS, data_race::{AtomicFenceOrd, AtomicReadOrd, AtomicRwOrd, AtomicWriteOrd, EvalContextExt as _}, init_once::{EvalContextExt as _, InitOnceId}, - sync::{ - AdditionalMutexData, AdditionalRwLockData, CondvarId, EvalContextExt as _, MutexId, - MutexKind, RwLockId, SynchronizationObjects, - }, + sync::{CondvarId, EvalContextExt as _, MutexId, RwLockId, SynchronizationObjects}, thread::{ BlockReason, EvalContextExt as _, StackEmptyCallback, ThreadId, ThreadManager, TimeoutAnchor, TimeoutClock, UnblockCallback, diff --git a/src/tools/miri/src/shims/unix/macos/sync.rs b/src/tools/miri/src/shims/unix/macos/sync.rs index 882c08cca154c..8f9237a1d46ea 100644 --- a/src/tools/miri/src/shims/unix/macos/sync.rs +++ b/src/tools/miri/src/shims/unix/macos/sync.rs @@ -14,12 +14,13 @@ use crate::*; impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { - fn os_unfair_lock_getid(&mut self, lock_op: &OpTy<'tcx>) -> InterpResult<'tcx, MutexId> { + fn os_unfair_lock_getid(&mut self, lock_ptr: &OpTy<'tcx>) -> InterpResult<'tcx, MutexId> { let this = self.eval_context_mut(); + let lock = this.deref_pointer(lock_ptr)?; // os_unfair_lock holds a 32-bit value, is initialized with zero and // must be assumed to be opaque. Therefore, we can just store our // internal mutex ID in the structure without anyone noticing. - this.mutex_get_or_create_id(lock_op, this.libc_ty_layout("os_unfair_lock"), 0, |_| Ok(None)) + this.mutex_get_or_create_id(&lock, 0, |_| Ok(None)) } } diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index 9d664985fd41e..dacbe973af260 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -18,10 +18,10 @@ fn mutexattr_kind_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u fn mutexattr_get_kind<'tcx>( ecx: &MiriInterpCx<'tcx>, - attr_op: &OpTy<'tcx>, + attr_ptr: &OpTy<'tcx>, ) -> InterpResult<'tcx, i32> { ecx.deref_pointer_and_read( - attr_op, + attr_ptr, mutexattr_kind_offset(ecx)?, ecx.libc_ty_layout("pthread_mutexattr_t"), ecx.machine.layouts.i32, @@ -31,11 +31,11 @@ fn mutexattr_get_kind<'tcx>( fn mutexattr_set_kind<'tcx>( ecx: &mut MiriInterpCx<'tcx>, - attr_op: &OpTy<'tcx>, + attr_ptr: &OpTy<'tcx>, kind: i32, ) -> InterpResult<'tcx, ()> { ecx.deref_pointer_and_write( - attr_op, + attr_ptr, mutexattr_kind_offset(ecx)?, Scalar::from_i32(kind), ecx.libc_ty_layout("pthread_mutexattr_t"), @@ -59,6 +59,25 @@ fn is_mutex_kind_normal<'tcx>(ecx: &MiriInterpCx<'tcx>, kind: i32) -> InterpResu Ok(kind == (mutex_normal_kind | PTHREAD_MUTEX_NORMAL_FLAG)) } +/// The mutex kind. +#[derive(Debug, Clone, Copy)] +pub enum MutexKind { + Normal, + Default, + Recursive, + ErrorCheck, +} + +#[derive(Debug)] +/// Additional data that we attach with each mutex instance. +pub struct AdditionalMutexData { + /// The mutex kind, used by some mutex implementations like pthreads mutexes. + pub kind: MutexKind, + + /// The address of the mutex. + pub address: u64, +} + // pthread_mutex_t is between 24 and 48 bytes, depending on the platform. // We ignore the platform layout and store our own fields: // - id: u32 @@ -94,15 +113,14 @@ fn mutex_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> { /// Eagerly create and initialize a new mutex. fn mutex_create<'tcx>( ecx: &mut MiriInterpCx<'tcx>, - mutex_op: &OpTy<'tcx>, + mutex_ptr: &OpTy<'tcx>, kind: i32, ) -> InterpResult<'tcx> { - // FIXME: might be worth changing mutex_create to take the mplace - // rather than the `OpTy`. - let address = ecx.read_pointer(mutex_op)?.addr().bytes(); + let mutex = ecx.deref_pointer(mutex_ptr)?; + let address = mutex.ptr().addr().bytes(); let kind = translate_kind(ecx, kind)?; - let data = Some(AdditionalMutexData { address, kind }); - ecx.mutex_create(mutex_op, ecx.libc_ty_layout("pthread_mutex_t"), mutex_id_offset(ecx)?, data)?; + let data = Box::new(AdditionalMutexData { address, kind }); + ecx.mutex_create(&mutex, mutex_id_offset(ecx)?, Some(data))?; Ok(()) } @@ -112,27 +130,23 @@ fn mutex_create<'tcx>( /// return an error if it has. fn mutex_get_id<'tcx>( ecx: &mut MiriInterpCx<'tcx>, - mutex_op: &OpTy<'tcx>, + mutex_ptr: &OpTy<'tcx>, ) -> InterpResult<'tcx, MutexId> { - let address = ecx.read_pointer(mutex_op)?.addr().bytes(); - - // FIXME: might be worth changing mutex_get_or_create_id to take the mplace - // rather than the `OpTy`. - let id = ecx.mutex_get_or_create_id( - mutex_op, - ecx.libc_ty_layout("pthread_mutex_t"), - mutex_id_offset(ecx)?, - |ecx| { - // This is called if a static initializer was used and the lock has not been assigned - // an ID yet. We have to determine the mutex kind from the static initializer. - let kind = kind_from_static_initializer(ecx, mutex_op)?; - - Ok(Some(AdditionalMutexData { kind, address })) - }, - )?; + let mutex = ecx.deref_pointer(mutex_ptr)?; + let address = mutex.ptr().addr().bytes(); + + let id = ecx.mutex_get_or_create_id(&mutex, mutex_id_offset(ecx)?, |ecx| { + // This is called if a static initializer was used and the lock has not been assigned + // an ID yet. We have to determine the mutex kind from the static initializer. + let kind = kind_from_static_initializer(ecx, &mutex)?; + + Ok(Some(Box::new(AdditionalMutexData { kind, address }))) + })?; // Check that the mutex has not been moved since last use. - let data = ecx.mutex_get_data(id).expect("data should be always exist for pthreads"); + let data = ecx + .mutex_get_data::(id) + .expect("data should always exist for pthreads"); if data.address != address { throw_ub_format!("pthread_mutex_t can't be moved after first use") } @@ -143,20 +157,15 @@ fn mutex_get_id<'tcx>( /// Returns the kind of a static initializer. fn kind_from_static_initializer<'tcx>( ecx: &MiriInterpCx<'tcx>, - mutex_op: &OpTy<'tcx>, + mutex: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, MutexKind> { // Only linux has static initializers other than PTHREAD_MUTEX_DEFAULT. let kind = match &*ecx.tcx.sess.target.os { "linux" => { let offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 }; - - ecx.deref_pointer_and_read( - mutex_op, - offset, - ecx.libc_ty_layout("pthread_mutex_t"), - ecx.machine.layouts.i32, - )? - .to_i32()? + let kind_place = + mutex.offset(Size::from_bytes(offset), ecx.machine.layouts.i32, ecx)?; + ecx.read_scalar(&kind_place)?.to_i32()? } | "illumos" | "solaris" | "macos" => ecx.eval_libc_i32("PTHREAD_MUTEX_DEFAULT"), os => throw_unsup_format!("`pthread_mutex` is not supported on {os}"), @@ -183,6 +192,13 @@ fn translate_kind<'tcx>(ecx: &MiriInterpCx<'tcx>, kind: i32) -> InterpResult<'tc // We ignore the platform layout and store our own fields: // - id: u32 +#[derive(Debug)] +/// Additional data that may be used by shim implementations. +pub struct AdditionalRwLockData { + /// The address of the rwlock. + pub address: u64, +} + fn rwlock_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> { let offset = match &*ecx.tcx.sess.target.os { "linux" | "illumos" | "solaris" => 0, @@ -211,19 +227,19 @@ fn rwlock_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> { fn rwlock_get_id<'tcx>( ecx: &mut MiriInterpCx<'tcx>, - rwlock_op: &OpTy<'tcx>, + rwlock_ptr: &OpTy<'tcx>, ) -> InterpResult<'tcx, RwLockId> { - let address = ecx.read_pointer(rwlock_op)?.addr().bytes(); + let rwlock = ecx.deref_pointer(rwlock_ptr)?; + let address = rwlock.ptr().addr().bytes(); - let id = ecx.rwlock_get_or_create_id( - rwlock_op, - ecx.libc_ty_layout("pthread_rwlock_t"), - rwlock_id_offset(ecx)?, - |_| Ok(Some(AdditionalRwLockData { address })), - )?; + let id = ecx.rwlock_get_or_create_id(&rwlock, rwlock_id_offset(ecx)?, |_| { + Ok(Some(Box::new(AdditionalRwLockData { address }))) + })?; // Check that the rwlock has not been moved since last use. - let data = ecx.rwlock_get_data(id).expect("data should be always exist for pthreads"); + let data = ecx + .rwlock_get_data::(id) + .expect("data should always exist for pthreads"); if data.address != address { throw_ub_format!("pthread_rwlock_t can't be moved after first use") } @@ -246,10 +262,10 @@ fn condattr_clock_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u fn condattr_get_clock_id<'tcx>( ecx: &MiriInterpCx<'tcx>, - attr_op: &OpTy<'tcx>, + attr_ptr: &OpTy<'tcx>, ) -> InterpResult<'tcx, i32> { ecx.deref_pointer_and_read( - attr_op, + attr_ptr, condattr_clock_offset(ecx)?, ecx.libc_ty_layout("pthread_condattr_t"), ecx.machine.layouts.i32, @@ -259,11 +275,11 @@ fn condattr_get_clock_id<'tcx>( fn condattr_set_clock_id<'tcx>( ecx: &mut MiriInterpCx<'tcx>, - attr_op: &OpTy<'tcx>, + attr_ptr: &OpTy<'tcx>, clock_id: i32, ) -> InterpResult<'tcx, ()> { ecx.deref_pointer_and_write( - attr_op, + attr_ptr, condattr_clock_offset(ecx)?, Scalar::from_i32(clock_id), ecx.libc_ty_layout("pthread_condattr_t"), @@ -337,21 +353,18 @@ fn cond_clock_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> u64 { fn cond_get_id<'tcx>( ecx: &mut MiriInterpCx<'tcx>, - cond_op: &OpTy<'tcx>, + cond_ptr: &OpTy<'tcx>, ) -> InterpResult<'tcx, CondvarId> { - ecx.condvar_get_or_create_id( - cond_op, - ecx.libc_ty_layout("pthread_cond_t"), - cond_id_offset(ecx)?, - ) + let cond = ecx.deref_pointer(cond_ptr)?; + ecx.condvar_get_or_create_id(&cond, cond_id_offset(ecx)?) } fn cond_reset_id<'tcx>( ecx: &mut MiriInterpCx<'tcx>, - cond_op: &OpTy<'tcx>, + cond_ptr: &OpTy<'tcx>, ) -> InterpResult<'tcx, ()> { ecx.deref_pointer_and_write( - cond_op, + cond_ptr, cond_id_offset(ecx)?, Scalar::from_i32(0), ecx.libc_ty_layout("pthread_cond_t"), @@ -361,10 +374,10 @@ fn cond_reset_id<'tcx>( fn cond_get_clock_id<'tcx>( ecx: &MiriInterpCx<'tcx>, - cond_op: &OpTy<'tcx>, + cond_ptr: &OpTy<'tcx>, ) -> InterpResult<'tcx, i32> { ecx.deref_pointer_and_read( - cond_op, + cond_ptr, cond_clock_offset(ecx), ecx.libc_ty_layout("pthread_cond_t"), ecx.machine.layouts.i32, @@ -374,11 +387,11 @@ fn cond_get_clock_id<'tcx>( fn cond_set_clock_id<'tcx>( ecx: &mut MiriInterpCx<'tcx>, - cond_op: &OpTy<'tcx>, + cond_ptr: &OpTy<'tcx>, clock_id: i32, ) -> InterpResult<'tcx, ()> { ecx.deref_pointer_and_write( - cond_op, + cond_ptr, cond_clock_offset(ecx), Scalar::from_i32(clock_id), ecx.libc_ty_layout("pthread_cond_t"), @@ -490,8 +503,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); let id = mutex_get_id(this, mutex_op)?; - let kind = - this.mutex_get_data(id).expect("data should always exist for pthread mutexes").kind; + let kind = this + .mutex_get_data::(id) + .expect("data should always exist for pthread mutexes") + .kind; let ret = if this.mutex_is_locked(id) { let owner_thread = this.mutex_get_owner(id); @@ -509,10 +524,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.mutex_lock(id); 0 } - _ => - throw_unsup_format!( - "called pthread_mutex_lock on an unsupported type of mutex" - ), } } } else { @@ -528,8 +539,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); let id = mutex_get_id(this, mutex_op)?; - let kind = - this.mutex_get_data(id).expect("data should always exist for pthread mutexes").kind; + let kind = this + .mutex_get_data::(id) + .expect("data should always exist for pthread mutexes") + .kind; Ok(Scalar::from_i32(if this.mutex_is_locked(id) { let owner_thread = this.mutex_get_owner(id); @@ -543,10 +556,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.mutex_lock(id); 0 } - _ => - throw_unsup_format!( - "called pthread_mutex_trylock on an unsupported type of mutex" - ), } } } else { @@ -560,8 +569,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); let id = mutex_get_id(this, mutex_op)?; - let kind = - this.mutex_get_data(id).expect("data should always exist for pthread mutexes").kind; + let kind = this + .mutex_get_data::(id) + .expect("data should always exist for pthread mutexes") + .kind; if let Some(_old_locked_count) = this.mutex_unlock(id)? { // The mutex was locked by the current thread. @@ -581,10 +592,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ), MutexKind::ErrorCheck | MutexKind::Recursive => Ok(Scalar::from_i32(this.eval_libc_i32("EPERM"))), - _ => - throw_unsup_format!( - "called pthread_mutex_unlock on an unsupported type of mutex" - ), } } } diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index e1fbb77037cfb..51b0129356baa 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -10,9 +10,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Windows sync primitives are pointer sized. // We only use the first 4 bytes for the id. - fn init_once_get_id(&mut self, init_once_op: &OpTy<'tcx>) -> InterpResult<'tcx, InitOnceId> { + fn init_once_get_id(&mut self, init_once_ptr: &OpTy<'tcx>) -> InterpResult<'tcx, InitOnceId> { let this = self.eval_context_mut(); - this.init_once_get_or_create_id(init_once_op, this.windows_ty_layout("INIT_ONCE"), 0) + let init_once = this.deref_pointer(init_once_ptr)?; + this.init_once_get_or_create_id(&init_once, 0) } /// Returns `true` if we were succssful, `false` if we would block.