Skip to content
Open
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
13 changes: 10 additions & 3 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,8 @@ declare_lint! {
///
/// - Passing `Ordering::Release` or `Ordering::AcqRel` as the failure
/// ordering for any of `AtomicType::compare_exchange`,
/// `AtomicType::compare_exchange_weak`, or `AtomicType::fetch_update`.
/// `AtomicType::compare_exchange_weak`, `AtomicType::update`, or
/// `AtomicType::try_update`.
INVALID_ATOMIC_ORDERING,
Deny,
"usage of invalid atomic ordering in atomic operations and memory fences"
Expand Down Expand Up @@ -1118,13 +1119,19 @@ impl InvalidAtomicOrdering {
let Some((method, args)) = Self::inherent_atomic_method_call(
cx,
expr,
&[sym::fetch_update, sym::compare_exchange, sym::compare_exchange_weak],
&[
sym::update,
sym::try_update,
sym::fetch_update,
sym::compare_exchange,
sym::compare_exchange_weak,
],
) else {
return;
};

let fail_order_arg = match method {
sym::fetch_update => &args[1],
sym::update | sym::try_update | sym::fetch_update => &args[1],
sym::compare_exchange | sym::compare_exchange_weak => &args[3],
_ => return,
};
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2273,6 +2273,7 @@ symbols! {
try_from_fn,
try_into,
try_trait_v2,
try_update,
tt,
tuple,
tuple_indexing,
Expand Down Expand Up @@ -2390,6 +2391,7 @@ symbols! {
unwrap,
unwrap_binder,
unwrap_or,
update,
use_cloned,
use_extern_macros,
use_nested_groups,
Expand Down
49 changes: 0 additions & 49 deletions tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs

This file was deleted.

83 changes: 0 additions & 83 deletions tests/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr

This file was deleted.

144 changes: 144 additions & 0 deletions tests/ui/lint/lint-invalid-atomic-ordering-update.rs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please update test name, since its now not only fetch_update test or create another test for this feature

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to not separate this into separate files, because it would make it more difficult to keep the tests in sync.

I tried to maybe use revisions approach, but it would still lead to each error message being written 3 times, and wouldn't really simplify the code that much.

I decided to just rename it from "fetch-update" to simply "update" as it is the word that all 3 methods have in common.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's fine, let's wait on CI green

Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
//@ only-x86_64
#![feature(atomic_try_update)]

use std::sync::atomic::{AtomicIsize, Ordering};

fn main() {
// `fetch_update` testing
let x = AtomicIsize::new(0);

// Allowed ordering combos
let _ = x.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |old| Some(old + 1));
let _ = x.try_update(Ordering::Relaxed, Ordering::Relaxed, |old| Some(old + 1));
let _ = x.update(Ordering::Relaxed, Ordering::Relaxed, |old| old + 1);

let _ = x.fetch_update(Ordering::Relaxed, Ordering::Acquire, |old| Some(old + 1));
let _ = x.try_update(Ordering::Relaxed, Ordering::Acquire, |old| Some(old + 1));
let _ = x.update(Ordering::Relaxed, Ordering::Acquire, |old| old + 1);

let _ = x.fetch_update(Ordering::Relaxed, Ordering::SeqCst, |old| Some(old + 1));
let _ = x.try_update(Ordering::Relaxed, Ordering::SeqCst, |old| Some(old + 1));
let _ = x.update(Ordering::Relaxed, Ordering::SeqCst, |old| old + 1);

let _ = x.fetch_update(Ordering::Acquire, Ordering::Relaxed, |old| Some(old + 1));
let _ = x.try_update(Ordering::Acquire, Ordering::Relaxed, |old| Some(old + 1));
let _ = x.update(Ordering::Acquire, Ordering::Relaxed, |old| old + 1);

let _ = x.fetch_update(Ordering::Acquire, Ordering::Acquire, |old| Some(old + 1));
let _ = x.try_update(Ordering::Acquire, Ordering::Acquire, |old| Some(old + 1));
let _ = x.update(Ordering::Acquire, Ordering::Acquire, |old| old + 1);

let _ = x.fetch_update(Ordering::Acquire, Ordering::SeqCst, |old| Some(old + 1));
let _ = x.try_update(Ordering::Acquire, Ordering::SeqCst, |old| Some(old + 1));
let _ = x.update(Ordering::Acquire, Ordering::SeqCst, |old| old + 1);

let _ = x.fetch_update(Ordering::Release, Ordering::Relaxed, |old| Some(old + 1));
let _ = x.try_update(Ordering::Release, Ordering::Relaxed, |old| Some(old + 1));
let _ = x.update(Ordering::Release, Ordering::Relaxed, |old| old + 1);

let _ = x.fetch_update(Ordering::Release, Ordering::Acquire, |old| Some(old + 1));
let _ = x.try_update(Ordering::Release, Ordering::Acquire, |old| Some(old + 1));
let _ = x.update(Ordering::Release, Ordering::Acquire, |old| old + 1);

let _ = x.fetch_update(Ordering::Release, Ordering::SeqCst, |old| Some(old + 1));
let _ = x.try_update(Ordering::Release, Ordering::SeqCst, |old| Some(old + 1));
let _ = x.update(Ordering::Release, Ordering::SeqCst, |old| old + 1);

let _ = x.fetch_update(Ordering::AcqRel, Ordering::Relaxed, |old| Some(old + 1));
let _ = x.try_update(Ordering::AcqRel, Ordering::Relaxed, |old| Some(old + 1));
let _ = x.update(Ordering::AcqRel, Ordering::Relaxed, |old| old + 1);

let _ = x.fetch_update(Ordering::AcqRel, Ordering::Acquire, |old| Some(old + 1));
let _ = x.try_update(Ordering::AcqRel, Ordering::Acquire, |old| Some(old + 1));
let _ = x.update(Ordering::AcqRel, Ordering::Acquire, |old| old + 1);

let _ = x.fetch_update(Ordering::AcqRel, Ordering::SeqCst, |old| Some(old + 1));
let _ = x.try_update(Ordering::AcqRel, Ordering::SeqCst, |old| Some(old + 1));
let _ = x.update(Ordering::AcqRel, Ordering::SeqCst, |old| old + 1);

let _ = x.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |old| Some(old + 1));
let _ = x.try_update(Ordering::SeqCst, Ordering::Relaxed, |old| Some(old + 1));
let _ = x.update(Ordering::SeqCst, Ordering::Relaxed, |old| old + 1);

let _ = x.fetch_update(Ordering::SeqCst, Ordering::Acquire, |old| Some(old + 1));
let _ = x.try_update(Ordering::SeqCst, Ordering::Acquire, |old| Some(old + 1));
let _ = x.update(Ordering::SeqCst, Ordering::Acquire, |old| old + 1);

let _ = x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |old| Some(old + 1));
let _ = x.try_update(Ordering::SeqCst, Ordering::SeqCst, |old| Some(old + 1));
let _ = x.update(Ordering::SeqCst, Ordering::SeqCst, |old| old + 1);

// AcqRel is always forbidden as a failure ordering

let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1));
//~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.try_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1));
//~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.update(Ordering::Relaxed, Ordering::AcqRel, |old| old + 1);
//~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel`

