Skip to content

Commit 6a34911

Browse files
authored
Dont write unused unary expr when operator is increment/decrement (#1344)
currently, c2rust transpiled this code ```c void increment(){ int i = 5; i++; i--; --i; ++i; } ``` to this ```rust #[no_mangle] pub unsafe extern "C" fn increment() { let mut i: std::ffi::c_int = 5 as std::ffi::c_int; i += 1; i; i -= 1; i; i -= 1; i; i += 1; i; } ``` which contain useless `i` expression. this is because UnaryExpr can contain side effect expression which cannot be ignored, ~~however not all unary expr can contain side effects. this pull request limit to only Negate , Plus, Complement, and Not~~ . However we can limit it to only expr which is not pure.
2 parents c458496 + 76b8137 commit 6a34911

File tree

7 files changed

+99
-14
lines changed

7 files changed

+99
-14
lines changed

c2rust-transpile/src/translator/operators.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,13 +1034,19 @@ impl<'c> Translation<'c> {
10341034
}
10351035
}?;
10361036

1037-
// Unused unary operators (`-foo()`) may have side effects, so we need
1038-
// to add them to stmts.
1039-
if ctx.is_unused() {
1037+
// Some unused unary operators (`-foo()`) may have side effects, so we need
1038+
// to add them to stmts when name is not increment/decrement operator.
1039+
if ctx.is_unused()
1040+
&& !matches!(
1041+
name,
1042+
c_ast::UnOp::PreDecrement
1043+
| c_ast::UnOp::PreIncrement
1044+
| c_ast::UnOp::PostDecrement
1045+
| c_ast::UnOp::PostIncrement
1046+
)
1047+
{
10401048
let v = unary.clone().into_value();
1041-
unary
1042-
.stmts_mut()
1043-
.push(Stmt::Expr(*v, Some(Default::default())));
1049+
unary.add_stmt(mk().semi_stmt(v));
10441050
}
10451051
Ok(unary)
10461052
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
int puts(const char *str);
2+
3+
static int side_effect(){
4+
puts("the return of side effect");
5+
return 10;
6+
}
7+
8+
void unary_without_side_effect(){
9+
int i = 5;
10+
-i;
11+
+i;
12+
~i;
13+
!i;
14+
&i;
15+
*&i;
16+
i++;
17+
i--;
18+
--i;
19+
++i;
20+
}
21+
22+
void unary_with_side_effect(){
23+
char* arr[1] = {0};
24+
25+
-side_effect();
26+
+side_effect();
27+
~side_effect();
28+
!side_effect();
29+
&""[side_effect()];
30+
*arr[side_effect()];
31+
++arr[side_effect()];
32+
--arr[side_effect()];
33+
arr[side_effect()]++;
34+
arr[side_effect()]--;
35+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
source: c2rust-transpile/tests/snapshots.rs
3+
expression: cat tests/snapshots/exprs.rs
4+
input_file: c2rust-transpile/tests/snapshots/exprs.c
5+
---
6+
#![allow(
7+
dead_code,
8+
mutable_transmutes,
9+
non_camel_case_types,
10+
non_snake_case,
11+
non_upper_case_globals,
12+
unused_assignments,
13+
unused_mut
14+
)]
15+
extern "C" {
16+
fn puts(str: *const std::ffi::c_char) -> std::ffi::c_int;
17+
}
18+
unsafe extern "C" fn side_effect() -> std::ffi::c_int {
19+
puts(b"the return of side effect\0" as *const u8 as *const std::ffi::c_char);
20+
return 10 as std::ffi::c_int;
21+
}
22+
#[no_mangle]
23+
pub unsafe extern "C" fn unary_without_side_effect() {
24+
let mut i: std::ffi::c_int = 5 as std::ffi::c_int;
25+
-i;
26+
i;
27+
!i;
28+
(i == 0) as std::ffi::c_int;
29+
&mut i;
30+
i;
31+
i += 1;
32+
i -= 1;
33+
i -= 1;
34+
i += 1;
35+
}
36+
#[no_mangle]
37+
pub unsafe extern "C" fn unary_with_side_effect() {
38+
let mut arr: [*mut std::ffi::c_char; 1] = [0 as *mut std::ffi::c_char];
39+
-side_effect();
40+
side_effect();
41+
!side_effect();
42+
(side_effect() == 0) as std::ffi::c_int;
43+
&*(b"\0" as *const u8 as *const std::ffi::c_char).offset(::core::mem::transmute::<
44+
unsafe extern "C" fn() -> std::ffi::c_int,
45+
unsafe extern "C" fn() -> std::ffi::c_int,
46+
>(side_effect)() as isize) as *const std::ffi::c_char;
47+
*arr[side_effect() as usize];
48+
arr[side_effect() as usize] = (arr[side_effect() as usize]).offset(1);
49+
arr[side_effect() as usize] = (arr[side_effect() as usize]).offset(-1);
50+
arr[side_effect() as usize] = (arr[side_effect() as usize]).offset(1);
51+
arr[side_effect() as usize] = (arr[side_effect() as usize]).offset(-1);
52+
}

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ pub unsafe extern "C" fn factorial(mut n: std::ffi::c_ushort) -> std::ffi::c_ush
1919
while (i as std::ffi::c_int) < n as std::ffi::c_int {
2020
result = (result as std::ffi::c_int * i as std::ffi::c_int) as std::ffi::c_ushort;
2121
i = i.wrapping_add(1);
22-
i;
2322
}
2423
return result;
2524
}

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
---
22
source: c2rust-transpile/tests/snapshots.rs
3-
assertion_line: 67
43
expression: cat tests/snapshots/gotos.rs
54
input_file: c2rust-transpile/tests/snapshots/gotos.c
65
---
@@ -19,8 +18,6 @@ pub unsafe extern "C" fn sum(mut count: std::ffi::c_int) -> std::ffi::c_int {
1918
while !(count <= 0 as std::ffi::c_int) {
2019
x += count;
2120
count -= 1;
22-
count;
2321
}
2422
return x;
2523
}
26-

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@ pub unsafe extern "C" fn insertion_sort(n: std::ffi::c_int, p: *mut std::ffi::c_
2121
while j > 0 as std::ffi::c_int && *p.offset((j - 1 as std::ffi::c_int) as isize) > tmp {
2222
*p.offset(j as isize) = *p.offset((j - 1 as std::ffi::c_int) as isize);
2323
j -= 1;
24-
j;
2524
}
2625
*p.offset(j as isize) = tmp;
2726
i += 1;
28-
i;
2927
}
3028
}

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,12 +368,10 @@ pub unsafe extern "C" fn stmt_expr_inc() -> std::ffi::c_int {
368368
({
369369
*b += 1;
370370
*b;
371-
*b;
372371
*b
373372
});
374373
return ({
375374
*b += 1;
376-
*b;
377375
*b
378376
});
379377
}

0 commit comments

Comments
 (0)