diff --git a/src/concurrency/data_race.rs b/src/concurrency/data_race.rs index bcbdb616514f..410c2b9c3ddf 100644 --- a/src/concurrency/data_race.rs +++ b/src/concurrency/data_race.rs @@ -997,14 +997,23 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> { )?; // Ensure the allocation is mutable. Even failing (read-only) compare_exchange need mutable // memory on many targets (i.e., they segfault if taht memory is mapped read-only), and - // atomic loads can be implemented via compare_exchange on some targets. See - // . + // atomic loads can be implemented via compare_exchange on some targets. There could + // possibly be some very specific exceptions to this, see + // for details. // We avoid `get_ptr_alloc` since we do *not* want to run the access hooks -- the actual // access will happen later. let (alloc_id, _offset, _prov) = this.ptr_try_get_alloc_id(place.ptr).expect("there are no zero-sized atomic accesses"); if this.get_alloc_mutability(alloc_id)? == Mutability::Not { - throw_ub_format!("atomic operations cannot be performed on read-only memory"); + // FIXME: make this prettier, once these messages have separate title/span/help messages. + throw_ub_format!( + "atomic operations cannot be performed on read-only memory\n\ + many platforms require atomic read-modify-write instructions to be performed on writeable memory, even if the operation fails \ + (and is hence nominally read-only)\n\ + some platforms implement (some) atomic loads via compare-exchange, which means they do not work on read-only memory; \ + it is possible that we could have an exception permitting this for specific kinds of loads\n\ + please report an issue at if this is a problem for you" + ); } Ok(()) } diff --git a/tests/fail/concurrency/read_only_atomic_cmpxchg.stderr b/tests/fail/concurrency/read_only_atomic_cmpxchg.stderr index 2753c492266b..b90dc5c9d6cd 100644 --- a/tests/fail/concurrency/read_only_atomic_cmpxchg.stderr +++ b/tests/fail/concurrency/read_only_atomic_cmpxchg.stderr @@ -1,8 +1,14 @@ error: Undefined Behavior: atomic operations cannot be performed on read-only memory + many platforms require atomic read-modify-write instructions to be performed on writeable memory, even if the operation fails (and is hence nominally read-only) + some platforms implement (some) atomic loads via compare-exchange, which means they do not work on read-only memory; it is possible that we could have an exception permitting this for specific kinds of loads + please report an issue at if this is a problem for you --> $DIR/read_only_atomic_cmpxchg.rs:LL:CC | LL | x.compare_exchange(1, 2, Ordering::Relaxed, Ordering::Relaxed).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ atomic operations cannot be performed on read-only memory +many platforms require atomic read-modify-write instructions to be performed on writeable memory, even if the operation fails (and is hence nominally read-only) +some platforms implement (some) atomic loads via compare-exchange, which means they do not work on read-only memory; it is possible that we could have an exception permitting this for specific kinds of loads +please report an issue at if this is a problem for you | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/concurrency/read_only_atomic_load.stderr b/tests/fail/concurrency/read_only_atomic_load.stderr index 588081afc62c..b19d3755fbb0 100644 --- a/tests/fail/concurrency/read_only_atomic_load.stderr +++ b/tests/fail/concurrency/read_only_atomic_load.stderr @@ -1,8 +1,14 @@ error: Undefined Behavior: atomic operations cannot be performed on read-only memory + many platforms require atomic read-modify-write instructions to be performed on writeable memory, even if the operation fails (and is hence nominally read-only) + some platforms implement (some) atomic loads via compare-exchange, which means they do not work on read-only memory; it is possible that we could have an exception permitting this for specific kinds of loads + please report an issue at if this is a problem for you --> $DIR/read_only_atomic_load.rs:LL:CC | LL | x.load(Ordering::Relaxed); | ^^^^^^^^^^^^^^^^^^^^^^^^^ atomic operations cannot be performed on read-only memory +many platforms require atomic read-modify-write instructions to be performed on writeable memory, even if the operation fails (and is hence nominally read-only) +some platforms implement (some) atomic loads via compare-exchange, which means they do not work on read-only memory; it is possible that we could have an exception permitting this for specific kinds of loads +please report an issue at if this is a problem for you | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information