let _ = x.fetch_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1));
//~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.try_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1));
//~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.update(Ordering::Acquire, Ordering::AcqRel, |old| old + 1);
//~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel`

let _ = x.fetch_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1));
//~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.try_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1));
//~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.update(Ordering::Release, Ordering::AcqRel, |old| old + 1);
//~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel`

let _ = x.fetch_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1));
//~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.try_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1));
//~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.update(Ordering::AcqRel, Ordering::AcqRel, |old| old + 1);
//~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel`

let _ = x.fetch_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1));
//~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.try_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1));
//~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.update(Ordering::SeqCst, Ordering::AcqRel, |old| old + 1);
//~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel`

// Release is always forbidden as a failure ordering

let _ = x.fetch_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1));
//~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.try_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1));
//~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.update(Ordering::Relaxed, Ordering::Release, |old| old + 1);
//~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel`

let _ = x.fetch_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1));
//~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.try_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1));
//~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.update(Ordering::Acquire, Ordering::Release, |old| old + 1);
//~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel`

let _ = x.fetch_update(Ordering::Release, Ordering::Release, |old| Some(old + 1));
//~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.try_update(Ordering::Release, Ordering::Release, |old| Some(old + 1));
//~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.update(Ordering::Release, Ordering::Release, |old| old + 1);
//~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel`

let _ = x.fetch_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1));
//~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.try_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1));
//~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.update(Ordering::AcqRel, Ordering::Release, |old| old + 1);
//~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel`

let _ = x.fetch_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1));
//~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.try_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1));
//~^ ERROR `try_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.update(Ordering::SeqCst, Ordering::Release, |old| old + 1);
//~^ ERROR `update`'s failure ordering may not be `Release` or `AcqRel`
}
Loading
Loading