Skip to content

Commit 0bcaa74

Browse files
authored
transpile: Flip comparison operators when negating in CFG (#1773)
Produces cleaner code, with relatively small changes.
2 parents 33d2293 + c2013aa commit 0bcaa74

10 files changed

Lines changed: 38 additions & 20 deletions

c2rust-transpile/src/cfg/structures.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use super::*;
44
use log::warn;
5-
use syn::{spanned::Spanned as _, ExprBreak, ExprIf, ExprUnary, Stmt};
5+
use syn::{spanned::Spanned as _, ExprBinary, ExprBreak, ExprIf, ExprUnary, Stmt};
66

77
use crate::rust_ast::{comment_store, set_span::SetSpan, BytePos, SpanExt};
88

@@ -1048,15 +1048,33 @@ impl StructureState {
10481048
/// Take the logical negation of an expression.
10491049
///
10501050
/// * Negating something of the form `!<expr>` produces `<expr>`
1051+
/// * Negating a comparison operator produces the opposite operator.
10511052
///
10521053
fn not(bool_expr: &Expr) -> Box<Expr> {
1053-
use syn::UnOp;
1054+
use syn::{BinOp::*, UnOp};
10541055
match *bool_expr {
10551056
Expr::Unary(ExprUnary {
10561057
op: UnOp::Not(_),
10571058
ref expr,
10581059
..
10591060
}) => Box::new(unparen(expr).clone()),
1061+
Expr::Binary(ExprBinary {
1062+
ref left,
1063+
op: op @ (Eq(_) | Ne(_) | Gt(_) | Lt(_) | Ge(_) | Le(_)),
1064+
ref right,
1065+
..
1066+
}) => {
1067+
let op = match op {
1068+
Eq(_) => Ne(Default::default()),
1069+
Ne(_) => Eq(Default::default()),
1070+
Gt(_) => Le(Default::default()),
1071+
Lt(_) => Ge(Default::default()),
1072+
Ge(_) => Lt(Default::default()),
1073+
Le(_) => Gt(Default::default()),
1074+
_ => unreachable!(),
1075+
};
1076+
mk().binary_expr(op, left.clone(), right.clone())
1077+
}
10601078
_ => mk().unary_expr(UnOp::Not(Default::default()), Box::new(bool_expr.clone())),
10611079
}
10621080
}

c2rust-transpile/tests/snapshots/snapshots__transpile-linux@irreducible.c.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub unsafe extern "C" fn irreducible(mut x: ::core::ffi::c_int) -> ::core::ffi::
3232
}
3333
}
3434
_ => {
35-
if !(x < 20 as ::core::ffi::c_int) {
35+
if x >= 20 as ::core::ffi::c_int {
3636
break 's_36;
3737
}
3838
x += 90 as ::core::ffi::c_int;

c2rust-transpile/tests/snapshots/snapshots__transpile-macos@irreducible.c.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub unsafe extern "C" fn irreducible(mut x: ::core::ffi::c_int) -> ::core::ffi::
3232
}
3333
}
3434
_ => {
35-
if !(x < 20 as ::core::ffi::c_int) {
35+
if x >= 20 as ::core::ffi::c_int {
3636
break 's_36;
3737
}
3838
x += 90 as ::core::ffi::c_int;

c2rust-transpile/tests/snapshots/snapshots__transpile@gotos.c.2021.clang15.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ expression: cat tests/snapshots/gotos.2021.clang15.rs
1414
#[no_mangle]
1515
pub unsafe extern "C" fn sum(mut count: ::core::ffi::c_int) -> ::core::ffi::c_int {
1616
let mut x: ::core::ffi::c_int = 0 as ::core::ffi::c_int;
17-
while !(count <= 0 as ::core::ffi::c_int) {
17+
while count > 0 as ::core::ffi::c_int {
1818
x += count;
1919
count -= 1;
2020
}

c2rust-transpile/tests/snapshots/snapshots__transpile@gotos.c.2024.clang15.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ expression: cat tests/snapshots/gotos.2024.clang15.rs
1515
#[unsafe(no_mangle)]
1616
pub unsafe extern "C" fn sum(mut count: ::core::ffi::c_int) -> ::core::ffi::c_int {
1717
let mut x: ::core::ffi::c_int = 0 as ::core::ffi::c_int;
18-
while !(count <= 0 as ::core::ffi::c_int) {
18+
while count > 0 as ::core::ffi::c_int {
1919
x += count;
2020
count -= 1;
2121
}

c2rust-transpile/tests/snapshots/snapshots__transpile@lift_const.c.2021.clang15.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub unsafe extern "C" fn lift_const(
2020
mut argv: *mut *mut ::core::ffi::c_char,
2121
) {
2222
let mut starts_with_a: ::core::ffi::c_int = 0;
23-
if !(argc == 3 as ::core::ffi::c_int) {
23+
if argc != 3 as ::core::ffi::c_int {
2424
starts_with_a = (**argv.offset(0 as ::core::ffi::c_int as isize) as ::core::ffi::c_int
2525
== 'a' as ::core::ffi::c_int) as ::core::ffi::c_int;
2626
if starts_with_a != 0 {

c2rust-transpile/tests/snapshots/snapshots__transpile@lift_const.c.2024.clang15.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub unsafe extern "C" fn lift_const(
2121
mut argv: *mut *mut ::core::ffi::c_char,
2222
) {
2323
let mut starts_with_a: ::core::ffi::c_int = 0;
24-
if !(argc == 3 as ::core::ffi::c_int) {
24+
if argc != 3 as ::core::ffi::c_int {
2525
starts_with_a = (**argv.offset(0 as ::core::ffi::c_int as isize) as ::core::ffi::c_int
2626
== 'a' as ::core::ffi::c_int) as ::core::ffi::c_int;
2727
if starts_with_a != 0 {

c2rust-transpile/tests/snapshots/snapshots__transpile@loops.c.snap

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub unsafe extern "C" fn infinite_loop(mut x: ::core::ffi::c_int) {
3838
pub unsafe extern "C" fn goto_loop(mut x: ::core::ffi::c_int) -> ::core::ffi::c_int {
3939
loop {
4040
x += 1 as ::core::ffi::c_int;
41-
if !(x != 0) {
41+
if x == 0 {
4242
break;
4343
}
4444
}
@@ -48,7 +48,7 @@ pub unsafe extern "C" fn goto_loop(mut x: ::core::ffi::c_int) -> ::core::ffi::c_
4848
pub unsafe extern "C" fn do_while_loop(mut x: ::core::ffi::c_int) -> ::core::ffi::c_int {
4949
loop {
5050
x += 1 as ::core::ffi::c_int;
51-
if !(x != 0) {
51+
if x == 0 {
5252
break;
5353
}
5454
}
@@ -206,7 +206,7 @@ pub unsafe extern "C" fn do_loop_single_continue(mut x: ::core::ffi::c_int) -> :
206206
}
207207
x += 1 as ::core::ffi::c_int;
208208
}
209-
if !(x != 0) {
209+
if x == 0 {
210210
break;
211211
}
212212
}
@@ -229,7 +229,7 @@ pub unsafe extern "C" fn do_loop_multi_continue(mut x: ::core::ffi::c_int) -> ::
229229
}
230230
x += 2 as ::core::ffi::c_int;
231231
}
232-
if !(x != 0) {
232+
if x == 0 {
233233
break;
234234
}
235235
}
@@ -354,14 +354,14 @@ pub unsafe extern "C" fn goto_loops(mut x: ::core::ffi::c_int) -> ::core::ffi::c
354354
if x != 0 {
355355
loop {
356356
x += 1 as ::core::ffi::c_int;
357-
if !(x != 0) {
357+
if x == 0 {
358358
break '_D;
359359
}
360360
}
361361
} else {
362362
loop {
363363
x += 2 as ::core::ffi::c_int;
364-
if !(x != 0) {
364+
if x == 0 {
365365
break '_D;
366366
}
367367
}
@@ -375,14 +375,14 @@ pub unsafe extern "C" fn goto_into_loops(mut x: ::core::ffi::c_int) {
375375
if x != 0 {
376376
loop {
377377
x += 1 as ::core::ffi::c_int;
378-
if !(x != 0) {
378+
if x == 0 {
379379
break '_D;
380380
}
381381
}
382382
} else {
383383
loop {
384384
x += 2 as ::core::ffi::c_int;
385-
if !(x != 0) {
385+
if x == 0 {
386386
break '_D;
387387
}
388388
}
@@ -394,14 +394,14 @@ pub unsafe extern "C" fn goto_separate_loops(mut x: ::core::ffi::c_int) {
394394
if x != 0 {
395395
loop {
396396
x += 1 as ::core::ffi::c_int;
397-
if !(x != 0) {
397+
if x == 0 {
398398
break;
399399
}
400400
}
401401
} else {
402402
loop {
403403
x += 2 as ::core::ffi::c_int;
404-
if !(x != 0) {
404+
if x == 0 {
405405
break;
406406
}
407407
}

c2rust-transpile/tests/snapshots/snapshots__transpile@varargs.c.2021.x86_64.linux.clang15.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ pub unsafe extern "C" fn my_printf(mut fmt: *const ::core::ffi::c_char, mut c2ru
6868
match *fmt as ::core::ffi::c_int {
6969
37 => {
7070
fmt = fmt.offset(1);
71-
if !(*fmt == 0) {
71+
if *fmt != 0 {
7272
match *fmt as ::core::ffi::c_int {
7373
105 | 100 => {
7474
printf(

c2rust-transpile/tests/snapshots/snapshots__transpile@varargs.c.2024.x86_64.linux.clang15.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub unsafe extern "C" fn my_printf(mut fmt: *const ::core::ffi::c_char, mut c2ru
6969
match *fmt as ::core::ffi::c_int {
7070
37 => {
7171
fmt = fmt.offset(1);
72-
if !(*fmt == 0) {
72+
if *fmt != 0 {
7373
match *fmt as ::core::ffi::c_int {
7474
105 | 100 => {
7575
printf(

0 commit comments

Comments
 (0)