Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 12 additions & 14 deletions src/concurrency/data_race.rs
Original file line number Diff line number Diff line change
Expand Up @@ -838,18 +838,18 @@ impl VClockAlloc {
&self,
alloc_id: AllocId,
range: AllocRange,
global: &GlobalState,
thread_mgr: &ThreadManager<'_, '_>,
machine: &MiriMachine<'_, '_>,
) -> InterpResult<'tcx> {
let global = machine.data_race.as_ref().unwrap();
if global.race_detecting() {
let (index, clocks) = global.current_thread_state(thread_mgr);
let (index, clocks) = global.current_thread_state(&machine.threads);
let mut alloc_ranges = self.alloc_ranges.borrow_mut();
for (offset, range) in alloc_ranges.iter_mut(range.start, range.size) {
if let Err(DataRace) = range.read_race_detect(&clocks, index) {
// Report data-race.
return Self::report_data_race(
global,
thread_mgr,
&machine.threads,
range,
"Read",
false,
Expand All @@ -869,17 +869,17 @@ impl VClockAlloc {
alloc_id: AllocId,
range: AllocRange,
write_type: WriteType,
global: &mut GlobalState,
thread_mgr: &ThreadManager<'_, '_>,
machine: &mut MiriMachine<'_, '_>,
) -> InterpResult<'tcx> {
let global = machine.data_race.as_mut().unwrap();
if global.race_detecting() {
let (index, clocks) = global.current_thread_state(thread_mgr);
let (index, clocks) = global.current_thread_state(&machine.threads);
for (offset, range) in self.alloc_ranges.get_mut().iter_mut(range.start, range.size) {
if let Err(DataRace) = range.write_race_detect(&clocks, index, write_type) {
// Report data-race
return Self::report_data_race(
global,
thread_mgr,
&machine.threads,
range,
write_type.get_descriptor(),
false,
Expand All @@ -901,10 +901,9 @@ impl VClockAlloc {
&mut self,
alloc_id: AllocId,
range: AllocRange,
global: &mut GlobalState,
thread_mgr: &ThreadManager<'_, '_>,
machine: &mut MiriMachine<'_, '_>,
) -> InterpResult<'tcx> {
self.unique_access(alloc_id, range, WriteType::Write, global, thread_mgr)
self.unique_access(alloc_id, range, WriteType::Write, machine)
}

/// Detect data-races for an unsynchronized deallocate operation, will not perform
Expand All @@ -915,10 +914,9 @@ impl VClockAlloc {
&mut self,
alloc_id: AllocId,
range: AllocRange,
global: &mut GlobalState,
thread_mgr: &ThreadManager<'_, '_>,
machine: &mut MiriMachine<'_, '_>,
) -> InterpResult<'tcx> {
self.unique_access(alloc_id, range, WriteType::Deallocate, global, thread_mgr)
self.unique_access(alloc_id, range, WriteType::Deallocate, machine)
}
}

Expand Down
40 changes: 7 additions & 33 deletions src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1003,21 +1003,12 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
range: AllocRange,
) -> InterpResult<'tcx> {
if let Some(data_race) = &alloc_extra.data_race {
data_race.read(
alloc_id,
range,
machine.data_race.as_ref().unwrap(),
&machine.threads,
)?;
data_race.read(alloc_id, range, machine)?;
}
if let Some(stacked_borrows) = &alloc_extra.stacked_borrows {
stacked_borrows.borrow_mut().before_memory_read(
alloc_id,
prov_extra,
range,
machine.stacked_borrows.as_ref().unwrap(),
machine,
)?;
stacked_borrows
.borrow_mut()
.before_memory_read(alloc_id, prov_extra, range, machine)?;
}
if let Some(weak_memory) = &alloc_extra.weak_memory {
weak_memory.memory_accessed(range, machine.data_race.as_ref().unwrap());
Expand All @@ -1034,21 +1025,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
range: AllocRange,
) -> InterpResult<'tcx> {
if let Some(data_race) = &mut alloc_extra.data_race {
data_race.write(
alloc_id,
range,
machine.data_race.as_mut().unwrap(),
&machine.threads,
)?;
data_race.write(alloc_id, range, machine)?;
}
if let Some(stacked_borrows) = &mut alloc_extra.stacked_borrows {
stacked_borrows.get_mut().before_memory_write(
alloc_id,
prov_extra,
range,
machine.stacked_borrows.as_ref().unwrap(),
machine,
)?;
stacked_borrows.get_mut().before_memory_write(alloc_id, prov_extra, range, machine)?;
}
if let Some(weak_memory) = &alloc_extra.weak_memory {
weak_memory.memory_accessed(range, machine.data_race.as_ref().unwrap());
Expand All @@ -1068,19 +1048,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
machine.emit_diagnostic(NonHaltingDiagnostic::FreedAlloc(alloc_id));
}
if let Some(data_race) = &mut alloc_extra.data_race {
data_race.deallocate(
alloc_id,
range,
machine.data_race.as_mut().unwrap(),
&machine.threads,
)?;
data_race.deallocate(alloc_id, range, machine)?;
}
if let Some(stacked_borrows) = &mut alloc_extra.stacked_borrows {
stacked_borrows.get_mut().before_memory_deallocation(
alloc_id,
prove_extra,
range,
machine.stacked_borrows.as_ref().unwrap(),
machine,
)
} else {
Expand Down
19 changes: 13 additions & 6 deletions src/stacked_borrows/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,10 +353,12 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {

/// Report a descriptive error when `new` could not be granted from `derived_from`.
#[inline(never)] // This is only called on fatal code paths
pub(super) fn grant_error(&self, perm: Permission, stack: &Stack) -> InterpError<'tcx> {
pub(super) fn grant_error(&self, stack: &Stack) -> InterpError<'tcx> {
let Operation::Retag(op) = &self.operation else {
unreachable!("grant_error should only be called during a retag")
};
let perm =
op.permission.expect("`start_grant` must be called before calling `grant_error`");
let action = format!(
"trying to retag from {:?} for {:?} permission at {:?}[{:#x}]",
op.orig_tag,
Expand All @@ -374,8 +376,11 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {
/// Report a descriptive error when `access` is not permitted based on `tag`.
#[inline(never)] // This is only called on fatal code paths
pub(super) fn access_error(&self, stack: &Stack) -> InterpError<'tcx> {
let Operation::Access(op) = &self.operation else {
unreachable!("access_error should only be called during an access")
// Deallocation and retagging also do an access as part of their thing, so handle that here, too.
let op = match &self.operation {
Operation::Access(op) => op,
Operation::Retag(_) => return self.grant_error(stack),
Operation::Dealloc(_) => return self.dealloc_error(stack),
};
let action = format!(
"attempting a {access} using {tag:?} at {alloc_id:?}[{offset:#x}]",
Expand Down Expand Up @@ -428,14 +433,16 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {
}

#[inline(never)] // This is only called on fatal code paths
pub fn dealloc_error(&self) -> InterpError<'tcx> {
pub fn dealloc_error(&self, stack: &Stack) -> InterpError<'tcx> {
let Operation::Dealloc(op) = &self.operation else {
unreachable!("dealloc_error should only be called during a deallocation")
};
err_sb_ub(
format!(
"no item granting write access for deallocation to tag {:?} at {:?} found in borrow stack",
op.tag, self.history.id,
"attempting deallocation using {tag:?} at {alloc_id:?}{cause}",
tag = op.tag,
alloc_id = self.history.id,
cause = error_cause(stack, op.tag),
),
None,
op.tag.and_then(|tag| self.get_logs_relevant_to(tag, None)),
Expand Down
Loading