-
Notifications
You must be signed in to change notification settings - Fork 248
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 fails to handle increment or decrement operations within compound literals #1165
Comments
I found post-decrement is also problematic, making it a general flaw. #include<stdio.h>
struct s {
int i;
};
int f(void) {
struct s *p;
int j = 42;
p = &((struct s){j--}); // Compound literal with address-of operator
return p->i;
}
int main() {
int result = f();
printf("Result of f: %d\n", result);
return 0;
} Same error. |
I believe it may just be enough to remove the offending assertion: diff --git a/c2rust-transpile/src/translator/structs.rs b/c2rust-transpile/src/translator/structs.rs
index fae47c4d1..4eb75e18a 100644
--- a/c2rust-transpile/src/translator/structs.rs
+++ b/c2rust-transpile/src/translator/structs.rs
@@ -544,12 +544,6 @@ impl<'a> Translation<'a> {
Both(field_id, (field_name, _, bitfield_width, use_inner_type)) => {
let mut expr = self.convert_expr(ctx.used(), *field_id)?;
- if !expr.is_pure() {
- return Err(TranslationError::generic(
- "Expected no statements in field expression",
- ));
- }
-
if use_inner_type {
// See comment above
expr = expr.map(|fi| mk().anon_field_expr(fi, 0)); This results in the following generated code: #![allow(dead_code, mutable_transmutes, non_camel_case_types, non_snake_case, non_upper_case_globals, unused_assignments, unused_mut)]
extern "C" {
fn printf(_: *const libc::c_char, _: ...) -> libc::c_int;
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct s {
pub i: libc::c_int,
}
#[no_mangle]
pub unsafe extern "C" fn f() -> libc::c_int {
let mut p: *mut s = 0 as *mut s;
let mut j: libc::c_int = 42 as libc::c_int;
let fresh0 = j;
j = j + 1;
p = &mut {
let mut init = s { i: fresh0 };
init
} as *mut s;
return (*p).i;
}
unsafe fn main_0() -> libc::c_int {
let mut result: libc::c_int = f();
printf(b"Result of f: %d\n\0" as *const u8 as *const libc::c_char, result);
return 0 as libc::c_int;
}
pub fn main() {
unsafe { ::std::process::exit(main_0() as i32) }
} There are two other places where we make the same assertion in |
Description
The
c2rust
tool fails to translate valid C code that uses the post-increment operator (j++
) inside a compound literal. This occurs even though the code is valid and compiles successfully with standard C compilers like GCC or Clang.If a simple integer (e.g.,
42
) is used instead ofj++
,c2rust
handles the compound literal without any issues.Source C code
Actual Behavior
c2rust
fails to translate the function f and gives the following error:$ c2rust-transpile compile_commands.json -e -o transpiled_code --binary runner Transpiling runner.c error: Failed to translate f: Expected no statements in field expression
Expected Behavior
c2rust
should translate the compound literal with j++ into equivalent Rust code.Observation
Interestingly,
c2rust
can translate the following C code perfectly, and the translated rust code prints42
The text was updated successfully, but these errors were encountered: