Skip to content

Commit f15b563

Browse files
committed
fix error read-read reporting when there's also an unsynchronized non-atomic read (which is fine)
1 parent e94c18e commit f15b563

File tree

4 files changed

+45
-22
lines changed

4 files changed

+45
-22
lines changed

src/tools/miri/src/concurrency/data_race.rs

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -847,13 +847,27 @@ impl VClockAlloc {
847847
let mut action = Cow::Borrowed(action);
848848
let mut involves_non_atomic = true;
849849
let write_clock;
850-
#[rustfmt::skip]
851850
let (other_action, other_thread, other_clock) =
852-
if mem_clocks.write.1 > current_clocks.clock[mem_clocks.write.0] {
851+
// First check the atomic-nonatomic cases. If it looks like multiple
852+
// cases apply, this one should take precedence, else it might look like
853+
// we are reporting races between two non-atomic reads.
854+
if !is_atomic &&
855+
let Some(atomic) = mem_clocks.atomic() &&
856+
let Some(idx) = Self::find_gt_index(&atomic.write_vector, &current_clocks.clock)
857+
{
858+
(format!("Atomic Store"), idx, &atomic.write_vector)
859+
} else if !is_atomic &&
860+
let Some(atomic) = mem_clocks.atomic() &&
861+
let Some(idx) = Self::find_gt_index(&atomic.read_vector, &current_clocks.clock)
862+
{
863+
(format!("Atomic Load"), idx, &atomic.read_vector)
864+
// Then check races with non-atomic writes/reads.
865+
} else if mem_clocks.write.1 > current_clocks.clock[mem_clocks.write.0] {
853866
write_clock = mem_clocks.write();
854867
(mem_clocks.write_type.get_descriptor().to_owned(), mem_clocks.write.0, &write_clock)
855868
} else if let Some(idx) = Self::find_gt_index(&mem_clocks.read, &current_clocks.clock) {
856869
(format!("Read"), idx, &mem_clocks.read)
870+
// Finally, mixed-size races.
857871
} else if is_atomic && let Some(atomic) = mem_clocks.atomic() && atomic.size != access_size {
858872
// This is only a race if we are not synchronized with all atomic accesses, so find
859873
// the one we are not synchronized with.
@@ -871,27 +885,8 @@ impl VClockAlloc {
871885
"Failed to report data-race for mixed-size access: no race found"
872886
)
873887
}
874-
} else if !is_atomic {
875-
if let Some(atomic) = mem_clocks.atomic() {
876-
if let Some(idx) = Self::find_gt_index(&atomic.write_vector, &current_clocks.clock)
877-
{
878-
(format!("Atomic Store"), idx, &atomic.write_vector)
879-
} else if let Some(idx) =
880-
Self::find_gt_index(&atomic.read_vector, &current_clocks.clock)
881-
{
882-
(format!("Atomic Load"), idx, &atomic.read_vector)
883-
} else {
884-
unreachable!(
885-
"Failed to report data-race for non-atomic operation: no race found"
886-
)
887-
}
888-
} else {
889-
unreachable!(
890-
"Failed to report data-race for non-atomic operation: no atomic component"
891-
)
892-
}
893888
} else {
894-
unreachable!("Failed to report data-race for atomic operation")
889+
unreachable!("Failed to report data-race")
895890
};
896891

897892
// Load elaborated thread information about the racing thread actions.

src/tools/miri/tests/fail/data_race/read_read_race1.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ fn main() {
1515
});
1616
s.spawn(|| {
1717
thread::yield_now();
18+
19+
// We also put a non-atomic access here, but that should *not* be reported.
20+
let ptr = &a as *const AtomicU16 as *mut u16;
21+
unsafe { ptr.read() };
22+
// Then do the atomic access.
1823
a.load(Ordering::SeqCst);
1924
//~^ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Atomic Load on thread `<unnamed>`
2025
});

src/tools/miri/tests/fail/data_race/read_read_race2.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@ fn main() {
1010

1111
thread::scope(|s| {
1212
s.spawn(|| {
13+
// We also put a non-atomic access here, but that should *not* be reported.
14+
let ptr = &a as *const AtomicU16 as *mut u16;
15+
unsafe { ptr.read() };
16+
// Then do the atomic access.
1317
a.load(Ordering::SeqCst);
1418
});
1519
s.spawn(|| {
1620
thread::yield_now();
21+
1722
let ptr = &a as *const AtomicU16 as *mut u16;
1823
unsafe { ptr.read() };
1924
//~^ ERROR: Data race detected between (1) Atomic Load on thread `<unnamed>` and (2) Read on thread `<unnamed>`

src/tools/miri/tests/pass/concurrency/simple.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,23 @@ fn panic_named() {
6262
.unwrap_err();
6363
}
6464

65+
// This is not a data race!
66+
fn shared_readonly() {
67+
use std::sync::Arc;
68+
69+
let x = Arc::new(42i32);
70+
let h = thread::spawn({
71+
let x = Arc::clone(&x);
72+
move || {
73+
assert_eq!(*x, 42);
74+
}
75+
});
76+
77+
assert_eq!(*x, 42);
78+
79+
h.join().unwrap();
80+
}
81+
6582
fn main() {
6683
create_and_detach();
6784
create_and_join();
@@ -71,6 +88,7 @@ fn main() {
7188
create_nested_and_join();
7289
create_move_in();
7390
create_move_out();
91+
shared_readonly();
7492
panic();
7593
panic_named();
7694
}

0 commit comments

Comments
 (0)