Skip to content

C2Rust generates invalid Rust code for __atomic_exchange_n on bool (uses atomic_xchg_relaxed<bool> which is unsupported) #1648

@lynae99

Description

@lynae99

When translating C code that uses the GCC atomic builtin __atomic_exchange_n on a bool variable, C2Rust generates Rust code that calls core::intrinsics::atomic_xchg_relaxed with type bool.
However, Rust's atomic_xchg_relaxed intrinsic only supports basic integer types, and does not support bool. As a result, the generated Rust code fails to compile with error E0511 (invalid monomorphization).
This affects multiple exchange intrinsics (atomic_xchg_relaxed, atomic_xchg_acquire, atomic_xchg_seqcst, …) whenever the pointee type is bool.
Reproducer

#include <stdio.h>
#include <stdbool.h>

int main() {
    // Test: Exchange on boolean with relaxed ordering
    bool flag = true;

    bool old = __atomic_exchange_n(&flag, false, __ATOMIC_RELAXED);

    printf("AtomicExchangeBool: Input=true, New=false, Old=%s\n", old ? "true" : "false");
    printf("AtomicExchangeBool: After exchange, flag=%s\n", flag ? "true" : "false");

    return 0;
}

C2Rust-Generated Rust

#![allow(
    dead_code,
    non_camel_case_types,
    non_snake_case,
    non_upper_case_globals,
    unused_assignments,
    unused_mut
)]
#![feature(core_intrinsics)]
extern "C" {
    fn printf(__format: *const ::core::ffi::c_char, ...) -> ::core::ffi::c_int;
}
pub const true_0: ::core::ffi::c_int = 1 as ::core::ffi::c_int;
pub const false_0: ::core::ffi::c_int = 0 as ::core::ffi::c_int;
unsafe fn main_0() -> ::core::ffi::c_int {
    let mut flag: bool = true_0 != 0;
    let mut old: bool = ::core::intrinsics::atomic_xchg_relaxed(&mut flag, false_0 != 0);
    printf(
        b"AtomicExchangeBool: Input=true, New=false, Old=%s\n\0" as *const u8
            as *const ::core::ffi::c_char,
        if old as ::core::ffi::c_int != 0 {
            b"true\0" as *const u8 as *const ::core::ffi::c_char
        } else {
            b"false\0" as *const u8 as *const ::core::ffi::c_char
        },
    );
    printf(
        b"AtomicExchangeBool: After exchange, flag=%s\n\0" as *const u8
            as *const ::core::ffi::c_char,
        if flag as ::core::ffi::c_int != 0 {
            b"true\0" as *const u8 as *const ::core::ffi::c_char
        } else {
            b"false\0" as *const u8 as *const ::core::ffi::c_char
        },
    );
    return 0 as ::core::ffi::c_int;
}
pub const __ATOMIC_RELAXED: ::core::ffi::c_int = 0 as ::core::ffi::c_int;
pub fn main() {
    unsafe { ::std::process::exit(main_0() as i32) }
}

Observed
The generated Rust code fails to compile with:

error[E0511]: invalid monomorphization of atomic_xchg_relaxed intrinsic: expected basic integer type, found bool

Environment

  • c2rust version: v0.21.0
  • platform:Ubuntu 24.04
  • Rust: nightly-2022-08-08

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions