From f33bf80b1418a3372d1f709b77c143c132deb96f Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 17:46:40 +0100 Subject: [PATCH 01/23] Convert condition on ternary operator --- cpp2rust/converter/converter.cpp | 2 +- cpp2rust/converter/models/converter_refcount.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 6d56236..6e7d0f7 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -2173,7 +2173,7 @@ void Converter::EmitStmtExprTail(clang::Expr *tail) { Convert(tail); } bool Converter::VisitConditionalOperator(clang::ConditionalOperator *expr) { StrCat(keyword::kIf); - Convert(expr->getCond()); + ConvertCondition(expr->getCond()); { PushBrace then_brace(*this); if (expr->isLValue() && !isRValue() && !expr->getType()->isFunctionType()) { diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 645cf63..b9fbb0e 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -615,7 +615,8 @@ bool ConverterRefCount::ConvertIncAndDec(clang::UnaryOperator *expr) { bool ConverterRefCount::VisitConditionalOperator( clang::ConditionalOperator *expr) { - StrCat(keyword::kIf, ConvertRValue(expr->getCond())); + StrCat(keyword::kIf); + ConvertCondition(expr->getCond()); { PushBrace then_brace(*this); StrCat(ConvertFresh(expr->getTrueExpr())); From ea324cd35f4c7569086f0bd1b6f12cde3a3da0e5 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 17:49:16 +0100 Subject: [PATCH 02/23] Handle logical not --- cpp2rust/converter/converter.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 6e7d0f7..3882875 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -2130,6 +2130,20 @@ bool Converter::VisitUnaryOperator(clang::UnaryOperator *expr) { Convert(sub_expr); computed_expr_type_ = ComputedExprType::FreshValue; break; + case clang::UO_LNot: { + bool needs_int_cast = expr->getType()->isIntegerType(); + PushParen paren_cast(*this, needs_int_cast); + StrCat(token::kNot); + { + PushParen paren(*this); + ConvertCondition(sub_expr); + } + if (needs_int_cast) { + ConvertCast(expr->getType()); + } + computed_expr_type_ = ComputedExprType::FreshValue; + break; + } case clang::UO_Minus: if (auto *literal = clang::dyn_cast(sub_expr)) { if (sub_expr->getType()->isUnsignedIntegerType()) { From 61cce271e0b752d4bbe359754fd93bc01b9219c1 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 17:50:10 +0100 Subject: [PATCH 03/23] Update tests --- tests/unit/bool_condition_enum.cpp | 29 ++++++ tests/unit/bool_condition_enum_c.c | 30 ++++++ tests/unit/bool_condition_int.cpp | 63 ++++++++++++ tests/unit/bool_condition_int_c.c | 64 ++++++++++++ tests/unit/bool_condition_logical.cpp | 49 ++++++++++ tests/unit/bool_condition_logical_c.c | 50 ++++++++++ tests/unit/bool_condition_ptr.cpp | 45 +++++++++ tests/unit/bool_condition_ptr_c.c | 46 +++++++++ .../unit/out/refcount/bool_condition_enum.rs | 51 ++++++++++ .../out/refcount/bool_condition_enum_c.rs | 49 ++++++++++ tests/unit/out/refcount/bool_condition_int.rs | 71 ++++++++++++++ .../unit/out/refcount/bool_condition_int_c.rs | 71 ++++++++++++++ .../out/refcount/bool_condition_logical.rs | 98 +++++++++++++++++++ .../out/refcount/bool_condition_logical_c.rs | 82 ++++++++++++++++ tests/unit/out/refcount/bool_condition_ptr.rs | 50 ++++++++++ .../unit/out/refcount/bool_condition_ptr_c.rs | 48 +++++++++ tests/unit/out/unsafe/bool_condition_enum.rs | 51 ++++++++++ .../unit/out/unsafe/bool_condition_enum_c.rs | 51 ++++++++++ tests/unit/out/unsafe/bool_condition_int.rs | 69 +++++++++++++ tests/unit/out/unsafe/bool_condition_int_c.rs | 69 +++++++++++++ .../unit/out/unsafe/bool_condition_logical.rs | 79 +++++++++++++++ .../out/unsafe/bool_condition_logical_c.rs | 81 +++++++++++++++ tests/unit/out/unsafe/bool_condition_ptr.rs | 50 ++++++++++ tests/unit/out/unsafe/bool_condition_ptr_c.rs | 50 ++++++++++ 24 files changed, 1396 insertions(+) create mode 100644 tests/unit/bool_condition_enum.cpp create mode 100644 tests/unit/bool_condition_enum_c.c create mode 100644 tests/unit/bool_condition_int.cpp create mode 100644 tests/unit/bool_condition_int_c.c create mode 100644 tests/unit/bool_condition_logical.cpp create mode 100644 tests/unit/bool_condition_logical_c.c create mode 100644 tests/unit/bool_condition_ptr.cpp create mode 100644 tests/unit/bool_condition_ptr_c.c create mode 100644 tests/unit/out/refcount/bool_condition_enum.rs create mode 100644 tests/unit/out/refcount/bool_condition_enum_c.rs create mode 100644 tests/unit/out/refcount/bool_condition_int.rs create mode 100644 tests/unit/out/refcount/bool_condition_int_c.rs create mode 100644 tests/unit/out/refcount/bool_condition_logical.rs create mode 100644 tests/unit/out/refcount/bool_condition_logical_c.rs create mode 100644 tests/unit/out/refcount/bool_condition_ptr.rs create mode 100644 tests/unit/out/refcount/bool_condition_ptr_c.rs create mode 100644 tests/unit/out/unsafe/bool_condition_enum.rs create mode 100644 tests/unit/out/unsafe/bool_condition_enum_c.rs create mode 100644 tests/unit/out/unsafe/bool_condition_int.rs create mode 100644 tests/unit/out/unsafe/bool_condition_int_c.rs create mode 100644 tests/unit/out/unsafe/bool_condition_logical.rs create mode 100644 tests/unit/out/unsafe/bool_condition_logical_c.rs create mode 100644 tests/unit/out/unsafe/bool_condition_ptr.rs create mode 100644 tests/unit/out/unsafe/bool_condition_ptr_c.rs diff --git a/tests/unit/bool_condition_enum.cpp b/tests/unit/bool_condition_enum.cpp new file mode 100644 index 0000000..fb24e8e --- /dev/null +++ b/tests/unit/bool_condition_enum.cpp @@ -0,0 +1,29 @@ +#include + +enum Code { CODE_OK = 0, CODE_ERR = 1, CODE_FATAL = 2 }; + +int main() { + Code code = CODE_OK; + Code err = CODE_ERR; + + if (code) { + assert(false); + } + if (!code) { + assert(true); + } + if (err) { + assert(true); + } + if (!err) { + assert(false); + } + + int t9 = !code; + assert(t9 == 1); + + bool b4 = code; + assert(!b4); + + return 0; +} diff --git a/tests/unit/bool_condition_enum_c.c b/tests/unit/bool_condition_enum_c.c new file mode 100644 index 0000000..617bf9e --- /dev/null +++ b/tests/unit/bool_condition_enum_c.c @@ -0,0 +1,30 @@ +#include +#include + +enum Code { CODE_OK = 0, CODE_ERR = 1, CODE_FATAL = 2 }; + +int main() { + enum Code code = CODE_OK; + enum Code err = CODE_ERR; + + if (code) { + assert(false); + } + if (!code) { + assert(true); + } + if (err) { + assert(true); + } + if (!err) { + assert(false); + } + + int t9 = !code; + assert(t9 == 1); + + bool b4 = code; + assert(!b4); + + return 0; +} diff --git a/tests/unit/bool_condition_int.cpp b/tests/unit/bool_condition_int.cpp new file mode 100644 index 0000000..4a1b889 --- /dev/null +++ b/tests/unit/bool_condition_int.cpp @@ -0,0 +1,63 @@ +#include + +int main() { + int n = 3; + int zero = 0; + unsigned u = 4; + unsigned long ul = 5; + long long ll = 6; + char ch = 'a'; + + if (n) { + assert(true); + } + if (!n) { + assert(false); + } + if (zero) { + assert(false); + } + if (!zero) { + assert(true); + } + + if (u) { + assert(true); + } + if (ul) { + assert(true); + } + if (ll) { + assert(true); + } + if (ch) { + assert(true); + } + + int loop_count = 0; + int counter = 3; + while (counter) { + --counter; + ++loop_count; + } + assert(loop_count == 3); + + for (int i = 5; i; --i) { + ++loop_count; + } + assert(loop_count == 8); + + int t = n ? 100 : 200; + assert(t == 100); + int t2 = zero ? 100 : 200; + assert(t2 == 200); + int t7 = !n; + assert(t7 == 0); + int t8 = !zero; + assert(t8 == 1); + + bool b1 = n; + assert(b1); + + return 0; +} diff --git a/tests/unit/bool_condition_int_c.c b/tests/unit/bool_condition_int_c.c new file mode 100644 index 0000000..8d9d68d --- /dev/null +++ b/tests/unit/bool_condition_int_c.c @@ -0,0 +1,64 @@ +#include +#include + +int main() { + int n = 3; + int zero = 0; + unsigned u = 4; + unsigned long ul = 5; + long long ll = 6; + char ch = 'a'; + + if (n) { + assert(true); + } + if (!n) { + assert(false); + } + if (zero) { + assert(false); + } + if (!zero) { + assert(true); + } + + if (u) { + assert(true); + } + if (ul) { + assert(true); + } + if (ll) { + assert(true); + } + if (ch) { + assert(true); + } + + int loop_count = 0; + int counter = 3; + while (counter) { + --counter; + ++loop_count; + } + assert(loop_count == 3); + + for (int i = 5; i; --i) { + ++loop_count; + } + assert(loop_count == 8); + + int t = n ? 100 : 200; + assert(t == 100); + int t2 = zero ? 100 : 200; + assert(t2 == 200); + int t7 = !n; + assert(t7 == 0); + int t8 = !zero; + assert(t8 == 1); + + bool b1 = n; + assert(b1); + + return 0; +} diff --git a/tests/unit/bool_condition_logical.cpp b/tests/unit/bool_condition_logical.cpp new file mode 100644 index 0000000..16085e7 --- /dev/null +++ b/tests/unit/bool_condition_logical.cpp @@ -0,0 +1,49 @@ +#include +#include + +enum Code { CODE_OK = 0, CODE_ERR = 1, CODE_FATAL = 2 }; + +int side_effect = 0; +int observe(int v) { + ++side_effect; + return v; +} + +int main() { + int n = 3; + int zero = 0; + int storage = 7; + int *p = &storage; + int *np = nullptr; + unsigned u = 4; + Code code = CODE_OK; + + if (n && p) { + assert(true); + } + if (n && np) { + assert(false); + } + if (zero || p) { + assert(true); + } + if (zero || np) { + assert(false); + } + if (n && u && p && code == CODE_OK) { + assert(true); + } + + side_effect = 0; + if (zero && observe(1)) { + assert(false); + } + assert(side_effect == 0); + + if (n || observe(1)) { + assert(true); + } + assert(side_effect == 0); + + return 0; +} diff --git a/tests/unit/bool_condition_logical_c.c b/tests/unit/bool_condition_logical_c.c new file mode 100644 index 0000000..0c9d01d --- /dev/null +++ b/tests/unit/bool_condition_logical_c.c @@ -0,0 +1,50 @@ +#include +#include +#include + +enum Code { CODE_OK = 0, CODE_ERR = 1, CODE_FATAL = 2 }; + +int side_effect = 0; +int observe(int v) { + ++side_effect; + return v; +} + +int main() { + int n = 3; + int zero = 0; + int storage = 7; + int *p = &storage; + int *np = NULL; + unsigned u = 4; + enum Code code = CODE_OK; + + if (n && p) { + assert(true); + } + if (n && np) { + assert(false); + } + if (zero || p) { + assert(true); + } + if (zero || np) { + assert(false); + } + if (n && u && p && code == CODE_OK) { + assert(true); + } + + side_effect = 0; + if (zero && observe(1)) { + assert(false); + } + assert(side_effect == 0); + + if (n || observe(1)) { + assert(true); + } + assert(side_effect == 0); + + return 0; +} diff --git a/tests/unit/bool_condition_ptr.cpp b/tests/unit/bool_condition_ptr.cpp new file mode 100644 index 0000000..ccf4714 --- /dev/null +++ b/tests/unit/bool_condition_ptr.cpp @@ -0,0 +1,45 @@ +#include +#include + +int main() { + int storage = 7; + int *p = &storage; + int *np = nullptr; + + if (p) { + assert(true); + } + if (!p) { + assert(false); + } + if (np) { + assert(false); + } + if (!np) { + assert(true); + } + + int *iter = p; + int iters = 0; + while (iter) { + ++iters; + iter = nullptr; + } + assert(iters == 1); + + int t3 = p ? 1 : 0; + assert(t3 == 1); + int t4 = np ? 1 : 0; + assert(t4 == 0); + int t5 = !p; + assert(t5 == 0); + int t6 = !np; + assert(t6 == 1); + + bool b2 = p; + bool b3 = np; + assert(b2); + assert(!b3); + + return 0; +} diff --git a/tests/unit/bool_condition_ptr_c.c b/tests/unit/bool_condition_ptr_c.c new file mode 100644 index 0000000..70a031b --- /dev/null +++ b/tests/unit/bool_condition_ptr_c.c @@ -0,0 +1,46 @@ +#include +#include +#include + +int main() { + int storage = 7; + int *p = &storage; + int *np = NULL; + + if (p) { + assert(true); + } + if (!p) { + assert(false); + } + if (np) { + assert(false); + } + if (!np) { + assert(true); + } + + int *iter = p; + int iters = 0; + while (iter) { + ++iters; + iter = NULL; + } + assert(iters == 1); + + int t3 = p ? 1 : 0; + assert(t3 == 1); + int t4 = np ? 1 : 0; + assert(t4 == 0); + int t5 = !p; + assert(t5 == 0); + int t6 = !np; + assert(t6 == 1); + + bool b2 = p; + bool b3 = np; + assert(b2); + assert(!b3); + + return 0; +} diff --git a/tests/unit/out/refcount/bool_condition_enum.rs b/tests/unit/out/refcount/bool_condition_enum.rs new file mode 100644 index 0000000..645f53d --- /dev/null +++ b/tests/unit/out/refcount/bool_condition_enum.rs @@ -0,0 +1,51 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Code { + #[default] + CODE_OK = 0, + CODE_ERR = 1, + CODE_FATAL = 2, +} +impl From for Code { + fn from(n: i32) -> Code { + match n { + 0 => Code::CODE_OK, + 1 => Code::CODE_ERR, + 2 => Code::CODE_FATAL, + _ => panic!("invalid Code value: {}", n), + } + } +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let code: Value = Rc::new(RefCell::new(Code::CODE_OK)); + let err: Value = Rc::new(RefCell::new(Code::CODE_ERR)); + if ((*code.borrow()) != Code::from(0)) { + assert!(false); + } + if (!((*code.borrow()) != Code::from(0)) as bool) { + assert!(true); + } + if ((*err.borrow()) != Code::from(0)) { + assert!(true); + } + if (!((*err.borrow()) != Code::from(0)) as bool) { + assert!(false); + } + let t9: Value = Rc::new(RefCell::new( + ((!((*code.borrow()) != Code::from(0)) as bool) as i32), + )); + assert!(((*t9.borrow()) == 1)); + let b4: Value = Rc::new(RefCell::new(((*code.borrow()) != Code::from(0)).clone())); + assert!((!(*b4.borrow()) as bool)); + return 0; +} diff --git a/tests/unit/out/refcount/bool_condition_enum_c.rs b/tests/unit/out/refcount/bool_condition_enum_c.rs new file mode 100644 index 0000000..b967401 --- /dev/null +++ b/tests/unit/out/refcount/bool_condition_enum_c.rs @@ -0,0 +1,49 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Code { + #[default] + CODE_OK = 0, + CODE_ERR = 1, + CODE_FATAL = 2, +} +impl From for Code { + fn from(n: i32) -> Code { + match n { + 0 => Code::CODE_OK, + 1 => Code::CODE_ERR, + 2 => Code::CODE_FATAL, + _ => panic!("invalid Code value: {}", n), + } + } +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let code: Value = Rc::new(RefCell::new(Code::from((Code::CODE_OK as i32)))); + let err: Value = Rc::new(RefCell::new(Code::from((Code::CODE_ERR as i32)))); + if ((*code.borrow()) != Code::from(0)) { + assert!((0 != 0)); + } + if (!((*code.borrow()) != Code::from(0)) as bool) { + assert!((1 != 0)); + } + if ((*err.borrow()) != Code::from(0)) { + assert!((1 != 0)); + } + if (!((*err.borrow()) != Code::from(0)) as bool) { + assert!((0 != 0)); + } + let t9: Value = Rc::new(RefCell::new((!((*code.borrow()) != Code::from(0)) as i32))); + assert!(((*t9.borrow()) == 1)); + let b4: Value = Rc::new(RefCell::new(((*code.borrow()) != Code::from(0)).clone())); + assert!(!(*b4.borrow())); + return 0; +} diff --git a/tests/unit/out/refcount/bool_condition_int.rs b/tests/unit/out/refcount/bool_condition_int.rs new file mode 100644 index 0000000..40ac436 --- /dev/null +++ b/tests/unit/out/refcount/bool_condition_int.rs @@ -0,0 +1,71 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let n: Value = Rc::new(RefCell::new(3)); + let zero: Value = Rc::new(RefCell::new(0)); + let u: Value = Rc::new(RefCell::new(4_u32)); + let ul: Value = Rc::new(RefCell::new(5_u64)); + let ll: Value = Rc::new(RefCell::new(6_i64)); + let ch: Value = Rc::new(RefCell::new(('a' as u8))); + if ((*n.borrow()) != 0) { + assert!(true); + } + if (!((*n.borrow()) != 0) as bool) { + assert!(false); + } + if ((*zero.borrow()) != 0) { + assert!(false); + } + if (!((*zero.borrow()) != 0) as bool) { + assert!(true); + } + if ((*u.borrow()) != 0) { + assert!(true); + } + if ((*ul.borrow()) != 0) { + assert!(true); + } + if ((*ll.borrow()) != 0) { + assert!(true); + } + if ((*ch.borrow()) != 0) { + assert!(true); + } + let loop_count: Value = Rc::new(RefCell::new(0)); + let counter: Value = Rc::new(RefCell::new(3)); + 'loop_: while ((*counter.borrow()) != 0) { + (*counter.borrow_mut()).prefix_dec(); + (*loop_count.borrow_mut()).prefix_inc(); + } + assert!(((*loop_count.borrow()) == 3)); + let i: Value = Rc::new(RefCell::new(5)); + 'loop_: while ((*i.borrow()) != 0) { + (*loop_count.borrow_mut()).prefix_inc(); + (*i.borrow_mut()).prefix_dec(); + } + assert!(((*loop_count.borrow()) == 8)); + let t: Value = Rc::new(RefCell::new(if ((*n.borrow()) != 0) { 100 } else { 200 })); + assert!(((*t.borrow()) == 100)); + let t2: Value = Rc::new(RefCell::new(if ((*zero.borrow()) != 0) { + 100 + } else { + 200 + })); + assert!(((*t2.borrow()) == 200)); + let t7: Value = Rc::new(RefCell::new(((!((*n.borrow()) != 0) as bool) as i32))); + assert!(((*t7.borrow()) == 0)); + let t8: Value = Rc::new(RefCell::new(((!((*zero.borrow()) != 0) as bool) as i32))); + assert!(((*t8.borrow()) == 1)); + let b1: Value = Rc::new(RefCell::new(((*n.borrow()) != 0))); + assert!((*b1.borrow())); + return 0; +} diff --git a/tests/unit/out/refcount/bool_condition_int_c.rs b/tests/unit/out/refcount/bool_condition_int_c.rs new file mode 100644 index 0000000..fc5fab5 --- /dev/null +++ b/tests/unit/out/refcount/bool_condition_int_c.rs @@ -0,0 +1,71 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let n: Value = Rc::new(RefCell::new(3)); + let zero: Value = Rc::new(RefCell::new(0)); + let u: Value = Rc::new(RefCell::new(4_u32)); + let ul: Value = Rc::new(RefCell::new(5_u64)); + let ll: Value = Rc::new(RefCell::new(6_i64)); + let ch: Value = Rc::new(RefCell::new((('a' as i32) as u8))); + if ((*n.borrow()) != 0) { + assert!((1 != 0)); + } + if (!((*n.borrow()) != 0) as bool) { + assert!((0 != 0)); + } + if ((*zero.borrow()) != 0) { + assert!((0 != 0)); + } + if (!((*zero.borrow()) != 0) as bool) { + assert!((1 != 0)); + } + if ((*u.borrow()) != 0) { + assert!((1 != 0)); + } + if ((*ul.borrow()) != 0) { + assert!((1 != 0)); + } + if ((*ll.borrow()) != 0) { + assert!((1 != 0)); + } + if ((*ch.borrow()) != 0) { + assert!((1 != 0)); + } + let loop_count: Value = Rc::new(RefCell::new(0)); + let counter: Value = Rc::new(RefCell::new(3)); + 'loop_: while ((*counter.borrow()) != 0) { + (*counter.borrow_mut()).prefix_dec(); + (*loop_count.borrow_mut()).prefix_inc(); + } + assert!(((*loop_count.borrow()) == 3)); + let i: Value = Rc::new(RefCell::new(5)); + 'loop_: while ((*i.borrow()) != 0) { + (*loop_count.borrow_mut()).prefix_inc(); + (*i.borrow_mut()).prefix_dec(); + } + assert!(((*loop_count.borrow()) == 8)); + let t: Value = Rc::new(RefCell::new(if ((*n.borrow()) != 0) { 100 } else { 200 })); + assert!(((*t.borrow()) == 100)); + let t2: Value = Rc::new(RefCell::new(if ((*zero.borrow()) != 0) { + 100 + } else { + 200 + })); + assert!(((*t2.borrow()) == 200)); + let t7: Value = Rc::new(RefCell::new((!((*n.borrow()) != 0) as i32))); + assert!(((*t7.borrow()) == 0)); + let t8: Value = Rc::new(RefCell::new((!((*zero.borrow()) != 0) as i32))); + assert!(((*t8.borrow()) == 1)); + let b1: Value = Rc::new(RefCell::new(((*n.borrow()) != 0))); + assert!((*b1.borrow())); + return 0; +} diff --git a/tests/unit/out/refcount/bool_condition_logical.rs b/tests/unit/out/refcount/bool_condition_logical.rs new file mode 100644 index 0000000..de803dd --- /dev/null +++ b/tests/unit/out/refcount/bool_condition_logical.rs @@ -0,0 +1,98 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Code { + #[default] + CODE_OK = 0, + CODE_ERR = 1, + CODE_FATAL = 2, +} +impl From for Code { + fn from(n: i32) -> Code { + match n { + 0 => Code::CODE_OK, + 1 => Code::CODE_ERR, + 2 => Code::CODE_FATAL, + _ => panic!("invalid Code value: {}", n), + } + } +} +thread_local!( + pub static side_effect: Value = Rc::new(RefCell::new(0)); +); +pub fn observe_0(v: i32) -> i32 { + let v: Value = Rc::new(RefCell::new(v)); + (*side_effect.with(Value::clone).borrow_mut()).prefix_inc(); + return (*v.borrow()); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let n: Value = Rc::new(RefCell::new(3)); + let zero: Value = Rc::new(RefCell::new(0)); + let storage: Value = Rc::new(RefCell::new(7)); + let p: Value> = Rc::new(RefCell::new((storage.as_pointer()))); + let np: Value> = Rc::new(RefCell::new(Default::default())); + let u: Value = Rc::new(RefCell::new(4_u32)); + let code: Value = Rc::new(RefCell::new(Code::CODE_OK)); + if { + let _lhs = ((*n.borrow()) != 0); + _lhs && (!(*p.borrow()).is_null()).clone() + } { + assert!(true); + } + if { + let _lhs = ((*n.borrow()) != 0); + _lhs && (!(*np.borrow()).is_null()).clone() + } { + assert!(false); + } + if { + let _lhs = ((*zero.borrow()) != 0); + _lhs || (!(*p.borrow()).is_null()).clone() + } { + assert!(true); + } + if { + let _lhs = ((*zero.borrow()) != 0); + _lhs || (!(*np.borrow()).is_null()).clone() + } { + assert!(false); + } + if { + let _lhs = { + let _lhs = (((*n.borrow()) != 0) && ((*u.borrow()) != 0)); + _lhs && (!(*p.borrow()).is_null()).clone() + }; + _lhs && (((*code.borrow()) as i32) == (Code::CODE_OK as i32)).clone() + } { + assert!(true); + } + (*side_effect.with(Value::clone).borrow_mut()) = 0; + if (((*zero.borrow()) != 0) + && (({ + let _v: i32 = 1; + observe_0(_v) + }) != 0)) + { + assert!(false); + } + assert!(((*side_effect.with(Value::clone).borrow()) == 0)); + if (((*n.borrow()) != 0) + || (({ + let _v: i32 = 1; + observe_0(_v) + }) != 0)) + { + assert!(true); + } + assert!(((*side_effect.with(Value::clone).borrow()) == 0)); + return 0; +} diff --git a/tests/unit/out/refcount/bool_condition_logical_c.rs b/tests/unit/out/refcount/bool_condition_logical_c.rs new file mode 100644 index 0000000..984a9dc --- /dev/null +++ b/tests/unit/out/refcount/bool_condition_logical_c.rs @@ -0,0 +1,82 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Code { + #[default] + CODE_OK = 0, + CODE_ERR = 1, + CODE_FATAL = 2, +} +impl From for Code { + fn from(n: i32) -> Code { + match n { + 0 => Code::CODE_OK, + 1 => Code::CODE_ERR, + 2 => Code::CODE_FATAL, + _ => panic!("invalid Code value: {}", n), + } + } +} +thread_local!( + pub static side_effect: Value = Rc::new(RefCell::new(0)); +); +pub fn observe_0(v: i32) -> i32 { + let v: Value = Rc::new(RefCell::new(v)); + (*side_effect.with(Value::clone).borrow_mut()).prefix_inc(); + return (*v.borrow()); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let n: Value = Rc::new(RefCell::new(3)); + let zero: Value = Rc::new(RefCell::new(0)); + let storage: Value = Rc::new(RefCell::new(7)); + let p: Value> = Rc::new(RefCell::new((storage.as_pointer()))); + let np: Value> = Rc::new(RefCell::new(Default::default())); + let u: Value = Rc::new(RefCell::new(4_u32)); + let code: Value = Rc::new(RefCell::new(Code::from((Code::CODE_OK as i32)))); + if (((*n.borrow()) != 0) && (!(*p.borrow()).is_null())) { + assert!((1 != 0)); + } + if (((*n.borrow()) != 0) && (!(*np.borrow()).is_null())) { + assert!((0 != 0)); + } + if (((*zero.borrow()) != 0) || (!(*p.borrow()).is_null())) { + assert!((1 != 0)); + } + if (((*zero.borrow()) != 0) || (!(*np.borrow()).is_null())) { + assert!((0 != 0)); + } + if (((((*n.borrow()) != 0) && ((*u.borrow()) != 0)) && (!(*p.borrow()).is_null())) + && (((*code.borrow()) as u32) == ((Code::CODE_OK as i32) as u32))) + { + assert!((1 != 0)); + } + (*side_effect.with(Value::clone).borrow_mut()) = 0; + if (((*zero.borrow()) != 0) + && (({ + let _v: i32 = 1; + observe_0(_v) + }) != 0)) + { + assert!((0 != 0)); + } + assert!(((*side_effect.with(Value::clone).borrow()) == 0)); + if (((*n.borrow()) != 0) + || (({ + let _v: i32 = 1; + observe_0(_v) + }) != 0)) + { + assert!((1 != 0)); + } + assert!(((*side_effect.with(Value::clone).borrow()) == 0)); + return 0; +} diff --git a/tests/unit/out/refcount/bool_condition_ptr.rs b/tests/unit/out/refcount/bool_condition_ptr.rs new file mode 100644 index 0000000..e31fe9c --- /dev/null +++ b/tests/unit/out/refcount/bool_condition_ptr.rs @@ -0,0 +1,50 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let storage: Value = Rc::new(RefCell::new(7)); + let p: Value> = Rc::new(RefCell::new((storage.as_pointer()))); + let np: Value> = Rc::new(RefCell::new(Default::default())); + if !(*p.borrow()).is_null() { + assert!(true); + } + if (!(!(*p.borrow()).is_null()) as bool) { + assert!(false); + } + if !(*np.borrow()).is_null() { + assert!(false); + } + if (!(!(*np.borrow()).is_null()) as bool) { + assert!(true); + } + let iter: Value> = Rc::new(RefCell::new((*p.borrow()).clone())); + let iters: Value = Rc::new(RefCell::new(0)); + 'loop_: while !(*iter.borrow()).is_null() { + (*iters.borrow_mut()).prefix_inc(); + (*iter.borrow_mut()) = Default::default(); + } + assert!(((*iters.borrow()) == 1)); + let t3: Value = Rc::new(RefCell::new(if !(*p.borrow()).is_null() { 1 } else { 0 })); + assert!(((*t3.borrow()) == 1)); + let t4: Value = Rc::new(RefCell::new(if !(*np.borrow()).is_null() { 1 } else { 0 })); + assert!(((*t4.borrow()) == 0)); + let t5: Value = Rc::new(RefCell::new(((!(!(*p.borrow()).is_null()) as bool) as i32))); + assert!(((*t5.borrow()) == 0)); + let t6: Value = Rc::new(RefCell::new( + ((!(!(*np.borrow()).is_null()) as bool) as i32), + )); + assert!(((*t6.borrow()) == 1)); + let b2: Value = Rc::new(RefCell::new((!(*p.borrow()).is_null()).clone())); + let b3: Value = Rc::new(RefCell::new((!(*np.borrow()).is_null()).clone())); + assert!((*b2.borrow())); + assert!((!(*b3.borrow()) as bool)); + return 0; +} diff --git a/tests/unit/out/refcount/bool_condition_ptr_c.rs b/tests/unit/out/refcount/bool_condition_ptr_c.rs new file mode 100644 index 0000000..a8b4679 --- /dev/null +++ b/tests/unit/out/refcount/bool_condition_ptr_c.rs @@ -0,0 +1,48 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let storage: Value = Rc::new(RefCell::new(7)); + let p: Value> = Rc::new(RefCell::new((storage.as_pointer()))); + let np: Value> = Rc::new(RefCell::new(Default::default())); + if !(*p.borrow()).is_null() { + assert!((1 != 0)); + } + if (!(!(*p.borrow()).is_null()) as bool) { + assert!((0 != 0)); + } + if !(*np.borrow()).is_null() { + assert!((0 != 0)); + } + if (!(!(*np.borrow()).is_null()) as bool) { + assert!((1 != 0)); + } + let iter: Value> = Rc::new(RefCell::new((*p.borrow()).clone())); + let iters: Value = Rc::new(RefCell::new(0)); + 'loop_: while !(*iter.borrow()).is_null() { + (*iters.borrow_mut()).prefix_inc(); + (*iter.borrow_mut()) = Default::default(); + } + assert!(((*iters.borrow()) == 1)); + let t3: Value = Rc::new(RefCell::new(if !(*p.borrow()).is_null() { 1 } else { 0 })); + assert!(((*t3.borrow()) == 1)); + let t4: Value = Rc::new(RefCell::new(if !(*np.borrow()).is_null() { 1 } else { 0 })); + assert!(((*t4.borrow()) == 0)); + let t5: Value = Rc::new(RefCell::new((!(!(*p.borrow()).is_null()) as i32))); + assert!(((*t5.borrow()) == 0)); + let t6: Value = Rc::new(RefCell::new((!(!(*np.borrow()).is_null()) as i32))); + assert!(((*t6.borrow()) == 1)); + let b2: Value = Rc::new(RefCell::new((!(*p.borrow()).is_null()).clone())); + let b3: Value = Rc::new(RefCell::new((!(*np.borrow()).is_null()).clone())); + assert!((*b2.borrow())); + assert!(!(*b3.borrow())); + return 0; +} diff --git a/tests/unit/out/unsafe/bool_condition_enum.rs b/tests/unit/out/unsafe/bool_condition_enum.rs new file mode 100644 index 0000000..a20fc91 --- /dev/null +++ b/tests/unit/out/unsafe/bool_condition_enum.rs @@ -0,0 +1,51 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Code { + #[default] + CODE_OK = 0, + CODE_ERR = 1, + CODE_FATAL = 2, +} +impl From for Code { + fn from(n: i32) -> Code { + match n { + 0 => Code::CODE_OK, + 1 => Code::CODE_ERR, + 2 => Code::CODE_FATAL, + _ => panic!("invalid Code value: {}", n), + } + } +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut code: Code = Code::CODE_OK; + let mut err: Code = Code::CODE_ERR; + if (code != Code::from(0)) { + assert!(false); + } + if (!(code != Code::from(0)) as bool) { + assert!(true); + } + if (err != Code::from(0)) { + assert!(true); + } + if (!(err != Code::from(0)) as bool) { + assert!(false); + } + let mut t9: i32 = ((!(code != Code::from(0)) as bool) as i32); + assert!(((t9) == (1))); + let mut b4: bool = (code != Code::from(0)); + assert!((!(b4) as bool)); + return 0; +} diff --git a/tests/unit/out/unsafe/bool_condition_enum_c.rs b/tests/unit/out/unsafe/bool_condition_enum_c.rs new file mode 100644 index 0000000..73f8d9b --- /dev/null +++ b/tests/unit/out/unsafe/bool_condition_enum_c.rs @@ -0,0 +1,51 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Code { + #[default] + CODE_OK = 0, + CODE_ERR = 1, + CODE_FATAL = 2, +} +impl From for Code { + fn from(n: i32) -> Code { + match n { + 0 => Code::CODE_OK, + 1 => Code::CODE_ERR, + 2 => Code::CODE_FATAL, + _ => panic!("invalid Code value: {}", n), + } + } +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut code: Code = Code::from((Code::CODE_OK as i32)); + let mut err: Code = Code::from((Code::CODE_ERR as i32)); + if (code != Code::from(0)) { + assert!((0 != 0)); + } + if (!(code != Code::from(0)) as bool) { + assert!((1 != 0)); + } + if (err != Code::from(0)) { + assert!((1 != 0)); + } + if (!(err != Code::from(0)) as bool) { + assert!((0 != 0)); + } + let mut t9: i32 = (!(code != Code::from(0)) as i32); + assert!(((t9) == (1))); + let mut b4: bool = (code != Code::from(0)); + assert!(!(b4)); + return 0; +} diff --git a/tests/unit/out/unsafe/bool_condition_int.rs b/tests/unit/out/unsafe/bool_condition_int.rs new file mode 100644 index 0000000..c07d2f6 --- /dev/null +++ b/tests/unit/out/unsafe/bool_condition_int.rs @@ -0,0 +1,69 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut n: i32 = 3; + let mut zero: i32 = 0; + let mut u: u32 = 4_u32; + let mut ul: u64 = 5_u64; + let mut ll: i64 = 6_i64; + let mut ch: u8 = ('a' as u8); + if (n != 0) { + assert!(true); + } + if (!(n != 0) as bool) { + assert!(false); + } + if (zero != 0) { + assert!(false); + } + if (!(zero != 0) as bool) { + assert!(true); + } + if (u != 0) { + assert!(true); + } + if (ul != 0) { + assert!(true); + } + if (ll != 0) { + assert!(true); + } + if (ch != 0) { + assert!(true); + } + let mut loop_count: i32 = 0; + let mut counter: i32 = 3; + 'loop_: while (counter != 0) { + counter.prefix_dec(); + loop_count.prefix_inc(); + } + assert!(((loop_count) == (3))); + let mut i: i32 = 5; + 'loop_: while (i != 0) { + loop_count.prefix_inc(); + i.prefix_dec(); + } + assert!(((loop_count) == (8))); + let mut t: i32 = if (n != 0) { 100 } else { 200 }; + assert!(((t) == (100))); + let mut t2: i32 = if (zero != 0) { 100 } else { 200 }; + assert!(((t2) == (200))); + let mut t7: i32 = ((!(n != 0) as bool) as i32); + assert!(((t7) == (0))); + let mut t8: i32 = ((!(zero != 0) as bool) as i32); + assert!(((t8) == (1))); + let mut b1: bool = (n != 0); + assert!(b1); + return 0; +} diff --git a/tests/unit/out/unsafe/bool_condition_int_c.rs b/tests/unit/out/unsafe/bool_condition_int_c.rs new file mode 100644 index 0000000..22e3134 --- /dev/null +++ b/tests/unit/out/unsafe/bool_condition_int_c.rs @@ -0,0 +1,69 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut n: i32 = 3; + let mut zero: i32 = 0; + let mut u: u32 = 4_u32; + let mut ul: u64 = 5_u64; + let mut ll: i64 = 6_i64; + let mut ch: u8 = (('a' as i32) as u8); + if (n != 0) { + assert!((1 != 0)); + } + if (!(n != 0) as bool) { + assert!((0 != 0)); + } + if (zero != 0) { + assert!((0 != 0)); + } + if (!(zero != 0) as bool) { + assert!((1 != 0)); + } + if (u != 0) { + assert!((1 != 0)); + } + if (ul != 0) { + assert!((1 != 0)); + } + if (ll != 0) { + assert!((1 != 0)); + } + if (ch != 0) { + assert!((1 != 0)); + } + let mut loop_count: i32 = 0; + let mut counter: i32 = 3; + 'loop_: while (counter != 0) { + counter.prefix_dec(); + loop_count.prefix_inc(); + } + assert!(((loop_count) == (3))); + let mut i: i32 = 5; + 'loop_: while (i != 0) { + loop_count.prefix_inc(); + i.prefix_dec(); + } + assert!(((loop_count) == (8))); + let mut t: i32 = if (n != 0) { 100 } else { 200 }; + assert!(((t) == (100))); + let mut t2: i32 = if (zero != 0) { 100 } else { 200 }; + assert!(((t2) == (200))); + let mut t7: i32 = (!(n != 0) as i32); + assert!(((t7) == (0))); + let mut t8: i32 = (!(zero != 0) as i32); + assert!(((t8) == (1))); + let mut b1: bool = (n != 0); + assert!(b1); + return 0; +} diff --git a/tests/unit/out/unsafe/bool_condition_logical.rs b/tests/unit/out/unsafe/bool_condition_logical.rs new file mode 100644 index 0000000..33cfda6 --- /dev/null +++ b/tests/unit/out/unsafe/bool_condition_logical.rs @@ -0,0 +1,79 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Code { + #[default] + CODE_OK = 0, + CODE_ERR = 1, + CODE_FATAL = 2, +} +impl From for Code { + fn from(n: i32) -> Code { + match n { + 0 => Code::CODE_OK, + 1 => Code::CODE_ERR, + 2 => Code::CODE_FATAL, + _ => panic!("invalid Code value: {}", n), + } + } +} +pub static mut side_effect: i32 = 0; +pub unsafe fn observe_0(mut v: i32) -> i32 { + side_effect.prefix_inc(); + return v; +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut n: i32 = 3; + let mut zero: i32 = 0; + let mut storage: i32 = 7; + let mut p: *mut i32 = (&mut storage as *mut i32); + let mut np: *mut i32 = Default::default(); + let mut u: u32 = 4_u32; + let mut code: Code = Code::CODE_OK; + if ((n != 0) && (!(p).is_null())) { + assert!(true); + } + if ((n != 0) && (!(np).is_null())) { + assert!(false); + } + if ((zero != 0) || (!(p).is_null())) { + assert!(true); + } + if ((zero != 0) || (!(np).is_null())) { + assert!(false); + } + if ((((n != 0) && (u != 0)) && (!(p).is_null())) && ((code as i32) == (Code::CODE_OK as i32))) { + assert!(true); + } + side_effect = 0; + if ((zero != 0) + && ((unsafe { + let _v: i32 = 1; + observe_0(_v) + }) != 0)) + { + assert!(false); + } + assert!(((side_effect) == (0))); + if ((n != 0) + || ((unsafe { + let _v: i32 = 1; + observe_0(_v) + }) != 0)) + { + assert!(true); + } + assert!(((side_effect) == (0))); + return 0; +} diff --git a/tests/unit/out/unsafe/bool_condition_logical_c.rs b/tests/unit/out/unsafe/bool_condition_logical_c.rs new file mode 100644 index 0000000..1131d88 --- /dev/null +++ b/tests/unit/out/unsafe/bool_condition_logical_c.rs @@ -0,0 +1,81 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Code { + #[default] + CODE_OK = 0, + CODE_ERR = 1, + CODE_FATAL = 2, +} +impl From for Code { + fn from(n: i32) -> Code { + match n { + 0 => Code::CODE_OK, + 1 => Code::CODE_ERR, + 2 => Code::CODE_FATAL, + _ => panic!("invalid Code value: {}", n), + } + } +} +pub static mut side_effect: i32 = 0; +pub unsafe fn observe_0(mut v: i32) -> i32 { + side_effect.prefix_inc(); + return v; +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut n: i32 = 3; + let mut zero: i32 = 0; + let mut storage: i32 = 7; + let mut p: *mut i32 = (&mut storage as *mut i32); + let mut np: *mut i32 = Default::default(); + let mut u: u32 = 4_u32; + let mut code: Code = Code::from((Code::CODE_OK as i32)); + if ((n != 0) && (!(p).is_null())) { + assert!((1 != 0)); + } + if ((n != 0) && (!(np).is_null())) { + assert!((0 != 0)); + } + if ((zero != 0) || (!(p).is_null())) { + assert!((1 != 0)); + } + if ((zero != 0) || (!(np).is_null())) { + assert!((0 != 0)); + } + if ((((n != 0) && (u != 0)) && (!(p).is_null())) + && ((code as u32) == ((Code::CODE_OK as i32) as u32))) + { + assert!((1 != 0)); + } + side_effect = 0; + if ((zero != 0) + && ((unsafe { + let _v: i32 = 1; + observe_0(_v) + }) != 0)) + { + assert!((0 != 0)); + } + assert!(((side_effect) == (0))); + if ((n != 0) + || ((unsafe { + let _v: i32 = 1; + observe_0(_v) + }) != 0)) + { + assert!((1 != 0)); + } + assert!(((side_effect) == (0))); + return 0; +} diff --git a/tests/unit/out/unsafe/bool_condition_ptr.rs b/tests/unit/out/unsafe/bool_condition_ptr.rs new file mode 100644 index 0000000..9535af8 --- /dev/null +++ b/tests/unit/out/unsafe/bool_condition_ptr.rs @@ -0,0 +1,50 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut storage: i32 = 7; + let mut p: *mut i32 = (&mut storage as *mut i32); + let mut np: *mut i32 = Default::default(); + if !(p).is_null() { + assert!(true); + } + if (!(!(p).is_null()) as bool) { + assert!(false); + } + if !(np).is_null() { + assert!(false); + } + if (!(!(np).is_null()) as bool) { + assert!(true); + } + let mut iter: *mut i32 = p; + let mut iters: i32 = 0; + 'loop_: while !(iter).is_null() { + iters.prefix_inc(); + iter = Default::default(); + } + assert!(((iters) == (1))); + let mut t3: i32 = if !(p).is_null() { 1 } else { 0 }; + assert!(((t3) == (1))); + let mut t4: i32 = if !(np).is_null() { 1 } else { 0 }; + assert!(((t4) == (0))); + let mut t5: i32 = ((!(!(p).is_null()) as bool) as i32); + assert!(((t5) == (0))); + let mut t6: i32 = ((!(!(np).is_null()) as bool) as i32); + assert!(((t6) == (1))); + let mut b2: bool = !(p).is_null(); + let mut b3: bool = !(np).is_null(); + assert!(b2); + assert!((!(b3) as bool)); + return 0; +} diff --git a/tests/unit/out/unsafe/bool_condition_ptr_c.rs b/tests/unit/out/unsafe/bool_condition_ptr_c.rs new file mode 100644 index 0000000..b26fcf1 --- /dev/null +++ b/tests/unit/out/unsafe/bool_condition_ptr_c.rs @@ -0,0 +1,50 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut storage: i32 = 7; + let mut p: *mut i32 = (&mut storage as *mut i32); + let mut np: *mut i32 = Default::default(); + if !(p).is_null() { + assert!((1 != 0)); + } + if (!(!(p).is_null()) as bool) { + assert!((0 != 0)); + } + if !(np).is_null() { + assert!((0 != 0)); + } + if (!(!(np).is_null()) as bool) { + assert!((1 != 0)); + } + let mut iter: *mut i32 = p; + let mut iters: i32 = 0; + 'loop_: while !(iter).is_null() { + iters.prefix_inc(); + iter = Default::default(); + } + assert!(((iters) == (1))); + let mut t3: i32 = if !(p).is_null() { 1 } else { 0 }; + assert!(((t3) == (1))); + let mut t4: i32 = if !(np).is_null() { 1 } else { 0 }; + assert!(((t4) == (0))); + let mut t5: i32 = (!(!(p).is_null()) as i32); + assert!(((t5) == (0))); + let mut t6: i32 = (!(!(np).is_null()) as i32); + assert!(((t6) == (1))); + let mut b2: bool = !(p).is_null(); + let mut b3: bool = !(np).is_null(); + assert!(b2); + assert!(!(b3)); + return 0; +} From 6a0131ffe135c12156dc1c3cf54b2728bfd30727 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 17:51:59 +0100 Subject: [PATCH 04/23] Choose between Pointer and Integral ToBoolean --- cpp2rust/converter/converter_lib.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 027d324..50f54b7 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -684,8 +684,15 @@ bool ContainsVAArgExpr(const clang::Stmt *stmt) { } clang::Expr *CreateConversionToBool(clang::Expr *expr, clang::ASTContext &ctx) { + clang::CastKind cast_kind; + if (expr->getType()->isPointerType()) { + cast_kind = clang::CK_PointerToBoolean; + } else /* expr->getType()->isIntegerType() */ { + cast_kind = clang::CK_IntegralToBoolean; + } + return clang::ImplicitCastExpr::Create( - ctx, ctx.BoolTy, clang::CK_IntegralToBoolean, expr, + ctx, ctx.BoolTy, cast_kind, expr, /*BasePath=*/nullptr, clang::VK_PRValue, clang::FPOptionsOverride()); } From b8af9442ffa74a57ce6b1319ceb7373a52116297 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 17:52:55 +0100 Subject: [PATCH 05/23] Convert integer LNot to boolean LNot --- cpp2rust/converter/converter_lib.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 50f54b7..92322cb 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -684,6 +684,15 @@ bool ContainsVAArgExpr(const clang::Stmt *stmt) { } clang::Expr *CreateConversionToBool(clang::Expr *expr, clang::ASTContext &ctx) { + if (auto bin = clang::dyn_cast(expr)) { + if (bin->getOpcode() == clang::UO_LNot) { + return clang::UnaryOperator::Create( + ctx, bin->getSubExpr(), clang::UO_LNot, ctx.BoolTy, clang::VK_PRValue, + clang::OK_Ordinary, clang::SourceLocation(), false, + clang::FPOptionsOverride()); + } + } + clang::CastKind cast_kind; if (expr->getType()->isPointerType()) { cast_kind = clang::CK_PointerToBoolean; From 7d375e4e88f4677b59d09ed1f6df50401c7e1a67 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 17:53:12 +0100 Subject: [PATCH 06/23] Short circuit if type is already bool --- cpp2rust/converter/converter_lib.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 92322cb..391fd87 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -684,6 +684,10 @@ bool ContainsVAArgExpr(const clang::Stmt *stmt) { } clang::Expr *CreateConversionToBool(clang::Expr *expr, clang::ASTContext &ctx) { + if (expr->getType()->isBooleanType()) { + return expr; + } + if (auto bin = clang::dyn_cast(expr)) { if (bin->getOpcode() == clang::UO_LNot) { return clang::UnaryOperator::Create( From ea6925bfc7e6cacc2ce8fc4b04f74d0df1169d90 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 17:56:11 +0100 Subject: [PATCH 07/23] Update tests --- tests/benchmarks/out/refcount/bfs.rs | 6 +++--- tests/benchmarks/out/unsafe/bfs.rs | 4 ++-- tests/unit/out/refcount/assert.rs | 2 +- tests/unit/out/refcount/expr_as_bool_c.rs | 2 +- tests/unit/out/refcount/expr_as_bool_cpp.rs | 4 ++-- tests/unit/out/refcount/fn_ptr_as_condition.rs | 4 ++-- tests/unit/out/refcount/no_direct_callee.rs | 2 +- tests/unit/out/refcount/polymorphism.rs | 2 +- .../out/refcount/switch_stacked_with_inner_fallthrough.rs | 2 +- tests/unit/out/refcount/vector.rs | 2 +- tests/unit/out/unsafe/assert.rs | 2 +- tests/unit/out/unsafe/expr_as_bool_c.rs | 2 +- tests/unit/out/unsafe/expr_as_bool_cpp.rs | 4 ++-- tests/unit/out/unsafe/fn_ptr_as_condition.rs | 2 +- tests/unit/out/unsafe/no_direct_callee.rs | 2 +- tests/unit/out/unsafe/polymorphism.rs | 2 +- .../out/unsafe/switch_stacked_with_inner_fallthrough.rs | 2 +- tests/unit/out/unsafe/vector.rs | 2 +- 18 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/benchmarks/out/refcount/bfs.rs b/tests/benchmarks/out/refcount/bfs.rs index 8c71337..63370d0 100644 --- a/tests/benchmarks/out/refcount/bfs.rs +++ b/tests/benchmarks/out/refcount/bfs.rs @@ -152,7 +152,7 @@ pub fn BFS_0(graph: Ptr, start_vertex: u32) -> Ptr { let _elem: i32 = ((*start_vertex.borrow()) as i32); (*Q.borrow()).enqueue(_elem) }); - 'loop_: while !({ (*Q.borrow()).empty() }) { + 'loop_: while (!({ (*Q.borrow()).empty() }) as bool) { let current_vertex: Value = Rc::new(RefCell::new((({ (*Q.borrow()).dequeue() }) as i32))); let head: Value> = Rc::new(RefCell::new( @@ -165,9 +165,9 @@ pub fn BFS_0(graph: Ptr, start_vertex: u32) -> Ptr { let adj_vertex: Value = Rc::new(RefCell::new( ((*(*(*head.borrow()).upgrade().deref()).vertex.borrow()) as i32), )); - if !((*visited.borrow()) + if (!((*visited.borrow()) .offset((*adj_vertex.borrow()) as isize) - .read()) + .read()) as bool) { (*visited.borrow()) .offset((*adj_vertex.borrow()) as isize) diff --git a/tests/benchmarks/out/unsafe/bfs.rs b/tests/benchmarks/out/unsafe/bfs.rs index df11cfc..ea6c7bd 100644 --- a/tests/benchmarks/out/unsafe/bfs.rs +++ b/tests/benchmarks/out/unsafe/bfs.rs @@ -95,12 +95,12 @@ pub unsafe fn BFS_0(graph: *const Graph, mut start_vertex: u32) -> *mut u32 { let _elem: i32 = (start_vertex as i32); Q.enqueue(_elem) }); - 'loop_: while !(unsafe { Q.empty() }) { + 'loop_: while (!(unsafe { Q.empty() }) as bool) { let mut current_vertex: i32 = ((unsafe { Q.dequeue() }) as i32); let mut head: *mut GraphNode = (*(*graph).adj.offset((current_vertex) as isize)); 'loop_: while !((head).is_null()) { let mut adj_vertex: i32 = ((*head).vertex as i32); - if !(*visited.offset((adj_vertex) as isize)) { + if (!(*visited.offset((adj_vertex) as isize)) as bool) { (*visited.offset((adj_vertex) as isize)) = true; (unsafe { let _elem: i32 = adj_vertex; diff --git a/tests/unit/out/refcount/assert.rs b/tests/unit/out/refcount/assert.rs index 1463a3c..9f74954 100644 --- a/tests/unit/out/refcount/assert.rs +++ b/tests/unit/out/refcount/assert.rs @@ -10,6 +10,6 @@ pub fn main() { std::process::exit(main_0()); } fn main_0() -> i32 { - assert!(!(0 != 0)); + assert!((!(0 != 0) as bool)); return 1; } diff --git a/tests/unit/out/refcount/expr_as_bool_c.rs b/tests/unit/out/refcount/expr_as_bool_c.rs index 4352b92..e795582 100644 --- a/tests/unit/out/refcount/expr_as_bool_c.rs +++ b/tests/unit/out/refcount/expr_as_bool_c.rs @@ -28,7 +28,7 @@ fn main_0() -> i32 { if ((*a.borrow()) < (*b.borrow())) {} assert!(((*a.borrow()) == (*b.borrow()))); assert!( - (!(({ + !((({ (*a.borrow_mut()) = (*b.borrow()); (*a.borrow()) }) as i32) diff --git a/tests/unit/out/refcount/expr_as_bool_cpp.rs b/tests/unit/out/refcount/expr_as_bool_cpp.rs index e795582..06b258b 100644 --- a/tests/unit/out/refcount/expr_as_bool_cpp.rs +++ b/tests/unit/out/refcount/expr_as_bool_cpp.rs @@ -28,11 +28,11 @@ fn main_0() -> i32 { if ((*a.borrow()) < (*b.borrow())) {} assert!(((*a.borrow()) == (*b.borrow()))); assert!( - !((({ + (!((({ (*a.borrow_mut()) = (*b.borrow()); (*a.borrow()) }) as i32) - != 0) + != 0) as bool) ); let c: Value = >::default(); (*c.borrow_mut()) = ({ diff --git a/tests/unit/out/refcount/fn_ptr_as_condition.rs b/tests/unit/out/refcount/fn_ptr_as_condition.rs index 72708ae..9ac3ca0 100644 --- a/tests/unit/out/refcount/fn_ptr_as_condition.rs +++ b/tests/unit/out/refcount/fn_ptr_as_condition.rs @@ -43,8 +43,8 @@ fn main_0() -> i32 { }); assert!(((*b.borrow()) == 5)); let fn_: Value)>> = Rc::new(RefCell::new(FnPtr::null())); - if !!(*fn_.borrow()).is_null() { - (*fn_.borrow_mut()) = (FnPtr::)>::new(double_it_0)).clone(); + if (!(!(*fn_.borrow()).is_null()) as bool) { + (*fn_.borrow_mut()) = FnPtr::)>::new(double_it_0); } let c: Value = Rc::new(RefCell::new(3)); if !(*fn_.borrow()).is_null() { diff --git a/tests/unit/out/refcount/no_direct_callee.rs b/tests/unit/out/refcount/no_direct_callee.rs index 582dca7..867bba1 100644 --- a/tests/unit/out/refcount/no_direct_callee.rs +++ b/tests/unit/out/refcount/no_direct_callee.rs @@ -11,7 +11,7 @@ pub fn test1_0() -> bool { } pub fn test_1(fn_: FnPtr bool>) -> i32 { let fn_: Value bool>> = Rc::new(RefCell::new(fn_)); - if !({ (*(*fn_.borrow()))() }) { + if (!({ (*(*fn_.borrow()))() }) as bool) { return 1; } return 0; diff --git a/tests/unit/out/refcount/polymorphism.rs b/tests/unit/out/refcount/polymorphism.rs index 8add81b..ccadbf9 100644 --- a/tests/unit/out/refcount/polymorphism.rs +++ b/tests/unit/out/refcount/polymorphism.rs @@ -58,5 +58,5 @@ fn main_0() -> i32 { let eat2: Value = Rc::new(RefCell::new( ({ (*(*animal.borrow()).upgrade().deref()).bark() }), )); - return (((*eat1.borrow()) && !(*eat2.borrow())) as i32); + return (((*eat1.borrow()) && (!(*eat2.borrow()) as bool)) as i32); } diff --git a/tests/unit/out/refcount/switch_stacked_with_inner_fallthrough.rs b/tests/unit/out/refcount/switch_stacked_with_inner_fallthrough.rs index 8241abc..9073061 100644 --- a/tests/unit/out/refcount/switch_stacked_with_inner_fallthrough.rs +++ b/tests/unit/out/refcount/switch_stacked_with_inner_fallthrough.rs @@ -12,7 +12,7 @@ pub fn stacked_with_inner_fallthrough_0(x: i32, flag: i32) -> i32 { let r: Value = Rc::new(RefCell::new(0)); switch!(match (*x.borrow()) { v if v == 1 || v == 2 || v == 3 => { - if !((*flag.borrow()) != 0) { + if (!((*flag.borrow()) != 0) as bool) { (*r.borrow_mut()) = 50; break; }; diff --git a/tests/unit/out/refcount/vector.rs b/tests/unit/out/refcount/vector.rs index 76d493f..2a9a070 100644 --- a/tests/unit/out/refcount/vector.rs +++ b/tests/unit/out/refcount/vector.rs @@ -17,7 +17,7 @@ fn main_0() -> i32 { assert!(((*v1.borrow()).len() as u64 == 0_u64)); assert!((*v1.borrow()).is_empty()); (*v1.borrow_mut()).push(1); - assert!(!(*v1.borrow()).is_empty()); + assert!((!((*v1.borrow()).is_empty()) as bool)); (*v1.borrow_mut()).pop(); assert!((*v1.borrow()).is_empty()); let s1: Value = Rc::new(RefCell::new((*v1.borrow()).len() as u64)); diff --git a/tests/unit/out/unsafe/assert.rs b/tests/unit/out/unsafe/assert.rs index 70b1ff7..5751447 100644 --- a/tests/unit/out/unsafe/assert.rs +++ b/tests/unit/out/unsafe/assert.rs @@ -12,6 +12,6 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - assert!(!(0 != 0)); + assert!((!(0 != 0) as bool)); return 1; } diff --git a/tests/unit/out/unsafe/expr_as_bool_c.rs b/tests/unit/out/unsafe/expr_as_bool_c.rs index 070f108..ae65ed2 100644 --- a/tests/unit/out/unsafe/expr_as_bool_c.rs +++ b/tests/unit/out/unsafe/expr_as_bool_c.rs @@ -30,7 +30,7 @@ unsafe fn main_0() -> i32 { if ((a) < (b)) {} assert!(((a) == (b))); assert!( - (!(({ + !((({ a = b; a }) as i32) diff --git a/tests/unit/out/unsafe/expr_as_bool_cpp.rs b/tests/unit/out/unsafe/expr_as_bool_cpp.rs index ae65ed2..acda5b9 100644 --- a/tests/unit/out/unsafe/expr_as_bool_cpp.rs +++ b/tests/unit/out/unsafe/expr_as_bool_cpp.rs @@ -30,11 +30,11 @@ unsafe fn main_0() -> i32 { if ((a) < (b)) {} assert!(((a) == (b))); assert!( - !((({ + (!((({ a = b; a }) as i32) - != 0) + != 0) as bool) ); let mut c: bool = false; c = ({ diff --git a/tests/unit/out/unsafe/fn_ptr_as_condition.rs b/tests/unit/out/unsafe/fn_ptr_as_condition.rs index d4b8a92..09f2d67 100644 --- a/tests/unit/out/unsafe/fn_ptr_as_condition.rs +++ b/tests/unit/out/unsafe/fn_ptr_as_condition.rs @@ -38,7 +38,7 @@ unsafe fn main_0() -> i32 { }); assert!(((b) == (5))); let mut fn_: Option = None; - if !!(fn_).is_none() { + if (!(!(fn_).is_none()) as bool) { fn_ = Some(double_it_0); } let mut c: i32 = 3; diff --git a/tests/unit/out/unsafe/no_direct_callee.rs b/tests/unit/out/unsafe/no_direct_callee.rs index 6d50bee..20d2198 100644 --- a/tests/unit/out/unsafe/no_direct_callee.rs +++ b/tests/unit/out/unsafe/no_direct_callee.rs @@ -10,7 +10,7 @@ pub unsafe fn test1_0() -> bool { return false; } pub unsafe fn test_1(mut fn_: Option bool>) -> i32 { - if !(unsafe { (fn_).unwrap()() }) { + if (!(unsafe { (fn_).unwrap()() }) as bool) { return 1; } return 0; diff --git a/tests/unit/out/unsafe/polymorphism.rs b/tests/unit/out/unsafe/polymorphism.rs index 2f98f68..8801a8c 100644 --- a/tests/unit/out/unsafe/polymorphism.rs +++ b/tests/unit/out/unsafe/polymorphism.rs @@ -42,5 +42,5 @@ unsafe fn main_0() -> i32 { let mut cat: Cat = ::default(); animal = (&mut cat as *mut Cat); let mut eat2: bool = (unsafe { (*animal.cast_const()).bark() }); - return (((eat1) && (!eat2)) as i32); + return (((eat1) && (!(eat2) as bool)) as i32); } diff --git a/tests/unit/out/unsafe/switch_stacked_with_inner_fallthrough.rs b/tests/unit/out/unsafe/switch_stacked_with_inner_fallthrough.rs index 515da37..adf6995 100644 --- a/tests/unit/out/unsafe/switch_stacked_with_inner_fallthrough.rs +++ b/tests/unit/out/unsafe/switch_stacked_with_inner_fallthrough.rs @@ -10,7 +10,7 @@ pub unsafe fn stacked_with_inner_fallthrough_0(mut x: i32, mut flag: i32) -> i32 let mut r: i32 = 0; switch!(match x { v if v == 1 || v == 2 || v == 3 => { - if !(flag != 0) { + if (!(flag != 0) as bool) { r = 50; break; }; diff --git a/tests/unit/out/unsafe/vector.rs b/tests/unit/out/unsafe/vector.rs index fb44d82..f030034 100644 --- a/tests/unit/out/unsafe/vector.rs +++ b/tests/unit/out/unsafe/vector.rs @@ -17,7 +17,7 @@ unsafe fn main_0() -> i32 { assert!(((v1.len() as u64) == (0_u64))); assert!(v1.is_empty()); v1.push(1); - assert!(!v1.is_empty()); + assert!((!(v1.is_empty()) as bool)); v1.pop(); assert!(v1.is_empty()); let mut s1: u64 = v1.len() as u64; From 3535cc20167ec874cafba7357f994ae05bcd7d67 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 18:05:22 +0100 Subject: [PATCH 08/23] Add ConvertIntegralToBooleanCast --- cpp2rust/converter/converter.cpp | 51 +++++++++++++++++++++++--------- cpp2rust/converter/converter.h | 2 ++ 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 3882875..bfd3f1b 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1741,6 +1741,42 @@ void Converter::ConvertIntegerToEnumeralCast(clang::Expr *to, } } +void Converter::ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr) { + auto sub_expr = expr->getSubExpr(); + auto *stripped = sub_expr->IgnoreParenImpCasts(); + + if (auto binop = clang::dyn_cast(stripped)) { + // Comparison already produces bool, no wrap needed. + if (binop->isComparisonOp()) { + Convert(sub_expr); + return; + } + // Distribute bool conversion to each argument of the logical op. + if (binop->isLogicalOp()) { + PushParen outer(*this); + { + PushParen lp(*this); + Convert(CreateConversionToBool(binop->getLHS(), ctx_)); + } + StrCat(binop->getOpcodeStr()); + { + PushParen rp(*this); + Convert(CreateConversionToBool(binop->getRHS(), ctx_)); + } + return; + } + } + + PushParen paren(*this); + Convert(sub_expr); + StrCat(token::kDiff); + if (sub_expr->getType()->isEnumeralType()) { + StrCat(GetUnsafeTypeAsString(sub_expr->getType()), "::from(0)"); + } else /* sub_expr->getType()->isIntegerType() */ { + StrCat(token::kZero); + } +} + bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { auto *sub_expr = expr->getSubExpr(); auto type = expr->getType(); @@ -1816,20 +1852,7 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { Convert(sub_expr); break; case clang::CastKind::CK_IntegralToBoolean: - if (auto binop = clang::dyn_cast( - sub_expr->IgnoreParenImpCasts())) { - // This already produces bool, no need for != 0 - if (binop->isComparisonOp()) { - Convert(sub_expr); - break; - } - } - - { - PushParen paren(*this); - Convert(sub_expr); - StrCat(token::kDiff, token::kZero); - } + ConvertIntegralToBooleanCast(expr); break; case clang::CastKind::CK_PointerToBoolean: StrCat(token::kNot); diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index 27a7804..9d7a741 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -243,6 +243,8 @@ class Converter : public clang::RecursiveASTVisitor { void ConvertIntegerToEnumeralCast(clang::Expr *to, clang::Expr *from); + void ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr); + virtual bool VisitImplicitCastExpr(clang::ImplicitCastExpr *expr); virtual bool VisitExplicitCastExpr(clang::ExplicitCastExpr *expr); From 5118834cf6a5b7bb8d7fdfb2b4da7336e0e3685d Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 18:09:06 +0100 Subject: [PATCH 09/23] Update tests --- tests/unit/bool_condition_logical_c.c | 2 +- tests/unit/bool_condition_ptr_c.c | 2 +- tests/unit/out/refcount/bool_condition_enum_c.rs | 2 +- tests/unit/out/refcount/bool_condition_ptr_c.rs | 2 +- tests/unit/out/refcount/expr_as_bool_c.rs | 3 ++- tests/unit/out/unsafe/bool_condition_enum_c.rs | 2 +- tests/unit/out/unsafe/bool_condition_ptr_c.rs | 2 +- tests/unit/out/unsafe/expr_as_bool_c.rs | 3 ++- 8 files changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/unit/bool_condition_logical_c.c b/tests/unit/bool_condition_logical_c.c index 0c9d01d..d05ea0b 100644 --- a/tests/unit/bool_condition_logical_c.c +++ b/tests/unit/bool_condition_logical_c.c @@ -1,6 +1,6 @@ #include -#include #include +#include enum Code { CODE_OK = 0, CODE_ERR = 1, CODE_FATAL = 2 }; diff --git a/tests/unit/bool_condition_ptr_c.c b/tests/unit/bool_condition_ptr_c.c index 70a031b..420e204 100644 --- a/tests/unit/bool_condition_ptr_c.c +++ b/tests/unit/bool_condition_ptr_c.c @@ -1,6 +1,6 @@ #include -#include #include +#include int main() { int storage = 7; diff --git a/tests/unit/out/refcount/bool_condition_enum_c.rs b/tests/unit/out/refcount/bool_condition_enum_c.rs index b967401..b53a516 100644 --- a/tests/unit/out/refcount/bool_condition_enum_c.rs +++ b/tests/unit/out/refcount/bool_condition_enum_c.rs @@ -44,6 +44,6 @@ fn main_0() -> i32 { let t9: Value = Rc::new(RefCell::new((!((*code.borrow()) != Code::from(0)) as i32))); assert!(((*t9.borrow()) == 1)); let b4: Value = Rc::new(RefCell::new(((*code.borrow()) != Code::from(0)).clone())); - assert!(!(*b4.borrow())); + assert!(((!(*b4.borrow()) as i32) != 0)); return 0; } diff --git a/tests/unit/out/refcount/bool_condition_ptr_c.rs b/tests/unit/out/refcount/bool_condition_ptr_c.rs index a8b4679..f1f8cc8 100644 --- a/tests/unit/out/refcount/bool_condition_ptr_c.rs +++ b/tests/unit/out/refcount/bool_condition_ptr_c.rs @@ -43,6 +43,6 @@ fn main_0() -> i32 { let b2: Value = Rc::new(RefCell::new((!(*p.borrow()).is_null()).clone())); let b3: Value = Rc::new(RefCell::new((!(*np.borrow()).is_null()).clone())); assert!((*b2.borrow())); - assert!(!(*b3.borrow())); + assert!(((!(*b3.borrow()) as i32) != 0)); return 0; } diff --git a/tests/unit/out/refcount/expr_as_bool_c.rs b/tests/unit/out/refcount/expr_as_bool_c.rs index e795582..175ff75 100644 --- a/tests/unit/out/refcount/expr_as_bool_c.rs +++ b/tests/unit/out/refcount/expr_as_bool_c.rs @@ -28,10 +28,11 @@ fn main_0() -> i32 { if ((*a.borrow()) < (*b.borrow())) {} assert!(((*a.borrow()) == (*b.borrow()))); assert!( - !((({ + ((!((({ (*a.borrow_mut()) = (*b.borrow()); (*a.borrow()) }) as i32) + != 0) as i32) != 0) ); let c: Value = >::default(); diff --git a/tests/unit/out/unsafe/bool_condition_enum_c.rs b/tests/unit/out/unsafe/bool_condition_enum_c.rs index 73f8d9b..1f4ca54 100644 --- a/tests/unit/out/unsafe/bool_condition_enum_c.rs +++ b/tests/unit/out/unsafe/bool_condition_enum_c.rs @@ -46,6 +46,6 @@ unsafe fn main_0() -> i32 { let mut t9: i32 = (!(code != Code::from(0)) as i32); assert!(((t9) == (1))); let mut b4: bool = (code != Code::from(0)); - assert!(!(b4)); + assert!(((!(b4) as i32) != 0)); return 0; } diff --git a/tests/unit/out/unsafe/bool_condition_ptr_c.rs b/tests/unit/out/unsafe/bool_condition_ptr_c.rs index b26fcf1..91ffb8e 100644 --- a/tests/unit/out/unsafe/bool_condition_ptr_c.rs +++ b/tests/unit/out/unsafe/bool_condition_ptr_c.rs @@ -45,6 +45,6 @@ unsafe fn main_0() -> i32 { let mut b2: bool = !(p).is_null(); let mut b3: bool = !(np).is_null(); assert!(b2); - assert!(!(b3)); + assert!(((!(b3) as i32) != 0)); return 0; } diff --git a/tests/unit/out/unsafe/expr_as_bool_c.rs b/tests/unit/out/unsafe/expr_as_bool_c.rs index ae65ed2..209a367 100644 --- a/tests/unit/out/unsafe/expr_as_bool_c.rs +++ b/tests/unit/out/unsafe/expr_as_bool_c.rs @@ -30,10 +30,11 @@ unsafe fn main_0() -> i32 { if ((a) < (b)) {} assert!(((a) == (b))); assert!( - !((({ + ((!((({ a = b; a }) as i32) + != 0) as i32) != 0) ); let mut c: bool = false; From 6312bdc8f0d751252a657c6890d5b341d13f9aa1 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 18:32:19 +0100 Subject: [PATCH 10/23] Change from CreateConversionToBool to NormalizeToBool --- cpp2rust/converter/converter.cpp | 27 ++++++++++----------------- cpp2rust/converter/converter_lib.cpp | 2 +- cpp2rust/converter/converter_lib.h | 2 +- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index bfd3f1b..12518c8 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -965,12 +965,8 @@ bool Converter::VisitReturnStmt(clang::ReturnStmt *stmt) { } void Converter::ConvertCondition(clang::Expr *cond) { - if (!cond->getType()->isBooleanType()) { - PushExprKind push(*this, ExprKind::RValue); - Convert(CreateConversionToBool(cond, ctx_)); - return; - } - Convert(cond); + PushExprKind push(*this, ExprKind::RValue); + Convert(NormalizeToBool(cond, ctx_)); } bool Converter::VisitIfStmt(clang::IfStmt *stmt) { @@ -1016,10 +1012,7 @@ bool Converter::VisitDoStmt(clang::DoStmt *stmt) { Convert(stmt->getBody()); curr_for_inc_.pop(); StrCat(keyword::kIf, token::kNot); - { - PushParen paren(*this); - ConvertCondition(stmt->getCond()); - } + ConvertCondition(stmt->getCond()); { PushBrace if_brace(*this); StrCat(keyword::kBreak, token::kSemiColon); @@ -1755,13 +1748,13 @@ void Converter::ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr) { if (binop->isLogicalOp()) { PushParen outer(*this); { - PushParen lp(*this); - Convert(CreateConversionToBool(binop->getLHS(), ctx_)); + PushParen paren(*this); + ConvertCondition(binop->getLHS()); } StrCat(binop->getOpcodeStr()); { - PushParen rp(*this); - Convert(CreateConversionToBool(binop->getRHS(), ctx_)); + PushParen paren(*this); + ConvertCondition(binop->getRHS()); } return; } @@ -2157,10 +2150,10 @@ bool Converter::VisitUnaryOperator(clang::UnaryOperator *expr) { bool needs_int_cast = expr->getType()->isIntegerType(); PushParen paren_cast(*this, needs_int_cast); StrCat(token::kNot); - { + { PushParen paren(*this); - ConvertCondition(sub_expr); - } + ConvertCondition(sub_expr); + } if (needs_int_cast) { ConvertCast(expr->getType()); } diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 391fd87..d2deb3f 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -683,7 +683,7 @@ bool ContainsVAArgExpr(const clang::Stmt *stmt) { return false; } -clang::Expr *CreateConversionToBool(clang::Expr *expr, clang::ASTContext &ctx) { +clang::Expr *NormalizeToBool(clang::Expr *expr, clang::ASTContext &ctx) { if (expr->getType()->isBooleanType()) { return expr; } diff --git a/cpp2rust/converter/converter_lib.h b/cpp2rust/converter/converter_lib.h index 3a3cf25..97fbde6 100644 --- a/cpp2rust/converter/converter_lib.h +++ b/cpp2rust/converter/converter_lib.h @@ -154,7 +154,7 @@ bool IsBuiltinVaCopy(const clang::CallExpr *expr); bool ContainsVAArgExpr(const clang::Stmt *stmt); -clang::Expr *CreateConversionToBool(clang::Expr *expr, clang::ASTContext &ctx); +clang::Expr *NormalizeToBool(clang::Expr *expr, clang::ASTContext &ctx); std::vector GetTopLevelSwitchCases(clang::SwitchStmt *stmt); From 0739f288514a19b20a89224a22e3644f62e995ec Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 18:32:31 +0100 Subject: [PATCH 11/23] Update tests --- tests/unit/out/refcount/continue.rs | 4 ++-- tests/unit/out/refcount/string_escape.rs | 4 ++-- tests/unit/out/unsafe/continue.rs | 4 ++-- tests/unit/out/unsafe/string_escape.rs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/unit/out/refcount/continue.rs b/tests/unit/out/refcount/continue.rs index 50c3363..593780e 100644 --- a/tests/unit/out/refcount/continue.rs +++ b/tests/unit/out/refcount/continue.rs @@ -35,14 +35,14 @@ fn main_0() -> i32 { 'loop_: while ((*k2.borrow()) < 5) { let k3: Value = Rc::new(RefCell::new(0)); 'loop_: while ((*k3.borrow()) < 5) { - if (((((*k1.borrow()) + (*k2.borrow())) + (*k3.borrow())) % 2) == 0) { + if ((((((*k1.borrow()) + (*k2.borrow())) + (*k3.borrow())) as i32) % 2) == 0) { (*k3.borrow_mut()).postfix_inc(); continue 'loop_; } (*out.borrow_mut()).prefix_inc(); (*k3.borrow_mut()).postfix_inc(); } - if ((((*k1.borrow()) + (*k2.borrow())) % 2) == 0) { + if (((((*k1.borrow()) + (*k2.borrow())) as i32) % 2) == 0) { (*k2.borrow_mut()).postfix_inc(); continue 'loop_; } diff --git a/tests/unit/out/refcount/string_escape.rs b/tests/unit/out/refcount/string_escape.rs index 85541a2..5909c61 100644 --- a/tests/unit/out/refcount/string_escape.rs +++ b/tests/unit/out/refcount/string_escape.rs @@ -23,8 +23,8 @@ fn main_0() -> i32 { ); let i: Value = Rc::new(RefCell::new(0)); 'loop_: while ((*i.borrow()) - < (((::std::mem::size_of::<[u8; 40]>() as u64 as u64) - .wrapping_div(::std::mem::size_of::() as u64 as u64)) as i32)) + < ((((::std::mem::size_of::<[u8; 40]>() as u64 as u64) + .wrapping_div(::std::mem::size_of::() as u64 as u64)) as u64) as i32)) { assert!({ let _lhs = (((*special.borrow()).offset((*i.borrow()) as isize).read()) as i32); diff --git a/tests/unit/out/unsafe/continue.rs b/tests/unit/out/unsafe/continue.rs index a26dd84..ad204b1 100644 --- a/tests/unit/out/unsafe/continue.rs +++ b/tests/unit/out/unsafe/continue.rs @@ -37,14 +37,14 @@ unsafe fn main_0() -> i32 { 'loop_: while ((k2) < (5)) { let mut k3: i32 = 0; 'loop_: while ((k3) < (5)) { - if (((((k1) + (k2)) + (k3)) % (2)) == (0)) { + if ((((((k1) + (k2)) + (k3)) as i32) % (2)) == (0)) { k3.postfix_inc(); continue 'loop_; } out.prefix_inc(); k3.postfix_inc(); } - if ((((k1) + (k2)) % (2)) == (0)) { + if (((((k1) + (k2)) as i32) % (2)) == (0)) { k2.postfix_inc(); continue 'loop_; } diff --git a/tests/unit/out/unsafe/string_escape.rs b/tests/unit/out/unsafe/string_escape.rs index 285f6dd..ff21009 100644 --- a/tests/unit/out/unsafe/string_escape.rs +++ b/tests/unit/out/unsafe/string_escape.rs @@ -22,8 +22,8 @@ unsafe fn main_0() -> i32 { ];; let mut i: i32 = 0; 'loop_: while ((i) - < (((::std::mem::size_of::<[u8; 40]>() as u64 as u64) - .wrapping_div(::std::mem::size_of::() as u64 as u64)) as i32)) + < ((((::std::mem::size_of::<[u8; 40]>() as u64 as u64) + .wrapping_div(::std::mem::size_of::() as u64 as u64)) as u64) as i32)) { assert!((((*special.offset((i) as isize)) as i32) == (expected[(i) as usize] as i32))); i.postfix_inc(); From 3ee82dbfd3c6fd17bf5d31eebdf1e8c013ec4a48 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 18:35:12 +0100 Subject: [PATCH 12/23] clang-format --- cpp2rust/converter/converter.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 12518c8..74fdcf0 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1012,7 +1012,10 @@ bool Converter::VisitDoStmt(clang::DoStmt *stmt) { Convert(stmt->getBody()); curr_for_inc_.pop(); StrCat(keyword::kIf, token::kNot); - ConvertCondition(stmt->getCond()); + { + PushParen paren(*this); + ConvertCondition(stmt->getCond()); + } { PushBrace if_brace(*this); StrCat(keyword::kBreak, token::kSemiColon); @@ -1748,13 +1751,13 @@ void Converter::ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr) { if (binop->isLogicalOp()) { PushParen outer(*this); { - PushParen paren(*this); - ConvertCondition(binop->getLHS()); + PushParen paren(*this); + ConvertCondition(binop->getLHS()); } StrCat(binop->getOpcodeStr()); { - PushParen paren(*this); - ConvertCondition(binop->getRHS()); + PushParen paren(*this); + ConvertCondition(binop->getRHS()); } return; } @@ -2150,10 +2153,10 @@ bool Converter::VisitUnaryOperator(clang::UnaryOperator *expr) { bool needs_int_cast = expr->getType()->isIntegerType(); PushParen paren_cast(*this, needs_int_cast); StrCat(token::kNot); - { + { PushParen paren(*this); - ConvertCondition(sub_expr); - } + ConvertCondition(sub_expr); + } if (needs_int_cast) { ConvertCast(expr->getType()); } From 14af91e1950ff6d722de2e5ab9a3965729a8cf03 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 18:42:22 +0100 Subject: [PATCH 13/23] Drop useless paren --- cpp2rust/converter/converter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 74fdcf0..a20ec93 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1749,7 +1749,6 @@ void Converter::ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr) { } // Distribute bool conversion to each argument of the logical op. if (binop->isLogicalOp()) { - PushParen outer(*this); { PushParen paren(*this); ConvertCondition(binop->getLHS()); From 6bbcfe0ef805b2e1b48b41cdbf8344151d79e45a Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 18:42:31 +0100 Subject: [PATCH 14/23] Update tests --- .../out/refcount/bool_condition_logical_c.rs | 20 +++++++++---------- .../out/unsafe/bool_condition_logical_c.rs | 20 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/unit/out/refcount/bool_condition_logical_c.rs b/tests/unit/out/refcount/bool_condition_logical_c.rs index 984a9dc..f775cd4 100644 --- a/tests/unit/out/refcount/bool_condition_logical_c.rs +++ b/tests/unit/out/refcount/bool_condition_logical_c.rs @@ -42,38 +42,38 @@ fn main_0() -> i32 { let np: Value> = Rc::new(RefCell::new(Default::default())); let u: Value = Rc::new(RefCell::new(4_u32)); let code: Value = Rc::new(RefCell::new(Code::from((Code::CODE_OK as i32)))); - if (((*n.borrow()) != 0) && (!(*p.borrow()).is_null())) { + if ((*n.borrow()) != 0) && (!(*p.borrow()).is_null()) { assert!((1 != 0)); } - if (((*n.borrow()) != 0) && (!(*np.borrow()).is_null())) { + if ((*n.borrow()) != 0) && (!(*np.borrow()).is_null()) { assert!((0 != 0)); } - if (((*zero.borrow()) != 0) || (!(*p.borrow()).is_null())) { + if ((*zero.borrow()) != 0) || (!(*p.borrow()).is_null()) { assert!((1 != 0)); } - if (((*zero.borrow()) != 0) || (!(*np.borrow()).is_null())) { + if ((*zero.borrow()) != 0) || (!(*np.borrow()).is_null()) { assert!((0 != 0)); } - if (((((*n.borrow()) != 0) && ((*u.borrow()) != 0)) && (!(*p.borrow()).is_null())) - && (((*code.borrow()) as u32) == ((Code::CODE_OK as i32) as u32))) + if ((((*n.borrow()) != 0) && ((*u.borrow()) != 0)) && (!(*p.borrow()).is_null())) + && (((*code.borrow()) as u32) == ((Code::CODE_OK as i32) as u32)) { assert!((1 != 0)); } (*side_effect.with(Value::clone).borrow_mut()) = 0; - if (((*zero.borrow()) != 0) + if ((*zero.borrow()) != 0) && (({ let _v: i32 = 1; observe_0(_v) - }) != 0)) + }) != 0) { assert!((0 != 0)); } assert!(((*side_effect.with(Value::clone).borrow()) == 0)); - if (((*n.borrow()) != 0) + if ((*n.borrow()) != 0) || (({ let _v: i32 = 1; observe_0(_v) - }) != 0)) + }) != 0) { assert!((1 != 0)); } diff --git a/tests/unit/out/unsafe/bool_condition_logical_c.rs b/tests/unit/out/unsafe/bool_condition_logical_c.rs index 1131d88..3fab7b5 100644 --- a/tests/unit/out/unsafe/bool_condition_logical_c.rs +++ b/tests/unit/out/unsafe/bool_condition_logical_c.rs @@ -41,38 +41,38 @@ unsafe fn main_0() -> i32 { let mut np: *mut i32 = Default::default(); let mut u: u32 = 4_u32; let mut code: Code = Code::from((Code::CODE_OK as i32)); - if ((n != 0) && (!(p).is_null())) { + if (n != 0) && (!(p).is_null()) { assert!((1 != 0)); } - if ((n != 0) && (!(np).is_null())) { + if (n != 0) && (!(np).is_null()) { assert!((0 != 0)); } - if ((zero != 0) || (!(p).is_null())) { + if (zero != 0) || (!(p).is_null()) { assert!((1 != 0)); } - if ((zero != 0) || (!(np).is_null())) { + if (zero != 0) || (!(np).is_null()) { assert!((0 != 0)); } - if ((((n != 0) && (u != 0)) && (!(p).is_null())) - && ((code as u32) == ((Code::CODE_OK as i32) as u32))) + if (((n != 0) && (u != 0)) && (!(p).is_null())) + && ((code as u32) == ((Code::CODE_OK as i32) as u32)) { assert!((1 != 0)); } side_effect = 0; - if ((zero != 0) + if (zero != 0) && ((unsafe { let _v: i32 = 1; observe_0(_v) - }) != 0)) + }) != 0) { assert!((0 != 0)); } assert!(((side_effect) == (0))); - if ((n != 0) + if (n != 0) || ((unsafe { let _v: i32 = 1; observe_0(_v) - }) != 0)) + }) != 0) { assert!((1 != 0)); } From b37fad7f7b2bf67eb444aedd687d36058a851e30 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 18:42:43 +0100 Subject: [PATCH 15/23] Add comments --- cpp2rust/converter/converter_lib.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index d2deb3f..ed6ddc9 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -688,6 +688,8 @@ clang::Expr *NormalizeToBool(clang::Expr *expr, clang::ASTContext &ctx) { return expr; } + // If logical not returns integer, then craft a new logical not that returns + // bool. if (auto bin = clang::dyn_cast(expr)) { if (bin->getOpcode() == clang::UO_LNot) { return clang::UnaryOperator::Create( @@ -697,6 +699,7 @@ clang::Expr *NormalizeToBool(clang::Expr *expr, clang::ASTContext &ctx) { } } + // Either to pointer -> bool, or int -> bool. clang::CastKind cast_kind; if (expr->getType()->isPointerType()) { cast_kind = clang::CK_PointerToBoolean; From d5df023540a1e393ea5999ce0284eff51c0424fe Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 18:59:28 +0100 Subject: [PATCH 16/23] Remove extra cast --- cpp2rust/converter/converter.cpp | 3 ++- tests/benchmarks/out/refcount/bfs.rs | 6 +++--- tests/benchmarks/out/unsafe/bfs.rs | 4 ++-- tests/unit/out/refcount/assert.rs | 2 +- tests/unit/out/refcount/bool_condition_enum.rs | 10 ++++------ tests/unit/out/refcount/bool_condition_enum_c.rs | 4 ++-- tests/unit/out/refcount/bool_condition_int.rs | 8 ++++---- tests/unit/out/refcount/bool_condition_int_c.rs | 4 ++-- tests/unit/out/refcount/bool_condition_ptr.rs | 12 +++++------- tests/unit/out/refcount/bool_condition_ptr_c.rs | 4 ++-- tests/unit/out/refcount/expr_as_bool_cpp.rs | 4 ++-- tests/unit/out/refcount/fn_ptr_as_condition.rs | 2 +- tests/unit/out/refcount/no_direct_callee.rs | 2 +- tests/unit/out/refcount/polymorphism.rs | 2 +- .../switch_stacked_with_inner_fallthrough.rs | 2 +- tests/unit/out/refcount/vector.rs | 2 +- tests/unit/out/unsafe/assert.rs | 2 +- tests/unit/out/unsafe/bool_condition_enum.rs | 8 ++++---- tests/unit/out/unsafe/bool_condition_enum_c.rs | 4 ++-- tests/unit/out/unsafe/bool_condition_int.rs | 8 ++++---- tests/unit/out/unsafe/bool_condition_int_c.rs | 4 ++-- tests/unit/out/unsafe/bool_condition_ptr.rs | 10 +++++----- tests/unit/out/unsafe/bool_condition_ptr_c.rs | 4 ++-- tests/unit/out/unsafe/expr_as_bool_cpp.rs | 4 ++-- tests/unit/out/unsafe/fn_ptr_as_condition.rs | 2 +- tests/unit/out/unsafe/no_direct_callee.rs | 2 +- tests/unit/out/unsafe/polymorphism.rs | 2 +- .../unsafe/switch_stacked_with_inner_fallthrough.rs | 2 +- tests/unit/out/unsafe/vector.rs | 2 +- 29 files changed, 61 insertions(+), 64 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index a20ec93..12a9966 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -2149,7 +2149,8 @@ bool Converter::VisitUnaryOperator(clang::UnaryOperator *expr) { computed_expr_type_ = ComputedExprType::FreshValue; break; case clang::UO_LNot: { - bool needs_int_cast = expr->getType()->isIntegerType(); + bool needs_int_cast = + expr->getType()->isIntegerType() && !expr->getType()->isBooleanType(); PushParen paren_cast(*this, needs_int_cast); StrCat(token::kNot); { diff --git a/tests/benchmarks/out/refcount/bfs.rs b/tests/benchmarks/out/refcount/bfs.rs index 63370d0..8c71337 100644 --- a/tests/benchmarks/out/refcount/bfs.rs +++ b/tests/benchmarks/out/refcount/bfs.rs @@ -152,7 +152,7 @@ pub fn BFS_0(graph: Ptr, start_vertex: u32) -> Ptr { let _elem: i32 = ((*start_vertex.borrow()) as i32); (*Q.borrow()).enqueue(_elem) }); - 'loop_: while (!({ (*Q.borrow()).empty() }) as bool) { + 'loop_: while !({ (*Q.borrow()).empty() }) { let current_vertex: Value = Rc::new(RefCell::new((({ (*Q.borrow()).dequeue() }) as i32))); let head: Value> = Rc::new(RefCell::new( @@ -165,9 +165,9 @@ pub fn BFS_0(graph: Ptr, start_vertex: u32) -> Ptr { let adj_vertex: Value = Rc::new(RefCell::new( ((*(*(*head.borrow()).upgrade().deref()).vertex.borrow()) as i32), )); - if (!((*visited.borrow()) + if !((*visited.borrow()) .offset((*adj_vertex.borrow()) as isize) - .read()) as bool) + .read()) { (*visited.borrow()) .offset((*adj_vertex.borrow()) as isize) diff --git a/tests/benchmarks/out/unsafe/bfs.rs b/tests/benchmarks/out/unsafe/bfs.rs index ea6c7bd..df11cfc 100644 --- a/tests/benchmarks/out/unsafe/bfs.rs +++ b/tests/benchmarks/out/unsafe/bfs.rs @@ -95,12 +95,12 @@ pub unsafe fn BFS_0(graph: *const Graph, mut start_vertex: u32) -> *mut u32 { let _elem: i32 = (start_vertex as i32); Q.enqueue(_elem) }); - 'loop_: while (!(unsafe { Q.empty() }) as bool) { + 'loop_: while !(unsafe { Q.empty() }) { let mut current_vertex: i32 = ((unsafe { Q.dequeue() }) as i32); let mut head: *mut GraphNode = (*(*graph).adj.offset((current_vertex) as isize)); 'loop_: while !((head).is_null()) { let mut adj_vertex: i32 = ((*head).vertex as i32); - if (!(*visited.offset((adj_vertex) as isize)) as bool) { + if !(*visited.offset((adj_vertex) as isize)) { (*visited.offset((adj_vertex) as isize)) = true; (unsafe { let _elem: i32 = adj_vertex; diff --git a/tests/unit/out/refcount/assert.rs b/tests/unit/out/refcount/assert.rs index 9f74954..1463a3c 100644 --- a/tests/unit/out/refcount/assert.rs +++ b/tests/unit/out/refcount/assert.rs @@ -10,6 +10,6 @@ pub fn main() { std::process::exit(main_0()); } fn main_0() -> i32 { - assert!((!(0 != 0) as bool)); + assert!(!(0 != 0)); return 1; } diff --git a/tests/unit/out/refcount/bool_condition_enum.rs b/tests/unit/out/refcount/bool_condition_enum.rs index 645f53d..312017a 100644 --- a/tests/unit/out/refcount/bool_condition_enum.rs +++ b/tests/unit/out/refcount/bool_condition_enum.rs @@ -32,20 +32,18 @@ fn main_0() -> i32 { if ((*code.borrow()) != Code::from(0)) { assert!(false); } - if (!((*code.borrow()) != Code::from(0)) as bool) { + if !((*code.borrow()) != Code::from(0)) { assert!(true); } if ((*err.borrow()) != Code::from(0)) { assert!(true); } - if (!((*err.borrow()) != Code::from(0)) as bool) { + if !((*err.borrow()) != Code::from(0)) { assert!(false); } - let t9: Value = Rc::new(RefCell::new( - ((!((*code.borrow()) != Code::from(0)) as bool) as i32), - )); + let t9: Value = Rc::new(RefCell::new((!((*code.borrow()) != Code::from(0)) as i32))); assert!(((*t9.borrow()) == 1)); let b4: Value = Rc::new(RefCell::new(((*code.borrow()) != Code::from(0)).clone())); - assert!((!(*b4.borrow()) as bool)); + assert!(!(*b4.borrow())); return 0; } diff --git a/tests/unit/out/refcount/bool_condition_enum_c.rs b/tests/unit/out/refcount/bool_condition_enum_c.rs index b53a516..150f261 100644 --- a/tests/unit/out/refcount/bool_condition_enum_c.rs +++ b/tests/unit/out/refcount/bool_condition_enum_c.rs @@ -32,13 +32,13 @@ fn main_0() -> i32 { if ((*code.borrow()) != Code::from(0)) { assert!((0 != 0)); } - if (!((*code.borrow()) != Code::from(0)) as bool) { + if !((*code.borrow()) != Code::from(0)) { assert!((1 != 0)); } if ((*err.borrow()) != Code::from(0)) { assert!((1 != 0)); } - if (!((*err.borrow()) != Code::from(0)) as bool) { + if !((*err.borrow()) != Code::from(0)) { assert!((0 != 0)); } let t9: Value = Rc::new(RefCell::new((!((*code.borrow()) != Code::from(0)) as i32))); diff --git a/tests/unit/out/refcount/bool_condition_int.rs b/tests/unit/out/refcount/bool_condition_int.rs index 40ac436..ad21fae 100644 --- a/tests/unit/out/refcount/bool_condition_int.rs +++ b/tests/unit/out/refcount/bool_condition_int.rs @@ -19,13 +19,13 @@ fn main_0() -> i32 { if ((*n.borrow()) != 0) { assert!(true); } - if (!((*n.borrow()) != 0) as bool) { + if !((*n.borrow()) != 0) { assert!(false); } if ((*zero.borrow()) != 0) { assert!(false); } - if (!((*zero.borrow()) != 0) as bool) { + if !((*zero.borrow()) != 0) { assert!(true); } if ((*u.borrow()) != 0) { @@ -61,9 +61,9 @@ fn main_0() -> i32 { 200 })); assert!(((*t2.borrow()) == 200)); - let t7: Value = Rc::new(RefCell::new(((!((*n.borrow()) != 0) as bool) as i32))); + let t7: Value = Rc::new(RefCell::new((!((*n.borrow()) != 0) as i32))); assert!(((*t7.borrow()) == 0)); - let t8: Value = Rc::new(RefCell::new(((!((*zero.borrow()) != 0) as bool) as i32))); + let t8: Value = Rc::new(RefCell::new((!((*zero.borrow()) != 0) as i32))); assert!(((*t8.borrow()) == 1)); let b1: Value = Rc::new(RefCell::new(((*n.borrow()) != 0))); assert!((*b1.borrow())); diff --git a/tests/unit/out/refcount/bool_condition_int_c.rs b/tests/unit/out/refcount/bool_condition_int_c.rs index fc5fab5..7d68528 100644 --- a/tests/unit/out/refcount/bool_condition_int_c.rs +++ b/tests/unit/out/refcount/bool_condition_int_c.rs @@ -19,13 +19,13 @@ fn main_0() -> i32 { if ((*n.borrow()) != 0) { assert!((1 != 0)); } - if (!((*n.borrow()) != 0) as bool) { + if !((*n.borrow()) != 0) { assert!((0 != 0)); } if ((*zero.borrow()) != 0) { assert!((0 != 0)); } - if (!((*zero.borrow()) != 0) as bool) { + if !((*zero.borrow()) != 0) { assert!((1 != 0)); } if ((*u.borrow()) != 0) { diff --git a/tests/unit/out/refcount/bool_condition_ptr.rs b/tests/unit/out/refcount/bool_condition_ptr.rs index e31fe9c..c600434 100644 --- a/tests/unit/out/refcount/bool_condition_ptr.rs +++ b/tests/unit/out/refcount/bool_condition_ptr.rs @@ -16,13 +16,13 @@ fn main_0() -> i32 { if !(*p.borrow()).is_null() { assert!(true); } - if (!(!(*p.borrow()).is_null()) as bool) { + if !(!(*p.borrow()).is_null()) { assert!(false); } if !(*np.borrow()).is_null() { assert!(false); } - if (!(!(*np.borrow()).is_null()) as bool) { + if !(!(*np.borrow()).is_null()) { assert!(true); } let iter: Value> = Rc::new(RefCell::new((*p.borrow()).clone())); @@ -36,15 +36,13 @@ fn main_0() -> i32 { assert!(((*t3.borrow()) == 1)); let t4: Value = Rc::new(RefCell::new(if !(*np.borrow()).is_null() { 1 } else { 0 })); assert!(((*t4.borrow()) == 0)); - let t5: Value = Rc::new(RefCell::new(((!(!(*p.borrow()).is_null()) as bool) as i32))); + let t5: Value = Rc::new(RefCell::new((!(!(*p.borrow()).is_null()) as i32))); assert!(((*t5.borrow()) == 0)); - let t6: Value = Rc::new(RefCell::new( - ((!(!(*np.borrow()).is_null()) as bool) as i32), - )); + let t6: Value = Rc::new(RefCell::new((!(!(*np.borrow()).is_null()) as i32))); assert!(((*t6.borrow()) == 1)); let b2: Value = Rc::new(RefCell::new((!(*p.borrow()).is_null()).clone())); let b3: Value = Rc::new(RefCell::new((!(*np.borrow()).is_null()).clone())); assert!((*b2.borrow())); - assert!((!(*b3.borrow()) as bool)); + assert!(!(*b3.borrow())); return 0; } diff --git a/tests/unit/out/refcount/bool_condition_ptr_c.rs b/tests/unit/out/refcount/bool_condition_ptr_c.rs index f1f8cc8..bff9299 100644 --- a/tests/unit/out/refcount/bool_condition_ptr_c.rs +++ b/tests/unit/out/refcount/bool_condition_ptr_c.rs @@ -16,13 +16,13 @@ fn main_0() -> i32 { if !(*p.borrow()).is_null() { assert!((1 != 0)); } - if (!(!(*p.borrow()).is_null()) as bool) { + if !(!(*p.borrow()).is_null()) { assert!((0 != 0)); } if !(*np.borrow()).is_null() { assert!((0 != 0)); } - if (!(!(*np.borrow()).is_null()) as bool) { + if !(!(*np.borrow()).is_null()) { assert!((1 != 0)); } let iter: Value> = Rc::new(RefCell::new((*p.borrow()).clone())); diff --git a/tests/unit/out/refcount/expr_as_bool_cpp.rs b/tests/unit/out/refcount/expr_as_bool_cpp.rs index 06b258b..e795582 100644 --- a/tests/unit/out/refcount/expr_as_bool_cpp.rs +++ b/tests/unit/out/refcount/expr_as_bool_cpp.rs @@ -28,11 +28,11 @@ fn main_0() -> i32 { if ((*a.borrow()) < (*b.borrow())) {} assert!(((*a.borrow()) == (*b.borrow()))); assert!( - (!((({ + !((({ (*a.borrow_mut()) = (*b.borrow()); (*a.borrow()) }) as i32) - != 0) as bool) + != 0) ); let c: Value = >::default(); (*c.borrow_mut()) = ({ diff --git a/tests/unit/out/refcount/fn_ptr_as_condition.rs b/tests/unit/out/refcount/fn_ptr_as_condition.rs index 9ac3ca0..d6a4e12 100644 --- a/tests/unit/out/refcount/fn_ptr_as_condition.rs +++ b/tests/unit/out/refcount/fn_ptr_as_condition.rs @@ -43,7 +43,7 @@ fn main_0() -> i32 { }); assert!(((*b.borrow()) == 5)); let fn_: Value)>> = Rc::new(RefCell::new(FnPtr::null())); - if (!(!(*fn_.borrow()).is_null()) as bool) { + if !(!(*fn_.borrow()).is_null()) { (*fn_.borrow_mut()) = FnPtr::)>::new(double_it_0); } let c: Value = Rc::new(RefCell::new(3)); diff --git a/tests/unit/out/refcount/no_direct_callee.rs b/tests/unit/out/refcount/no_direct_callee.rs index 867bba1..582dca7 100644 --- a/tests/unit/out/refcount/no_direct_callee.rs +++ b/tests/unit/out/refcount/no_direct_callee.rs @@ -11,7 +11,7 @@ pub fn test1_0() -> bool { } pub fn test_1(fn_: FnPtr bool>) -> i32 { let fn_: Value bool>> = Rc::new(RefCell::new(fn_)); - if (!({ (*(*fn_.borrow()))() }) as bool) { + if !({ (*(*fn_.borrow()))() }) { return 1; } return 0; diff --git a/tests/unit/out/refcount/polymorphism.rs b/tests/unit/out/refcount/polymorphism.rs index ccadbf9..8add81b 100644 --- a/tests/unit/out/refcount/polymorphism.rs +++ b/tests/unit/out/refcount/polymorphism.rs @@ -58,5 +58,5 @@ fn main_0() -> i32 { let eat2: Value = Rc::new(RefCell::new( ({ (*(*animal.borrow()).upgrade().deref()).bark() }), )); - return (((*eat1.borrow()) && (!(*eat2.borrow()) as bool)) as i32); + return (((*eat1.borrow()) && !(*eat2.borrow())) as i32); } diff --git a/tests/unit/out/refcount/switch_stacked_with_inner_fallthrough.rs b/tests/unit/out/refcount/switch_stacked_with_inner_fallthrough.rs index 9073061..8241abc 100644 --- a/tests/unit/out/refcount/switch_stacked_with_inner_fallthrough.rs +++ b/tests/unit/out/refcount/switch_stacked_with_inner_fallthrough.rs @@ -12,7 +12,7 @@ pub fn stacked_with_inner_fallthrough_0(x: i32, flag: i32) -> i32 { let r: Value = Rc::new(RefCell::new(0)); switch!(match (*x.borrow()) { v if v == 1 || v == 2 || v == 3 => { - if (!((*flag.borrow()) != 0) as bool) { + if !((*flag.borrow()) != 0) { (*r.borrow_mut()) = 50; break; }; diff --git a/tests/unit/out/refcount/vector.rs b/tests/unit/out/refcount/vector.rs index 2a9a070..6f3ad77 100644 --- a/tests/unit/out/refcount/vector.rs +++ b/tests/unit/out/refcount/vector.rs @@ -17,7 +17,7 @@ fn main_0() -> i32 { assert!(((*v1.borrow()).len() as u64 == 0_u64)); assert!((*v1.borrow()).is_empty()); (*v1.borrow_mut()).push(1); - assert!((!((*v1.borrow()).is_empty()) as bool)); + assert!(!((*v1.borrow()).is_empty())); (*v1.borrow_mut()).pop(); assert!((*v1.borrow()).is_empty()); let s1: Value = Rc::new(RefCell::new((*v1.borrow()).len() as u64)); diff --git a/tests/unit/out/unsafe/assert.rs b/tests/unit/out/unsafe/assert.rs index 5751447..70b1ff7 100644 --- a/tests/unit/out/unsafe/assert.rs +++ b/tests/unit/out/unsafe/assert.rs @@ -12,6 +12,6 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - assert!((!(0 != 0) as bool)); + assert!(!(0 != 0)); return 1; } diff --git a/tests/unit/out/unsafe/bool_condition_enum.rs b/tests/unit/out/unsafe/bool_condition_enum.rs index a20fc91..2127444 100644 --- a/tests/unit/out/unsafe/bool_condition_enum.rs +++ b/tests/unit/out/unsafe/bool_condition_enum.rs @@ -34,18 +34,18 @@ unsafe fn main_0() -> i32 { if (code != Code::from(0)) { assert!(false); } - if (!(code != Code::from(0)) as bool) { + if !(code != Code::from(0)) { assert!(true); } if (err != Code::from(0)) { assert!(true); } - if (!(err != Code::from(0)) as bool) { + if !(err != Code::from(0)) { assert!(false); } - let mut t9: i32 = ((!(code != Code::from(0)) as bool) as i32); + let mut t9: i32 = (!(code != Code::from(0)) as i32); assert!(((t9) == (1))); let mut b4: bool = (code != Code::from(0)); - assert!((!(b4) as bool)); + assert!(!(b4)); return 0; } diff --git a/tests/unit/out/unsafe/bool_condition_enum_c.rs b/tests/unit/out/unsafe/bool_condition_enum_c.rs index 1f4ca54..9cebcb9 100644 --- a/tests/unit/out/unsafe/bool_condition_enum_c.rs +++ b/tests/unit/out/unsafe/bool_condition_enum_c.rs @@ -34,13 +34,13 @@ unsafe fn main_0() -> i32 { if (code != Code::from(0)) { assert!((0 != 0)); } - if (!(code != Code::from(0)) as bool) { + if !(code != Code::from(0)) { assert!((1 != 0)); } if (err != Code::from(0)) { assert!((1 != 0)); } - if (!(err != Code::from(0)) as bool) { + if !(err != Code::from(0)) { assert!((0 != 0)); } let mut t9: i32 = (!(code != Code::from(0)) as i32); diff --git a/tests/unit/out/unsafe/bool_condition_int.rs b/tests/unit/out/unsafe/bool_condition_int.rs index c07d2f6..ba4559a 100644 --- a/tests/unit/out/unsafe/bool_condition_int.rs +++ b/tests/unit/out/unsafe/bool_condition_int.rs @@ -21,13 +21,13 @@ unsafe fn main_0() -> i32 { if (n != 0) { assert!(true); } - if (!(n != 0) as bool) { + if !(n != 0) { assert!(false); } if (zero != 0) { assert!(false); } - if (!(zero != 0) as bool) { + if !(zero != 0) { assert!(true); } if (u != 0) { @@ -59,9 +59,9 @@ unsafe fn main_0() -> i32 { assert!(((t) == (100))); let mut t2: i32 = if (zero != 0) { 100 } else { 200 }; assert!(((t2) == (200))); - let mut t7: i32 = ((!(n != 0) as bool) as i32); + let mut t7: i32 = (!(n != 0) as i32); assert!(((t7) == (0))); - let mut t8: i32 = ((!(zero != 0) as bool) as i32); + let mut t8: i32 = (!(zero != 0) as i32); assert!(((t8) == (1))); let mut b1: bool = (n != 0); assert!(b1); diff --git a/tests/unit/out/unsafe/bool_condition_int_c.rs b/tests/unit/out/unsafe/bool_condition_int_c.rs index 22e3134..3847ed1 100644 --- a/tests/unit/out/unsafe/bool_condition_int_c.rs +++ b/tests/unit/out/unsafe/bool_condition_int_c.rs @@ -21,13 +21,13 @@ unsafe fn main_0() -> i32 { if (n != 0) { assert!((1 != 0)); } - if (!(n != 0) as bool) { + if !(n != 0) { assert!((0 != 0)); } if (zero != 0) { assert!((0 != 0)); } - if (!(zero != 0) as bool) { + if !(zero != 0) { assert!((1 != 0)); } if (u != 0) { diff --git a/tests/unit/out/unsafe/bool_condition_ptr.rs b/tests/unit/out/unsafe/bool_condition_ptr.rs index 9535af8..0931063 100644 --- a/tests/unit/out/unsafe/bool_condition_ptr.rs +++ b/tests/unit/out/unsafe/bool_condition_ptr.rs @@ -18,13 +18,13 @@ unsafe fn main_0() -> i32 { if !(p).is_null() { assert!(true); } - if (!(!(p).is_null()) as bool) { + if !(!(p).is_null()) { assert!(false); } if !(np).is_null() { assert!(false); } - if (!(!(np).is_null()) as bool) { + if !(!(np).is_null()) { assert!(true); } let mut iter: *mut i32 = p; @@ -38,13 +38,13 @@ unsafe fn main_0() -> i32 { assert!(((t3) == (1))); let mut t4: i32 = if !(np).is_null() { 1 } else { 0 }; assert!(((t4) == (0))); - let mut t5: i32 = ((!(!(p).is_null()) as bool) as i32); + let mut t5: i32 = (!(!(p).is_null()) as i32); assert!(((t5) == (0))); - let mut t6: i32 = ((!(!(np).is_null()) as bool) as i32); + let mut t6: i32 = (!(!(np).is_null()) as i32); assert!(((t6) == (1))); let mut b2: bool = !(p).is_null(); let mut b3: bool = !(np).is_null(); assert!(b2); - assert!((!(b3) as bool)); + assert!(!(b3)); return 0; } diff --git a/tests/unit/out/unsafe/bool_condition_ptr_c.rs b/tests/unit/out/unsafe/bool_condition_ptr_c.rs index 91ffb8e..622279b 100644 --- a/tests/unit/out/unsafe/bool_condition_ptr_c.rs +++ b/tests/unit/out/unsafe/bool_condition_ptr_c.rs @@ -18,13 +18,13 @@ unsafe fn main_0() -> i32 { if !(p).is_null() { assert!((1 != 0)); } - if (!(!(p).is_null()) as bool) { + if !(!(p).is_null()) { assert!((0 != 0)); } if !(np).is_null() { assert!((0 != 0)); } - if (!(!(np).is_null()) as bool) { + if !(!(np).is_null()) { assert!((1 != 0)); } let mut iter: *mut i32 = p; diff --git a/tests/unit/out/unsafe/expr_as_bool_cpp.rs b/tests/unit/out/unsafe/expr_as_bool_cpp.rs index acda5b9..ae65ed2 100644 --- a/tests/unit/out/unsafe/expr_as_bool_cpp.rs +++ b/tests/unit/out/unsafe/expr_as_bool_cpp.rs @@ -30,11 +30,11 @@ unsafe fn main_0() -> i32 { if ((a) < (b)) {} assert!(((a) == (b))); assert!( - (!((({ + !((({ a = b; a }) as i32) - != 0) as bool) + != 0) ); let mut c: bool = false; c = ({ diff --git a/tests/unit/out/unsafe/fn_ptr_as_condition.rs b/tests/unit/out/unsafe/fn_ptr_as_condition.rs index 09f2d67..88c1e5c 100644 --- a/tests/unit/out/unsafe/fn_ptr_as_condition.rs +++ b/tests/unit/out/unsafe/fn_ptr_as_condition.rs @@ -38,7 +38,7 @@ unsafe fn main_0() -> i32 { }); assert!(((b) == (5))); let mut fn_: Option = None; - if (!(!(fn_).is_none()) as bool) { + if !(!(fn_).is_none()) { fn_ = Some(double_it_0); } let mut c: i32 = 3; diff --git a/tests/unit/out/unsafe/no_direct_callee.rs b/tests/unit/out/unsafe/no_direct_callee.rs index 20d2198..6d50bee 100644 --- a/tests/unit/out/unsafe/no_direct_callee.rs +++ b/tests/unit/out/unsafe/no_direct_callee.rs @@ -10,7 +10,7 @@ pub unsafe fn test1_0() -> bool { return false; } pub unsafe fn test_1(mut fn_: Option bool>) -> i32 { - if (!(unsafe { (fn_).unwrap()() }) as bool) { + if !(unsafe { (fn_).unwrap()() }) { return 1; } return 0; diff --git a/tests/unit/out/unsafe/polymorphism.rs b/tests/unit/out/unsafe/polymorphism.rs index 8801a8c..fe5c8e9 100644 --- a/tests/unit/out/unsafe/polymorphism.rs +++ b/tests/unit/out/unsafe/polymorphism.rs @@ -42,5 +42,5 @@ unsafe fn main_0() -> i32 { let mut cat: Cat = ::default(); animal = (&mut cat as *mut Cat); let mut eat2: bool = (unsafe { (*animal.cast_const()).bark() }); - return (((eat1) && (!(eat2) as bool)) as i32); + return (((eat1) && (!(eat2))) as i32); } diff --git a/tests/unit/out/unsafe/switch_stacked_with_inner_fallthrough.rs b/tests/unit/out/unsafe/switch_stacked_with_inner_fallthrough.rs index adf6995..515da37 100644 --- a/tests/unit/out/unsafe/switch_stacked_with_inner_fallthrough.rs +++ b/tests/unit/out/unsafe/switch_stacked_with_inner_fallthrough.rs @@ -10,7 +10,7 @@ pub unsafe fn stacked_with_inner_fallthrough_0(mut x: i32, mut flag: i32) -> i32 let mut r: i32 = 0; switch!(match x { v if v == 1 || v == 2 || v == 3 => { - if (!(flag != 0) as bool) { + if !(flag != 0) { r = 50; break; }; diff --git a/tests/unit/out/unsafe/vector.rs b/tests/unit/out/unsafe/vector.rs index f030034..2ac7bed 100644 --- a/tests/unit/out/unsafe/vector.rs +++ b/tests/unit/out/unsafe/vector.rs @@ -17,7 +17,7 @@ unsafe fn main_0() -> i32 { assert!(((v1.len() as u64) == (0_u64))); assert!(v1.is_empty()); v1.push(1); - assert!((!(v1.is_empty()) as bool)); + assert!(!(v1.is_empty())); v1.pop(); assert!(v1.is_empty()); let mut s1: u64 = v1.len() as u64; From c28fb2d233b5e623601d9f15f1e99dc233d9578e Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 19:05:09 +0100 Subject: [PATCH 17/23] Remove extra paren --- cpp2rust/converter/converter.cpp | 5 +---- tests/unit/out/refcount/bool_condition_ptr.rs | 8 ++++---- tests/unit/out/refcount/bool_condition_ptr_c.rs | 8 ++++---- tests/unit/out/refcount/fn_ptr_as_condition.rs | 2 +- tests/unit/out/refcount/vector.rs | 2 +- tests/unit/out/unsafe/bool_condition_enum.rs | 2 +- tests/unit/out/unsafe/bool_condition_enum_c.rs | 2 +- tests/unit/out/unsafe/bool_condition_ptr.rs | 10 +++++----- tests/unit/out/unsafe/bool_condition_ptr_c.rs | 10 +++++----- tests/unit/out/unsafe/fn_ptr_as_condition.rs | 2 +- tests/unit/out/unsafe/polymorphism.rs | 2 +- tests/unit/out/unsafe/vector.rs | 2 +- 12 files changed, 26 insertions(+), 29 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 12a9966..372ce1a 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -2153,10 +2153,7 @@ bool Converter::VisitUnaryOperator(clang::UnaryOperator *expr) { expr->getType()->isIntegerType() && !expr->getType()->isBooleanType(); PushParen paren_cast(*this, needs_int_cast); StrCat(token::kNot); - { - PushParen paren(*this); - ConvertCondition(sub_expr); - } + ConvertCondition(sub_expr); if (needs_int_cast) { ConvertCast(expr->getType()); } diff --git a/tests/unit/out/refcount/bool_condition_ptr.rs b/tests/unit/out/refcount/bool_condition_ptr.rs index c600434..87545fd 100644 --- a/tests/unit/out/refcount/bool_condition_ptr.rs +++ b/tests/unit/out/refcount/bool_condition_ptr.rs @@ -16,13 +16,13 @@ fn main_0() -> i32 { if !(*p.borrow()).is_null() { assert!(true); } - if !(!(*p.borrow()).is_null()) { + if !!(*p.borrow()).is_null() { assert!(false); } if !(*np.borrow()).is_null() { assert!(false); } - if !(!(*np.borrow()).is_null()) { + if !!(*np.borrow()).is_null() { assert!(true); } let iter: Value> = Rc::new(RefCell::new((*p.borrow()).clone())); @@ -36,9 +36,9 @@ fn main_0() -> i32 { assert!(((*t3.borrow()) == 1)); let t4: Value = Rc::new(RefCell::new(if !(*np.borrow()).is_null() { 1 } else { 0 })); assert!(((*t4.borrow()) == 0)); - let t5: Value = Rc::new(RefCell::new((!(!(*p.borrow()).is_null()) as i32))); + let t5: Value = Rc::new(RefCell::new((!!(*p.borrow()).is_null() as i32))); assert!(((*t5.borrow()) == 0)); - let t6: Value = Rc::new(RefCell::new((!(!(*np.borrow()).is_null()) as i32))); + let t6: Value = Rc::new(RefCell::new((!!(*np.borrow()).is_null() as i32))); assert!(((*t6.borrow()) == 1)); let b2: Value = Rc::new(RefCell::new((!(*p.borrow()).is_null()).clone())); let b3: Value = Rc::new(RefCell::new((!(*np.borrow()).is_null()).clone())); diff --git a/tests/unit/out/refcount/bool_condition_ptr_c.rs b/tests/unit/out/refcount/bool_condition_ptr_c.rs index bff9299..68f93d2 100644 --- a/tests/unit/out/refcount/bool_condition_ptr_c.rs +++ b/tests/unit/out/refcount/bool_condition_ptr_c.rs @@ -16,13 +16,13 @@ fn main_0() -> i32 { if !(*p.borrow()).is_null() { assert!((1 != 0)); } - if !(!(*p.borrow()).is_null()) { + if !!(*p.borrow()).is_null() { assert!((0 != 0)); } if !(*np.borrow()).is_null() { assert!((0 != 0)); } - if !(!(*np.borrow()).is_null()) { + if !!(*np.borrow()).is_null() { assert!((1 != 0)); } let iter: Value> = Rc::new(RefCell::new((*p.borrow()).clone())); @@ -36,9 +36,9 @@ fn main_0() -> i32 { assert!(((*t3.borrow()) == 1)); let t4: Value = Rc::new(RefCell::new(if !(*np.borrow()).is_null() { 1 } else { 0 })); assert!(((*t4.borrow()) == 0)); - let t5: Value = Rc::new(RefCell::new((!(!(*p.borrow()).is_null()) as i32))); + let t5: Value = Rc::new(RefCell::new((!!(*p.borrow()).is_null() as i32))); assert!(((*t5.borrow()) == 0)); - let t6: Value = Rc::new(RefCell::new((!(!(*np.borrow()).is_null()) as i32))); + let t6: Value = Rc::new(RefCell::new((!!(*np.borrow()).is_null() as i32))); assert!(((*t6.borrow()) == 1)); let b2: Value = Rc::new(RefCell::new((!(*p.borrow()).is_null()).clone())); let b3: Value = Rc::new(RefCell::new((!(*np.borrow()).is_null()).clone())); diff --git a/tests/unit/out/refcount/fn_ptr_as_condition.rs b/tests/unit/out/refcount/fn_ptr_as_condition.rs index d6a4e12..d629dfb 100644 --- a/tests/unit/out/refcount/fn_ptr_as_condition.rs +++ b/tests/unit/out/refcount/fn_ptr_as_condition.rs @@ -43,7 +43,7 @@ fn main_0() -> i32 { }); assert!(((*b.borrow()) == 5)); let fn_: Value)>> = Rc::new(RefCell::new(FnPtr::null())); - if !(!(*fn_.borrow()).is_null()) { + if !!(*fn_.borrow()).is_null() { (*fn_.borrow_mut()) = FnPtr::)>::new(double_it_0); } let c: Value = Rc::new(RefCell::new(3)); diff --git a/tests/unit/out/refcount/vector.rs b/tests/unit/out/refcount/vector.rs index 6f3ad77..76d493f 100644 --- a/tests/unit/out/refcount/vector.rs +++ b/tests/unit/out/refcount/vector.rs @@ -17,7 +17,7 @@ fn main_0() -> i32 { assert!(((*v1.borrow()).len() as u64 == 0_u64)); assert!((*v1.borrow()).is_empty()); (*v1.borrow_mut()).push(1); - assert!(!((*v1.borrow()).is_empty())); + assert!(!(*v1.borrow()).is_empty()); (*v1.borrow_mut()).pop(); assert!((*v1.borrow()).is_empty()); let s1: Value = Rc::new(RefCell::new((*v1.borrow()).len() as u64)); diff --git a/tests/unit/out/unsafe/bool_condition_enum.rs b/tests/unit/out/unsafe/bool_condition_enum.rs index 2127444..da7dae3 100644 --- a/tests/unit/out/unsafe/bool_condition_enum.rs +++ b/tests/unit/out/unsafe/bool_condition_enum.rs @@ -46,6 +46,6 @@ unsafe fn main_0() -> i32 { let mut t9: i32 = (!(code != Code::from(0)) as i32); assert!(((t9) == (1))); let mut b4: bool = (code != Code::from(0)); - assert!(!(b4)); + assert!(!b4); return 0; } diff --git a/tests/unit/out/unsafe/bool_condition_enum_c.rs b/tests/unit/out/unsafe/bool_condition_enum_c.rs index 9cebcb9..3f6a45e 100644 --- a/tests/unit/out/unsafe/bool_condition_enum_c.rs +++ b/tests/unit/out/unsafe/bool_condition_enum_c.rs @@ -46,6 +46,6 @@ unsafe fn main_0() -> i32 { let mut t9: i32 = (!(code != Code::from(0)) as i32); assert!(((t9) == (1))); let mut b4: bool = (code != Code::from(0)); - assert!(((!(b4) as i32) != 0)); + assert!(((!b4 as i32) != 0)); return 0; } diff --git a/tests/unit/out/unsafe/bool_condition_ptr.rs b/tests/unit/out/unsafe/bool_condition_ptr.rs index 0931063..35aa449 100644 --- a/tests/unit/out/unsafe/bool_condition_ptr.rs +++ b/tests/unit/out/unsafe/bool_condition_ptr.rs @@ -18,13 +18,13 @@ unsafe fn main_0() -> i32 { if !(p).is_null() { assert!(true); } - if !(!(p).is_null()) { + if !!(p).is_null() { assert!(false); } if !(np).is_null() { assert!(false); } - if !(!(np).is_null()) { + if !!(np).is_null() { assert!(true); } let mut iter: *mut i32 = p; @@ -38,13 +38,13 @@ unsafe fn main_0() -> i32 { assert!(((t3) == (1))); let mut t4: i32 = if !(np).is_null() { 1 } else { 0 }; assert!(((t4) == (0))); - let mut t5: i32 = (!(!(p).is_null()) as i32); + let mut t5: i32 = (!!(p).is_null() as i32); assert!(((t5) == (0))); - let mut t6: i32 = (!(!(np).is_null()) as i32); + let mut t6: i32 = (!!(np).is_null() as i32); assert!(((t6) == (1))); let mut b2: bool = !(p).is_null(); let mut b3: bool = !(np).is_null(); assert!(b2); - assert!(!(b3)); + assert!(!b3); return 0; } diff --git a/tests/unit/out/unsafe/bool_condition_ptr_c.rs b/tests/unit/out/unsafe/bool_condition_ptr_c.rs index 622279b..efd0659 100644 --- a/tests/unit/out/unsafe/bool_condition_ptr_c.rs +++ b/tests/unit/out/unsafe/bool_condition_ptr_c.rs @@ -18,13 +18,13 @@ unsafe fn main_0() -> i32 { if !(p).is_null() { assert!((1 != 0)); } - if !(!(p).is_null()) { + if !!(p).is_null() { assert!((0 != 0)); } if !(np).is_null() { assert!((0 != 0)); } - if !(!(np).is_null()) { + if !!(np).is_null() { assert!((1 != 0)); } let mut iter: *mut i32 = p; @@ -38,13 +38,13 @@ unsafe fn main_0() -> i32 { assert!(((t3) == (1))); let mut t4: i32 = if !(np).is_null() { 1 } else { 0 }; assert!(((t4) == (0))); - let mut t5: i32 = (!(!(p).is_null()) as i32); + let mut t5: i32 = (!!(p).is_null() as i32); assert!(((t5) == (0))); - let mut t6: i32 = (!(!(np).is_null()) as i32); + let mut t6: i32 = (!!(np).is_null() as i32); assert!(((t6) == (1))); let mut b2: bool = !(p).is_null(); let mut b3: bool = !(np).is_null(); assert!(b2); - assert!(((!(b3) as i32) != 0)); + assert!(((!b3 as i32) != 0)); return 0; } diff --git a/tests/unit/out/unsafe/fn_ptr_as_condition.rs b/tests/unit/out/unsafe/fn_ptr_as_condition.rs index 88c1e5c..d4b8a92 100644 --- a/tests/unit/out/unsafe/fn_ptr_as_condition.rs +++ b/tests/unit/out/unsafe/fn_ptr_as_condition.rs @@ -38,7 +38,7 @@ unsafe fn main_0() -> i32 { }); assert!(((b) == (5))); let mut fn_: Option = None; - if !(!(fn_).is_none()) { + if !!(fn_).is_none() { fn_ = Some(double_it_0); } let mut c: i32 = 3; diff --git a/tests/unit/out/unsafe/polymorphism.rs b/tests/unit/out/unsafe/polymorphism.rs index fe5c8e9..2f98f68 100644 --- a/tests/unit/out/unsafe/polymorphism.rs +++ b/tests/unit/out/unsafe/polymorphism.rs @@ -42,5 +42,5 @@ unsafe fn main_0() -> i32 { let mut cat: Cat = ::default(); animal = (&mut cat as *mut Cat); let mut eat2: bool = (unsafe { (*animal.cast_const()).bark() }); - return (((eat1) && (!(eat2))) as i32); + return (((eat1) && (!eat2)) as i32); } diff --git a/tests/unit/out/unsafe/vector.rs b/tests/unit/out/unsafe/vector.rs index 2ac7bed..fb44d82 100644 --- a/tests/unit/out/unsafe/vector.rs +++ b/tests/unit/out/unsafe/vector.rs @@ -17,7 +17,7 @@ unsafe fn main_0() -> i32 { assert!(((v1.len() as u64) == (0_u64))); assert!(v1.is_empty()); v1.push(1); - assert!(!(v1.is_empty())); + assert!(!v1.is_empty()); v1.pop(); assert!(v1.is_empty()); let mut s1: u64 = v1.len() as u64; From 20f0e00e3a32ef1faa17492132c2008c63307cc3 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 20:33:24 +0100 Subject: [PATCH 18/23] Expand bool_condition_logical test --- tests/unit/bool_condition_logical.cpp | 32 +++++++++++++++++++++++++++ tests/unit/bool_condition_logical_c.c | 32 +++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/tests/unit/bool_condition_logical.cpp b/tests/unit/bool_condition_logical.cpp index 16085e7..d88e3a3 100644 --- a/tests/unit/bool_condition_logical.cpp +++ b/tests/unit/bool_condition_logical.cpp @@ -45,5 +45,37 @@ int main() { } assert(side_effect == 0); + int chunk_count = 5; + int max_chunks = 3; + unsigned opts = 0x2u; + if ((chunk_count > max_chunks) || (opts & 0x1u)) { + assert(true); + } + if ((chunk_count < max_chunks) || (opts & 0x1u)) { + assert(false); + } + + unsigned a_id = 1u; + unsigned b_id = 2u; + unsigned other_id = 3u; + if (((a_id != other_id)) && ((b_id != other_id))) { + assert(true); + } + + int reply_ms = -1; + if ((p != nullptr) && (reply_ms < 0)) { + assert(true); + } + + unsigned baller_count = 2u; + bool ballers_complete = false; + if ((baller_count > 1u) || !ballers_complete) { + assert(true); + } + + if (((chunk_count > max_chunks)) || ((opts & 0x4u))) { + assert(true); + } + return 0; } diff --git a/tests/unit/bool_condition_logical_c.c b/tests/unit/bool_condition_logical_c.c index d05ea0b..794ecdf 100644 --- a/tests/unit/bool_condition_logical_c.c +++ b/tests/unit/bool_condition_logical_c.c @@ -46,5 +46,37 @@ int main() { } assert(side_effect == 0); + int chunk_count = 5; + int max_chunks = 3; + unsigned opts = 0x2u; + if ((chunk_count > max_chunks) || (opts & 0x1u)) { + assert(true); + } + if ((chunk_count < max_chunks) || (opts & 0x1u)) { + assert(false); + } + + unsigned a_id = 1u; + unsigned b_id = 2u; + unsigned other_id = 3u; + if (((a_id != other_id)) && ((b_id != other_id))) { + assert(true); + } + + int reply_ms = -1; + if ((p != NULL) && (reply_ms < 0)) { + assert(true); + } + + unsigned baller_count = 2u; + bool ballers_complete = false; + if ((baller_count > 1u) || !ballers_complete) { + assert(true); + } + + if (((chunk_count > max_chunks)) || ((opts & 0x4u))) { + assert(true); + } + return 0; } From e84db5a944e83beeb97afcb1ae922424897deb69 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 20:33:05 +0100 Subject: [PATCH 19/23] Transate NULL in C --- cpp2rust/converter/models/converter_refcount.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index b9fbb0e..9b3c310 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1047,9 +1047,12 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { } } - if (expr->getCastKind() == clang::CastKind::CK_NullToPointer && - expr->getType()->isFunctionPointerType()) { - StrCat("FnPtr::null()"); + if (expr->getCastKind() == clang::CastKind::CK_NullToPointer) { + if (expr->getType()->isFunctionPointerType()) { + StrCat("FnPtr::null()"); + } else { + StrCat("Default::default()"); + } computed_expr_type_ = ComputedExprType::FreshPointer; return false; } @@ -1138,6 +1141,11 @@ bool ConverterRefCount::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) { } return false; } + if (expr->getCastKind() == clang::CK_NullToPointer) { + StrCat("Default::default()"); + computed_expr_type_ = ComputedExprType::FreshPointer; + return false; + } switch (expr->getStmtClass()) { case clang::Stmt::CXXReinterpretCastExprClass: assert(expr->getType()->isPointerType() && From 0584d109fb73c0d243c93dd64efdbf9c288f9d00 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 20:32:56 +0100 Subject: [PATCH 20/23] Delete extra int cast in VisitParen --- cpp2rust/converter/converter.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 372ce1a..17c1075 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -2320,21 +2320,11 @@ bool Converter::VisitParenExpr(clang::ParenExpr *expr) { } } - // Add cast to avoid ambigous integers. Don't add cast if sub expression is a - // pointer dereference because we might want to mutate the dereferenced value. - bool should_add_integral_cast = - expr->getType()->isIntegralOrEnumerationType() && !isAddrOf() && - !isVoid() && !clang::isa(expr->getSubExpr()); - PushParen outer(*this, should_add_integral_cast); - { PushParen inner(*this); Convert(expr->getSubExpr()); } - if (should_add_integral_cast) { - ConvertCast(expr->getType()); - } return false; } From 14bc5c3d17cfaabcc65a78d7be8d5db02b085974 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 2 May 2026 20:35:31 +0100 Subject: [PATCH 21/23] Update tests --- .../out/refcount/bool_condition_logical.rs | 30 +++++++++++++++++++ .../out/refcount/bool_condition_logical_c.rs | 27 +++++++++++++++++ .../unit/out/unsafe/bool_condition_logical.rs | 27 +++++++++++++++++ .../out/unsafe/bool_condition_logical_c.rs | 27 +++++++++++++++++ 4 files changed, 111 insertions(+) diff --git a/tests/unit/out/refcount/bool_condition_logical.rs b/tests/unit/out/refcount/bool_condition_logical.rs index de803dd..9810312 100644 --- a/tests/unit/out/refcount/bool_condition_logical.rs +++ b/tests/unit/out/refcount/bool_condition_logical.rs @@ -94,5 +94,35 @@ fn main_0() -> i32 { assert!(true); } assert!(((*side_effect.with(Value::clone).borrow()) == 0)); + let chunk_count: Value = Rc::new(RefCell::new(5)); + let max_chunks: Value = Rc::new(RefCell::new(3)); + let opts: Value = Rc::new(RefCell::new(2_u32)); + if (((*chunk_count.borrow()) > (*max_chunks.borrow())) || (((*opts.borrow()) & 1_u32) != 0)) { + assert!(true); + } + if (((*chunk_count.borrow()) < (*max_chunks.borrow())) || (((*opts.borrow()) & 1_u32) != 0)) { + assert!(false); + } + let a_id: Value = Rc::new(RefCell::new(1_u32)); + let b_id: Value = Rc::new(RefCell::new(2_u32)); + let other_id: Value = Rc::new(RefCell::new(3_u32)); + if (((*a_id.borrow()) != (*other_id.borrow())) && ((*b_id.borrow()) != (*other_id.borrow()))) { + assert!(true); + } + let reply_ms: Value = Rc::new(RefCell::new(-1_i32)); + if { + let _lhs = (!((*p.borrow()).is_null())).clone(); + _lhs && ((*reply_ms.borrow()) < 0) + } { + assert!(true); + } + let baller_count: Value = Rc::new(RefCell::new(2_u32)); + let ballers_complete: Value = Rc::new(RefCell::new(false)); + if (((*baller_count.borrow()) > 1_u32) || !(*ballers_complete.borrow())) { + assert!(true); + } + if (((*chunk_count.borrow()) > (*max_chunks.borrow())) || (((*opts.borrow()) & 4_u32) != 0)) { + assert!(true); + } return 0; } diff --git a/tests/unit/out/refcount/bool_condition_logical_c.rs b/tests/unit/out/refcount/bool_condition_logical_c.rs index f775cd4..a500037 100644 --- a/tests/unit/out/refcount/bool_condition_logical_c.rs +++ b/tests/unit/out/refcount/bool_condition_logical_c.rs @@ -78,5 +78,32 @@ fn main_0() -> i32 { assert!((1 != 0)); } assert!(((*side_effect.with(Value::clone).borrow()) == 0)); + let chunk_count: Value = Rc::new(RefCell::new(5)); + let max_chunks: Value = Rc::new(RefCell::new(3)); + let opts: Value = Rc::new(RefCell::new(2_u32)); + if ((*chunk_count.borrow()) > (*max_chunks.borrow())) || (((*opts.borrow()) & 1_u32) != 0) { + assert!((1 != 0)); + } + if ((*chunk_count.borrow()) < (*max_chunks.borrow())) || (((*opts.borrow()) & 1_u32) != 0) { + assert!((0 != 0)); + } + let a_id: Value = Rc::new(RefCell::new(1_u32)); + let b_id: Value = Rc::new(RefCell::new(2_u32)); + let other_id: Value = Rc::new(RefCell::new(3_u32)); + if ((*a_id.borrow()) != (*other_id.borrow())) && ((*b_id.borrow()) != (*other_id.borrow())) { + assert!((1 != 0)); + } + let reply_ms: Value = Rc::new(RefCell::new(-1_i32)); + if ((*p.borrow()) != (Default::default())) && ((*reply_ms.borrow()) < 0) { + assert!((1 != 0)); + } + let baller_count: Value = Rc::new(RefCell::new(2_u32)); + let ballers_complete: Value = Rc::new(RefCell::new((0 != 0))); + if ((*baller_count.borrow()) > 1_u32) || (!(*ballers_complete.borrow())) { + assert!((1 != 0)); + } + if ((*chunk_count.borrow()) > (*max_chunks.borrow())) || (((*opts.borrow()) & 4_u32) != 0) { + assert!((1 != 0)); + } return 0; } diff --git a/tests/unit/out/unsafe/bool_condition_logical.rs b/tests/unit/out/unsafe/bool_condition_logical.rs index 33cfda6..713496a 100644 --- a/tests/unit/out/unsafe/bool_condition_logical.rs +++ b/tests/unit/out/unsafe/bool_condition_logical.rs @@ -75,5 +75,32 @@ unsafe fn main_0() -> i32 { assert!(true); } assert!(((side_effect) == (0))); + let mut chunk_count: i32 = 5; + let mut max_chunks: i32 = 3; + let mut opts: u32 = 2_u32; + if (((chunk_count) > (max_chunks)) || (((opts) & (1_u32)) != 0)) { + assert!(true); + } + if (((chunk_count) < (max_chunks)) || (((opts) & (1_u32)) != 0)) { + assert!(false); + } + let mut a_id: u32 = 1_u32; + let mut b_id: u32 = 2_u32; + let mut other_id: u32 = 3_u32; + if (((a_id) != (other_id)) && ((b_id) != (other_id))) { + assert!(true); + } + let mut reply_ms: i32 = -1_i32; + if ((!((p).is_null())) && ((reply_ms) < (0))) { + assert!(true); + } + let mut baller_count: u32 = 2_u32; + let mut ballers_complete: bool = false; + if (((baller_count) > (1_u32)) || (!ballers_complete)) { + assert!(true); + } + if (((chunk_count) > (max_chunks)) || (((opts) & (4_u32)) != 0)) { + assert!(true); + } return 0; } diff --git a/tests/unit/out/unsafe/bool_condition_logical_c.rs b/tests/unit/out/unsafe/bool_condition_logical_c.rs index 3fab7b5..6d9b346 100644 --- a/tests/unit/out/unsafe/bool_condition_logical_c.rs +++ b/tests/unit/out/unsafe/bool_condition_logical_c.rs @@ -77,5 +77,32 @@ unsafe fn main_0() -> i32 { assert!((1 != 0)); } assert!(((side_effect) == (0))); + let mut chunk_count: i32 = 5; + let mut max_chunks: i32 = 3; + let mut opts: u32 = 2_u32; + if ((chunk_count) > (max_chunks)) || (((opts) & (1_u32)) != 0) { + assert!((1 != 0)); + } + if ((chunk_count) < (max_chunks)) || (((opts) & (1_u32)) != 0) { + assert!((0 != 0)); + } + let mut a_id: u32 = 1_u32; + let mut b_id: u32 = 2_u32; + let mut other_id: u32 = 3_u32; + if ((a_id) != (other_id)) && ((b_id) != (other_id)) { + assert!((1 != 0)); + } + let mut reply_ms: i32 = -1_i32; + if ((p) != ((0 as *mut ::libc::c_void) as *mut i32)) && ((reply_ms) < (0)) { + assert!((1 != 0)); + } + let mut baller_count: u32 = 2_u32; + let mut ballers_complete: bool = (0 != 0); + if ((baller_count) > (1_u32)) || (!ballers_complete) { + assert!((1 != 0)); + } + if ((chunk_count) > (max_chunks)) || (((opts) & (4_u32)) != 0) { + assert!((1 != 0)); + } return 0; } From 67b6f49e512707622ca71013f659bd3da844c919 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sun, 3 May 2026 09:56:38 +0100 Subject: [PATCH 22/23] Update tests --- tests/ub/out/refcount/ub4.rs | 5 ++-- tests/ub/out/unsafe/ub4.rs | 6 +--- tests/unit/bool_condition_logical.cpp | 30 +++++++++---------- tests/unit/bool_condition_logical_c.c | 30 +++++++++---------- .../out/refcount/bool_condition_logical.rs | 30 +++++++++---------- .../out/refcount/bool_condition_logical_c.rs | 30 +++++++++---------- tests/unit/out/refcount/continue.rs | 4 +-- tests/unit/out/refcount/enum_int_interop.rs | 4 +-- tests/unit/out/refcount/enum_int_interop_c.rs | 2 +- tests/unit/out/refcount/expr_as_bool_c.rs | 15 ++++------ tests/unit/out/refcount/expr_as_bool_cpp.rs | 15 ++++------ tests/unit/out/refcount/fft.rs | 19 +++++------- tests/unit/out/refcount/huffman.rs | 8 ++--- tests/unit/out/refcount/linked_list.rs | 24 +++++++-------- tests/unit/out/refcount/main.rs | 2 +- tests/unit/out/refcount/map-reallocation.rs | 2 +- tests/unit/out/refcount/operator_less_than.rs | 4 +-- .../out/refcount/reinterpret_cast_iterate.rs | 2 +- tests/unit/out/refcount/string_escape.rs | 4 +-- .../refcount/switch_continue_inside_switch.rs | 2 +- tests/unit/out/refcount/types.rs | 2 +- tests/unit/out/refcount/va_arg_concat.rs | 5 ++-- tests/unit/out/refcount/va_arg_two_passes.rs | 10 +++---- .../unit/out/unsafe/bool_condition_logical.rs | 30 +++++++++---------- .../out/unsafe/bool_condition_logical_c.rs | 30 +++++++++---------- tests/unit/out/unsafe/continue.rs | 4 +-- tests/unit/out/unsafe/enum_int_interop.rs | 2 +- tests/unit/out/unsafe/enum_int_interop_c.rs | 2 +- tests/unit/out/unsafe/expr_as_bool_c.rs | 15 ++++------ tests/unit/out/unsafe/expr_as_bool_cpp.rs | 15 ++++------ tests/unit/out/unsafe/fft.rs | 17 +++++------ tests/unit/out/unsafe/huffman.rs | 9 +++--- tests/unit/out/unsafe/linked_list.rs | 22 +++++++------- tests/unit/out/unsafe/main.rs | 2 +- tests/unit/out/unsafe/map-reallocation.rs | 2 +- tests/unit/out/unsafe/operator_less_than.rs | 2 +- .../out/unsafe/reinterpret_cast_iterate.rs | 2 +- tests/unit/out/unsafe/string_escape.rs | 4 +-- tests/unit/out/unsafe/swap.rs | 2 +- .../unsafe/switch_continue_inside_switch.rs | 2 +- tests/unit/out/unsafe/types.rs | 2 +- tests/unit/out/unsafe/va_arg_concat.rs | 5 ++-- tests/unit/out/unsafe/va_arg_two_passes.rs | 10 +++---- 43 files changed, 202 insertions(+), 232 deletions(-) diff --git a/tests/ub/out/refcount/ub4.rs b/tests/ub/out/refcount/ub4.rs index 8864310..58bb8f6 100644 --- a/tests/ub/out/refcount/ub4.rs +++ b/tests/ub/out/refcount/ub4.rs @@ -7,11 +7,10 @@ use std::io::{Read, Seek, Write}; use std::os::fd::AsFd; use std::rc::{Rc, Weak}; pub fn smaller_0(x1: Ptr, x2: Ptr) -> Ptr { - return if (({ + return if ({ let _lhs = (x1.read()); _lhs < (x2.read()) - }) as bool) - { + }) { (x1).clone() } else { (x2).clone() diff --git a/tests/ub/out/unsafe/ub4.rs b/tests/ub/out/unsafe/ub4.rs index 9d642ab..4e49a9a 100644 --- a/tests/ub/out/unsafe/ub4.rs +++ b/tests/ub/out/unsafe/ub4.rs @@ -7,11 +7,7 @@ use std::io::{Read, Seek, Write}; use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; pub unsafe fn smaller_0(x1: *mut i32, x2: *mut i32) -> *mut i32 { - return if (((*x1) < (*x2)) as bool) { - (x1) - } else { - (x2) - }; + return if ((*x1) < (*x2)) { (x1) } else { (x2) }; } pub fn main() { unsafe { diff --git a/tests/unit/bool_condition_logical.cpp b/tests/unit/bool_condition_logical.cpp index d88e3a3..eff2ae5 100644 --- a/tests/unit/bool_condition_logical.cpp +++ b/tests/unit/bool_condition_logical.cpp @@ -45,35 +45,35 @@ int main() { } assert(side_effect == 0); - int chunk_count = 5; - int max_chunks = 3; - unsigned opts = 0x2u; - if ((chunk_count > max_chunks) || (opts & 0x1u)) { + int x = 5; + int y = 3; + unsigned flags = 0x2u; + if ((x > y) || (flags & 0x1u)) { assert(true); } - if ((chunk_count < max_chunks) || (opts & 0x1u)) { + if ((x < y) || (flags & 0x1u)) { assert(false); } - unsigned a_id = 1u; - unsigned b_id = 2u; - unsigned other_id = 3u; - if (((a_id != other_id)) && ((b_id != other_id))) { + unsigned a = 1u; + unsigned b = 2u; + unsigned c = 3u; + if (((a != c)) && ((b != c))) { assert(true); } - int reply_ms = -1; - if ((p != nullptr) && (reply_ms < 0)) { + int s = -1; + if ((p != nullptr) && (s < 0)) { assert(true); } - unsigned baller_count = 2u; - bool ballers_complete = false; - if ((baller_count > 1u) || !ballers_complete) { + unsigned k = 2u; + bool done = false; + if ((k > 1u) || !done) { assert(true); } - if (((chunk_count > max_chunks)) || ((opts & 0x4u))) { + if (((x > y)) || ((flags & 0x4u))) { assert(true); } diff --git a/tests/unit/bool_condition_logical_c.c b/tests/unit/bool_condition_logical_c.c index 794ecdf..c7870f3 100644 --- a/tests/unit/bool_condition_logical_c.c +++ b/tests/unit/bool_condition_logical_c.c @@ -46,35 +46,35 @@ int main() { } assert(side_effect == 0); - int chunk_count = 5; - int max_chunks = 3; - unsigned opts = 0x2u; - if ((chunk_count > max_chunks) || (opts & 0x1u)) { + int x = 5; + int y = 3; + unsigned flags = 0x2u; + if ((x > y) || (flags & 0x1u)) { assert(true); } - if ((chunk_count < max_chunks) || (opts & 0x1u)) { + if ((x < y) || (flags & 0x1u)) { assert(false); } - unsigned a_id = 1u; - unsigned b_id = 2u; - unsigned other_id = 3u; - if (((a_id != other_id)) && ((b_id != other_id))) { + unsigned a = 1u; + unsigned b = 2u; + unsigned c = 3u; + if (((a != c)) && ((b != c))) { assert(true); } - int reply_ms = -1; - if ((p != NULL) && (reply_ms < 0)) { + int s = -1; + if ((p != NULL) && (s < 0)) { assert(true); } - unsigned baller_count = 2u; - bool ballers_complete = false; - if ((baller_count > 1u) || !ballers_complete) { + unsigned k = 2u; + bool done = false; + if ((k > 1u) || !done) { assert(true); } - if (((chunk_count > max_chunks)) || ((opts & 0x4u))) { + if (((x > y)) || ((flags & 0x4u))) { assert(true); } diff --git a/tests/unit/out/refcount/bool_condition_logical.rs b/tests/unit/out/refcount/bool_condition_logical.rs index 9810312..a25a429 100644 --- a/tests/unit/out/refcount/bool_condition_logical.rs +++ b/tests/unit/out/refcount/bool_condition_logical.rs @@ -94,34 +94,34 @@ fn main_0() -> i32 { assert!(true); } assert!(((*side_effect.with(Value::clone).borrow()) == 0)); - let chunk_count: Value = Rc::new(RefCell::new(5)); - let max_chunks: Value = Rc::new(RefCell::new(3)); - let opts: Value = Rc::new(RefCell::new(2_u32)); - if (((*chunk_count.borrow()) > (*max_chunks.borrow())) || (((*opts.borrow()) & 1_u32) != 0)) { + let x: Value = Rc::new(RefCell::new(5)); + let y: Value = Rc::new(RefCell::new(3)); + let flags: Value = Rc::new(RefCell::new(2_u32)); + if (((*x.borrow()) > (*y.borrow())) || (((*flags.borrow()) & 1_u32) != 0)) { assert!(true); } - if (((*chunk_count.borrow()) < (*max_chunks.borrow())) || (((*opts.borrow()) & 1_u32) != 0)) { + if (((*x.borrow()) < (*y.borrow())) || (((*flags.borrow()) & 1_u32) != 0)) { assert!(false); } - let a_id: Value = Rc::new(RefCell::new(1_u32)); - let b_id: Value = Rc::new(RefCell::new(2_u32)); - let other_id: Value = Rc::new(RefCell::new(3_u32)); - if (((*a_id.borrow()) != (*other_id.borrow())) && ((*b_id.borrow()) != (*other_id.borrow()))) { + let a: Value = Rc::new(RefCell::new(1_u32)); + let b: Value = Rc::new(RefCell::new(2_u32)); + let c: Value = Rc::new(RefCell::new(3_u32)); + if (((*a.borrow()) != (*c.borrow())) && ((*b.borrow()) != (*c.borrow()))) { assert!(true); } - let reply_ms: Value = Rc::new(RefCell::new(-1_i32)); + let s: Value = Rc::new(RefCell::new(-1_i32)); if { let _lhs = (!((*p.borrow()).is_null())).clone(); - _lhs && ((*reply_ms.borrow()) < 0) + _lhs && ((*s.borrow()) < 0) } { assert!(true); } - let baller_count: Value = Rc::new(RefCell::new(2_u32)); - let ballers_complete: Value = Rc::new(RefCell::new(false)); - if (((*baller_count.borrow()) > 1_u32) || !(*ballers_complete.borrow())) { + let k: Value = Rc::new(RefCell::new(2_u32)); + let done: Value = Rc::new(RefCell::new(false)); + if (((*k.borrow()) > 1_u32) || !(*done.borrow())) { assert!(true); } - if (((*chunk_count.borrow()) > (*max_chunks.borrow())) || (((*opts.borrow()) & 4_u32) != 0)) { + if (((*x.borrow()) > (*y.borrow())) || (((*flags.borrow()) & 4_u32) != 0)) { assert!(true); } return 0; diff --git a/tests/unit/out/refcount/bool_condition_logical_c.rs b/tests/unit/out/refcount/bool_condition_logical_c.rs index a500037..fcf9535 100644 --- a/tests/unit/out/refcount/bool_condition_logical_c.rs +++ b/tests/unit/out/refcount/bool_condition_logical_c.rs @@ -78,31 +78,31 @@ fn main_0() -> i32 { assert!((1 != 0)); } assert!(((*side_effect.with(Value::clone).borrow()) == 0)); - let chunk_count: Value = Rc::new(RefCell::new(5)); - let max_chunks: Value = Rc::new(RefCell::new(3)); - let opts: Value = Rc::new(RefCell::new(2_u32)); - if ((*chunk_count.borrow()) > (*max_chunks.borrow())) || (((*opts.borrow()) & 1_u32) != 0) { + let x: Value = Rc::new(RefCell::new(5)); + let y: Value = Rc::new(RefCell::new(3)); + let flags: Value = Rc::new(RefCell::new(2_u32)); + if ((*x.borrow()) > (*y.borrow())) || (((*flags.borrow()) & 1_u32) != 0) { assert!((1 != 0)); } - if ((*chunk_count.borrow()) < (*max_chunks.borrow())) || (((*opts.borrow()) & 1_u32) != 0) { + if ((*x.borrow()) < (*y.borrow())) || (((*flags.borrow()) & 1_u32) != 0) { assert!((0 != 0)); } - let a_id: Value = Rc::new(RefCell::new(1_u32)); - let b_id: Value = Rc::new(RefCell::new(2_u32)); - let other_id: Value = Rc::new(RefCell::new(3_u32)); - if ((*a_id.borrow()) != (*other_id.borrow())) && ((*b_id.borrow()) != (*other_id.borrow())) { + let a: Value = Rc::new(RefCell::new(1_u32)); + let b: Value = Rc::new(RefCell::new(2_u32)); + let c: Value = Rc::new(RefCell::new(3_u32)); + if ((*a.borrow()) != (*c.borrow())) && ((*b.borrow()) != (*c.borrow())) { assert!((1 != 0)); } - let reply_ms: Value = Rc::new(RefCell::new(-1_i32)); - if ((*p.borrow()) != (Default::default())) && ((*reply_ms.borrow()) < 0) { + let s: Value = Rc::new(RefCell::new(-1_i32)); + if ((*p.borrow()) != (Default::default())) && ((*s.borrow()) < 0) { assert!((1 != 0)); } - let baller_count: Value = Rc::new(RefCell::new(2_u32)); - let ballers_complete: Value = Rc::new(RefCell::new((0 != 0))); - if ((*baller_count.borrow()) > 1_u32) || (!(*ballers_complete.borrow())) { + let k: Value = Rc::new(RefCell::new(2_u32)); + let done: Value = Rc::new(RefCell::new((0 != 0))); + if ((*k.borrow()) > 1_u32) || (!(*done.borrow())) { assert!((1 != 0)); } - if ((*chunk_count.borrow()) > (*max_chunks.borrow())) || (((*opts.borrow()) & 4_u32) != 0) { + if ((*x.borrow()) > (*y.borrow())) || (((*flags.borrow()) & 4_u32) != 0) { assert!((1 != 0)); } return 0; diff --git a/tests/unit/out/refcount/continue.rs b/tests/unit/out/refcount/continue.rs index 593780e..50c3363 100644 --- a/tests/unit/out/refcount/continue.rs +++ b/tests/unit/out/refcount/continue.rs @@ -35,14 +35,14 @@ fn main_0() -> i32 { 'loop_: while ((*k2.borrow()) < 5) { let k3: Value = Rc::new(RefCell::new(0)); 'loop_: while ((*k3.borrow()) < 5) { - if ((((((*k1.borrow()) + (*k2.borrow())) + (*k3.borrow())) as i32) % 2) == 0) { + if (((((*k1.borrow()) + (*k2.borrow())) + (*k3.borrow())) % 2) == 0) { (*k3.borrow_mut()).postfix_inc(); continue 'loop_; } (*out.borrow_mut()).prefix_inc(); (*k3.borrow_mut()).postfix_inc(); } - if (((((*k1.borrow()) + (*k2.borrow())) as i32) % 2) == 0) { + if ((((*k1.borrow()) + (*k2.borrow())) % 2) == 0) { (*k2.borrow_mut()).postfix_inc(); continue 'loop_; } diff --git a/tests/unit/out/refcount/enum_int_interop.rs b/tests/unit/out/refcount/enum_int_interop.rs index 64e02ed..6ba4c69 100644 --- a/tests/unit/out/refcount/enum_int_interop.rs +++ b/tests/unit/out/refcount/enum_int_interop.rs @@ -131,9 +131,7 @@ fn main_0() -> i32 { make_color_2(_n) }); assert!((((*c.borrow()) as i32) == (Color::GREEN as i32))); - let cmp: Value = Rc::new(RefCell::new(Color::from( - ((((*c.borrow()) as i32) + 1) as i32), - ))); + let cmp: Value = Rc::new(RefCell::new(Color::from((((*c.borrow()) as i32) + 1)))); assert!((((*cmp.borrow()) as i32) == (Color::BLUE as i32))); let o: Value