From 59d49c5d6d8f68e39677aada438708158027d6f7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 14 Jul 2017 11:06:29 -0700 Subject: [PATCH] fix checks when releasing write locks (101) --- src/librustc_mir/interpret/memory.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 19d6c3ed66d..36fb69cbe5b 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -63,9 +63,9 @@ pub fn range(offset: u64, len: u64) -> ops::Range { left..right } - pub fn contains(&self, offset: u64, len: u64) -> bool { + pub fn contained_in(&self, offset: u64, len: u64) -> bool { assert!(len > 0); - self.start <= offset && (offset + len) <= self.end + offset <= self.start && self.end <= (offset + len) } pub fn overlaps(&self, offset: u64, len: u64) -> bool { @@ -576,10 +576,6 @@ pub(crate) fn release_write_lock_until(&mut self, ptr: MemoryPointer, len: u64, let alloc = self.get_mut_unchecked(ptr.alloc_id)?; for (range, locks) in alloc.iter_lock_vecs_mut(ptr.offset, len) { - if !range.contains(ptr.offset, len) { - return Err(EvalError::Unimplemented(format!("miri does not support release part of a write-locked region"))); - } - // Check all locks in this region; make sure there are no conflicting write locks of other frames. // Also, if we will recover later, perform our release by changing the lock status. for lock in locks.iter_mut() { @@ -587,6 +583,9 @@ pub(crate) fn release_write_lock_until(&mut self, ptr: MemoryPointer, len: u64, if lock.lifetime.frame != cur_frame { return Err(EvalError::InvalidMemoryLockRelease { ptr, len }); } + if !range.contained_in(ptr.offset, len) { + return Err(EvalError::Unimplemented(format!("miri does not support release part of a write-locked region"))); + } let ptr = MemoryPointer { alloc_id : ptr.alloc_id, offset: range.offset() }; trace!("Releasing write lock at {:?}, size {} until {:?}", ptr, range.len(), release_until); if let Some(region) = release_until { @@ -594,7 +593,7 @@ pub(crate) fn release_write_lock_until(&mut self, ptr: MemoryPointer, len: u64, } } - // If we will not recove, we did not do anything above except for some checks. Now, erase the locks from the list. + // If we will not recover, we did not do anything above except for some checks. Now, erase the locks from the list. if let None = release_until { // Delete everything that's a held write lock. We already checked above that these are ours. // Unfortunately, this duplicates the condition from above. Is there anything we can do about this? @@ -615,7 +614,7 @@ pub(crate) fn locks_lifetime_ended(&mut self, ending_region: Option) match ending_region { None => true, // When a function ends, we end *all* its locks. It's okay for a function to still have lifetime-related locks // when it returns, that can happen e.g. with NLL when a lifetime can, but does not have to, extend beyond the - // end of a function. + // end of a function. Same for a function still having recoveries. Some(ending_region) => lock.lifetime.region == Some(ending_region), } }; -- 2.44.0