|
4 | 4 | use super::*; |
5 | 5 |
|
6 | 6 | use crate::format_translation_err; |
7 | | -use crate::translator::atomics::CAtomicBinOp; |
| 7 | +use crate::translator::atomics::{order_ty_name, CAtomicBinOp}; |
8 | 8 | use crate::translator::simd::simd_fn_from_builtin_fn; |
9 | 9 | use c2rust_rust_tools::RustEdition::Edition2024; |
10 | 10 | use log::warn; |
11 | 11 | use std::sync::atomic::Ordering::Acquire; |
| 12 | +use std::sync::atomic::Ordering::Relaxed; |
12 | 13 | use std::sync::atomic::Ordering::Release; |
13 | 14 | use std::sync::atomic::Ordering::SeqCst; |
14 | 15 |
|
@@ -525,6 +526,43 @@ impl<'c> Translation<'c> { |
525 | 526 | ) |
526 | 527 | } |
527 | 528 |
|
| 529 | + // `__atomic_thread_fence` is a full fence (`atomic_fence`); |
| 530 | + // `__atomic_signal_fence` only fences the compiler |
| 531 | + // (`compiler_fence`). The order picks the intrinsic at |
| 532 | + // compile time, so we only support a constant one. A relaxed fence |
| 533 | + // is a no-op (and Rust has no relaxed fence intrinsic), so we drop it. |
| 534 | + "__atomic_thread_fence" | "__atomic_signal_fence" => { |
| 535 | + let order = self.convert_memordering(args[0]).ok_or_else(|| { |
| 536 | + format_translation_err!( |
| 537 | + self.ast_context.display_loc(src_loc), |
| 538 | + "non-constant memory order argument to {} is not supported", |
| 539 | + builtin_name |
| 540 | + ) |
| 541 | + })?; |
| 542 | + let call_expr = if order == Relaxed { |
| 543 | + mk().tuple_expr(vec![]) |
| 544 | + } else if builtin_name == "__atomic_thread_fence" { |
| 545 | + mk().call_expr(self.atomic_intrinsic_expr("fence", &[order]), vec![]) |
| 546 | + } else { |
| 547 | + let ordering = mk().abs_path_expr(vec![ |
| 548 | + "core", |
| 549 | + "sync", |
| 550 | + "atomic", |
| 551 | + "Ordering", |
| 552 | + order_ty_name(order), |
| 553 | + ]); |
| 554 | + mk().call_expr( |
| 555 | + mk().abs_path_expr(vec!["core", "sync", "atomic", "compiler_fence"]), |
| 556 | + vec![ordering], |
| 557 | + ) |
| 558 | + }; |
| 559 | + self.convert_side_effects_expr( |
| 560 | + ctx, |
| 561 | + WithStmts::new_val(call_expr), |
| 562 | + "Builtin is not supposed to be used", |
| 563 | + ) |
| 564 | + } |
| 565 | + |
528 | 566 | "__sync_lock_test_and_set_1" |
529 | 567 | | "__sync_lock_test_and_set_2" |
530 | 568 | | "__sync_lock_test_and_set_4" |
|
0 commit comments