Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

c2rust generates invalid Rust code for compound literals with pointers requiring mutability #1166

Open
Yeaseen opened this issue Nov 23, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@Yeaseen
Copy link
Contributor

Yeaseen commented Nov 23, 2024

Description

c2rust produces invalid Rust code when translating compound literals involving pointers and expressions (e.g., condition--). The generated Rust code incorrectly declares a temporary variable as immutable (let) while attempting to create a mutable reference (&mut) to it, leading to a Rust compiler error.

Source C code

int main() {
    int condition = 1; 
    int *single_value = &(int){condition--}; 
    return 0;
}

Expected Behavior

c2rust should generate valid Rust code that handles the mutability requirements of the compound literal, resulting in successful compilation.

Translated Rust code

#![allow(dead_code, mutable_transmutes, non_camel_case_types, non_snake_case, non_upper_case_globals, unused_assignments, unused_mut)]
use ::transpiled_code::*;
unsafe fn main_0() -> libc::c_int {
    let mut condition: libc::c_int = 1 as libc::c_int;
    let fresh0 = condition;
    condition = condition - 1;
    let mut single_value: *mut libc::c_int = &mut fresh0 as *mut libc::c_int;
    return 0 as libc::c_int;
}
pub fn main() {
    unsafe { ::std::process::exit(main_0() as i32) }
}

Cargo build failure

The translated Rust code incorrectly declares a temporary variable (fresh0) as immutable and attempts to create a mutable reference to it, causing the following Rust compile-time error.

error[E0596]: cannot borrow `fresh0` as mutable, as it is not declared as mutable
 --> src/runner.rs:7:46
  |
7 |     let mut single_value: *mut libc::c_int = &mut fresh0 as *mut libc::c_int;
  |                                              ^^^^^^^^^^^ cannot borrow as mutable

Observation

I think &(int){condition--} involves modifying condition, but the temporary value created by the compound literal (fresh0) does not need to be mutable, as it is never modified in the original C code. Instead, c2rust should declare fresh0 as immutable and adjust the pointer type accordingly to align with C semantics.

let mut condition: libc::c_int = 1 as libc::c_int;
let fresh0 = condition; // fresh0 is immutable
condition = condition - 1; // condition is decremented
let single_value: *const libc::c_int = &fresh0; // Use a const pointer
@Yeaseen
Copy link
Contributor Author

Yeaseen commented Dec 3, 2024

@kkysen this persists in v0.19.0 as well. I would appreciate it if you would confirm this at your convenience. Thank you.

@kkysen kkysen added the bug Something isn't working label Dec 6, 2024
@kkysen
Copy link
Contributor

kkysen commented Dec 6, 2024

@kkysen this persists in v0.19.0 as well. I would appreciate it if you would confirm this at your convenience. Thank you.

Yup, this definitely looks like a bug. Thanks for finding so many!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants