immunant / c2rust

Migrate C code to Rust
https://c2rust.com/
Other
4.03k stars 244 forks source link

c2rust fails to handle increment or decrement operations within compound literals #1165

Open Yeaseen opened 6 days ago

Yeaseen commented 6 days ago

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 of j++, c2rust handles the compound literal without any issues.

Source C code

#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 and post-increment operator
    return p->i;
}

int main() {
    int result = f();
    printf("Result of f: %d\n", result);
    return 0;
}

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 prints 42

#include<stdio.h>
struct s { 
    int i; 
};

int f(void) {
    struct s *p;
    p = &((struct s){42}); // Compound literal with address-of operator
    return p->i;
}

int main() {
    int result = f();
    print("%d\n", result);
    return 0;
}
Yeaseen commented 6 days ago

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.