diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index d54fe2a..cb5c814 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1050,22 +1050,20 @@ bool Converter::VisitWhileStmt(clang::WhileStmt *stmt) { bool Converter::VisitDoStmt(clang::DoStmt *stmt) { PushBreakTarget push(break_target_, BreakTarget::Loop); - StrCat("'loop_:"); - StrCat(keyword::kLoop); + const char *control_var = "__do_while"; + StrCat(keyword::kLet, "mut", control_var, token::kAssign, keyword::kTrue, + token::kSemiColon); + StrCat("'loop_:", keyword::kWhile, control_var, "||"); + { + PushParen paren(*this); + ConvertCondition(stmt->getCond()); + } { PushBrace loop_brace(*this); + StrCat(control_var, token::kAssign, keyword::kFalse, token::kSemiColon); curr_for_inc_.emplace_back(nullptr); Convert(stmt->getBody()); curr_for_inc_.pop_back(); - StrCat(keyword::kIf, token::kNot); - { - PushParen paren(*this); - ConvertCondition(stmt->getCond()); - } - { - PushBrace if_brace(*this); - StrCat(keyword::kBreak, token::kSemiColon); - } } return false; } diff --git a/tests/unit/do_while_continue.c b/tests/unit/do_while_continue.c new file mode 100644 index 0000000..b0e6d84 --- /dev/null +++ b/tests/unit/do_while_continue.c @@ -0,0 +1,37 @@ +#include + +static int run(void) { + int i = 0; + int runs = 0; + do { + runs += 1; + i += 1; + if (i == 4) { + continue; + } + } while (i < 4); + return runs; +} + +static int nested(void) { + int oi = 0; + int runs = 0; + do { + oi += 1; + int ii = 0; + do { + runs += 1; + ii += 1; + if (ii == 3) { + continue; + } + } while (ii < 3); + } while (oi < 2); + return runs; +} + +int main(void) { + assert(run() == 4); + assert(nested() == 6); + return 0; +} diff --git a/tests/unit/out/refcount/do_while_continue.rs b/tests/unit/out/refcount/do_while_continue.rs new file mode 100644 index 0000000..13b7d26 --- /dev/null +++ b/tests/unit/out/refcount/do_while_continue.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 run_0() -> i32 { + let i: Value = Rc::new(RefCell::new(0)); + let runs: Value = Rc::new(RefCell::new(0)); + let mut __do_while = true; + 'loop_: while __do_while || ((((*i.borrow()) < 4) as i32) != 0) { + __do_while = false; + (*runs.borrow_mut()) += 1; + (*i.borrow_mut()) += 1; + if ((((*i.borrow()) == 4) as i32) != 0) { + continue 'loop_; + } + } + return (*runs.borrow()); +} +pub fn nested_1() -> i32 { + let oi: Value = Rc::new(RefCell::new(0)); + let runs: Value = Rc::new(RefCell::new(0)); + let mut __do_while = true; + 'loop_: while __do_while || ((((*oi.borrow()) < 2) as i32) != 0) { + __do_while = false; + (*oi.borrow_mut()) += 1; + let ii: Value = Rc::new(RefCell::new(0)); + let mut __do_while = true; + 'loop_: while __do_while || ((((*ii.borrow()) < 3) as i32) != 0) { + __do_while = false; + (*runs.borrow_mut()) += 1; + (*ii.borrow_mut()) += 1; + if ((((*ii.borrow()) == 3) as i32) != 0) { + continue 'loop_; + } + } + } + return (*runs.borrow()); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + assert!((((({ run_0() }) == 4) as i32) != 0)); + assert!((((({ nested_1() }) == 6) as i32) != 0)); + return 0; +} diff --git a/tests/unit/out/refcount/dowhile.rs b/tests/unit/out/refcount/dowhile.rs index a1379db..9efe9e6 100644 --- a/tests/unit/out/refcount/dowhile.rs +++ b/tests/unit/out/refcount/dowhile.rs @@ -8,19 +8,17 @@ use std::os::fd::AsFd; use std::rc::{Rc, Weak}; pub fn dowhile_0(x: i32) -> i32 { let x: Value = Rc::new(RefCell::new(x)); - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || ((*x.borrow()) <= 200) { + __do_while = false; (*x.borrow_mut()) += 1; - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || ((*x.borrow()) <= 100) { + __do_while = false; (*x.borrow_mut()) += 1; (*x.borrow_mut()) += 1; - if !((*x.borrow()) <= 100) { - break; - } } (*x.borrow_mut()) += 1; - if !((*x.borrow()) <= 200) { - break; - } } return (*x.borrow()); } diff --git a/tests/unit/out/refcount/fn_ptr_stdlib_compare.rs b/tests/unit/out/refcount/fn_ptr_stdlib_compare.rs index e095c17..4121432 100644 --- a/tests/unit/out/refcount/fn_ptr_stdlib_compare.rs +++ b/tests/unit/out/refcount/fn_ptr_stdlib_compare.rs @@ -73,7 +73,9 @@ fn main_0() -> i32 { (*(*f3.borrow()))(_arg0, _arg1, _arg2, _arg3) }) == 22_u64) ); - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || (0 != 0) { + __do_while = false; let stream: Value> = Rc::new(RefCell::new( match Ptr::from_string_literal("rb").to_rust_string() { v if v == "rb" => std::fs::OpenOptions::new() @@ -124,11 +126,10 @@ fn main_0() -> i32 { (*stream.borrow()).delete(); 0 }; - if !(0 != 0) { - break; - } } - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || (0 != 0) { + __do_while = false; let stream: Value> = Rc::new(RefCell::new( match Ptr::from_string_literal("rb").to_rust_string() { v if v == "rb" => std::fs::OpenOptions::new() @@ -181,9 +182,6 @@ fn main_0() -> i32 { (*stream.borrow()).delete(); 0 }; - if !(0 != 0) { - break; - } } let gn1: Value) -> u64>> = Rc::new(RefCell::new(FnPtr::< @@ -239,7 +237,9 @@ fn main_0() -> i32 { (*(*g3.borrow()))(_arg0, _arg1, _arg2, _arg3) }) == 33_u64) ); - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || (0 != 0) { + __do_while = false; let stream: Value> = Rc::new(RefCell::new( match Ptr::from_string_literal("wb").to_rust_string() { v if v == "rb" => std::fs::OpenOptions::new() @@ -280,11 +280,10 @@ fn main_0() -> i32 { (*stream.borrow()).delete(); 0 }; - if !(0 != 0) { - break; - } } - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || (0 != 0) { + __do_while = false; let stream: Value> = Rc::new(RefCell::new( match Ptr::from_string_literal("wb").to_rust_string() { v if v == "rb" => std::fs::OpenOptions::new() @@ -327,9 +326,6 @@ fn main_0() -> i32 { (*stream.borrow()).delete(); 0 }; - if !(0 != 0) { - break; - } } return 0; } diff --git a/tests/unit/out/refcount/switch_in_dowhile.rs b/tests/unit/out/refcount/switch_in_dowhile.rs index 360a0de..03d6984 100644 --- a/tests/unit/out/refcount/switch_in_dowhile.rs +++ b/tests/unit/out/refcount/switch_in_dowhile.rs @@ -10,7 +10,9 @@ pub fn switch_in_dowhile_0(n: i32) -> i32 { let n: Value = Rc::new(RefCell::new(n)); let r: Value = Rc::new(RefCell::new(0)); let i: Value = Rc::new(RefCell::new(0)); - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || ((*i.borrow()) < (*n.borrow())) { + __do_while = false; 'switch: { let __match_cond = (*i.borrow()); match __match_cond { @@ -29,9 +31,6 @@ pub fn switch_in_dowhile_0(n: i32) -> i32 { } }; (*i.borrow_mut()).prefix_inc(); - if !((*i.borrow()) < (*n.borrow())) { - break; - } } return (*r.borrow()); } diff --git a/tests/unit/out/unsafe/do_while_continue.rs b/tests/unit/out/unsafe/do_while_continue.rs new file mode 100644 index 0000000..787aa49 --- /dev/null +++ b/tests/unit/out/unsafe/do_while_continue.rs @@ -0,0 +1,52 @@ +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 unsafe fn run_0() -> i32 { + let mut i: i32 = 0; + let mut runs: i32 = 0; + let mut __do_while = true; + 'loop_: while __do_while || ((((i) < (4)) as i32) != 0) { + __do_while = false; + runs += 1; + i += 1; + if ((((i) == (4)) as i32) != 0) { + continue 'loop_; + } + } + return runs; +} +pub unsafe fn nested_1() -> i32 { + let mut oi: i32 = 0; + let mut runs: i32 = 0; + let mut __do_while = true; + 'loop_: while __do_while || ((((oi) < (2)) as i32) != 0) { + __do_while = false; + oi += 1; + let mut ii: i32 = 0; + let mut __do_while = true; + 'loop_: while __do_while || ((((ii) < (3)) as i32) != 0) { + __do_while = false; + runs += 1; + ii += 1; + if ((((ii) == (3)) as i32) != 0) { + continue 'loop_; + } + } + } + return runs; +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + assert!(((((unsafe { run_0() }) == (4)) as i32) != 0)); + assert!(((((unsafe { nested_1() }) == (6)) as i32) != 0)); + return 0; +} diff --git a/tests/unit/out/unsafe/dowhile.rs b/tests/unit/out/unsafe/dowhile.rs index 3e40ce4..42197a4 100644 --- a/tests/unit/out/unsafe/dowhile.rs +++ b/tests/unit/out/unsafe/dowhile.rs @@ -7,19 +7,17 @@ use std::io::{Read, Seek, Write}; use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; pub unsafe fn dowhile_0(mut x: i32) -> i32 { - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || ((x) <= (200)) { + __do_while = false; x += 1; - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || ((x) <= (100)) { + __do_while = false; x += 1; x += 1; - if !((x) <= (100)) { - break; - } } x += 1; - if !((x) <= (200)) { - break; - } } return x; } diff --git a/tests/unit/out/unsafe/fn_ptr_stdlib_compare.rs b/tests/unit/out/unsafe/fn_ptr_stdlib_compare.rs index 01d5ebb..1bbc3c0 100644 --- a/tests/unit/out/unsafe/fn_ptr_stdlib_compare.rs +++ b/tests/unit/out/unsafe/fn_ptr_stdlib_compare.rs @@ -58,7 +58,9 @@ unsafe fn main_0() -> i32 { (f3).unwrap()(_arg0, _arg1, _arg2, _arg3) }) == (22_u64)) ); - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || (0 != 0) { + __do_while = false; let mut stream: *mut ::libc::FILE = libc::fopen( b"/dev/zero\0".as_ptr() as *const i8, b"rb\0".as_ptr() as *const i8, @@ -90,11 +92,10 @@ unsafe fn main_0() -> i32 { i.prefix_inc(); } libc::fclose(stream); - if !(0 != 0) { - break; - } } - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || (0 != 0) { + __do_while = false; let mut stream: *mut ::libc::FILE = libc::fopen( b"/dev/zero\0".as_ptr() as *const i8, b"rb\0".as_ptr() as *const i8, @@ -127,9 +128,6 @@ unsafe fn main_0() -> i32 { i.prefix_inc(); } libc::fclose(stream); - if !(0 != 0) { - break; - } } let mut gn1: Option u64> = Some(libcc2rs::fwrite_unsafe); @@ -161,7 +159,9 @@ unsafe fn main_0() -> i32 { (g3).unwrap()(_arg0, _arg1, _arg2, _arg3) }) == (33_u64)) ); - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || (0 != 0) { + __do_while = false; let mut stream: *mut ::libc::FILE = libc::fopen( b"/dev/null\0".as_ptr() as *const i8, b"wb\0".as_ptr() as *const i8, @@ -183,11 +183,10 @@ unsafe fn main_0() -> i32 { ); assert!(((n) == (10_u64))); libc::fclose(stream); - if !(0 != 0) { - break; - } } - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || (0 != 0) { + __do_while = false; let mut stream: *mut ::libc::FILE = libc::fopen( b"/dev/null\0".as_ptr() as *const i8, b"wb\0".as_ptr() as *const i8, @@ -211,9 +210,6 @@ unsafe fn main_0() -> i32 { }); assert!(((n) == (10_u64))); libc::fclose(stream); - if !(0 != 0) { - break; - } } return 0; } diff --git a/tests/unit/out/unsafe/malloc_realloc_free.rs b/tests/unit/out/unsafe/malloc_realloc_free.rs index a1ff1d1..4075cb1 100644 --- a/tests/unit/out/unsafe/malloc_realloc_free.rs +++ b/tests/unit/out/unsafe/malloc_realloc_free.rs @@ -12,7 +12,9 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || (0 != 0) { + __do_while = false; let mut p: *mut i32 = (libcc2rs::malloc_unsafe(::std::mem::size_of::() as u64) as *mut i32); (*p) = 42; @@ -53,9 +55,6 @@ unsafe fn main_0() -> i32 { i.postfix_inc(); } libcc2rs::free_unsafe((zeros as *mut i32 as *mut ::libc::c_void)); - if !(0 != 0) { - break; - } } let mut pmalloc: Option *mut ::libc::c_void> = Some(libcc2rs::malloc_unsafe); let mut pfree: Option = Some(libcc2rs::free_unsafe); @@ -63,7 +62,9 @@ unsafe fn main_0() -> i32 { Some(libcc2rs::realloc_unsafe); let mut pcalloc: Option *mut ::libc::c_void> = Some(libcc2rs::calloc_unsafe); - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || (0 != 0) { + __do_while = false; let mut p: *mut i32 = ((unsafe { let _arg0: u64 = ::std::mem::size_of::() as u64; (pmalloc).unwrap()(_arg0) @@ -124,9 +125,6 @@ unsafe fn main_0() -> i32 { let _arg0: *mut ::libc::c_void = (zeros as *mut i32 as *mut ::libc::c_void); (pfree).unwrap()(_arg0) }); - if !(0 != 0) { - break; - } } return 0; } diff --git a/tests/unit/out/unsafe/switch_in_dowhile.rs b/tests/unit/out/unsafe/switch_in_dowhile.rs index e6144b0..3c34a73 100644 --- a/tests/unit/out/unsafe/switch_in_dowhile.rs +++ b/tests/unit/out/unsafe/switch_in_dowhile.rs @@ -9,7 +9,9 @@ use std::rc::Rc; pub unsafe fn switch_in_dowhile_0(mut n: i32) -> i32 { let mut r: i32 = 0; let mut i: i32 = 0; - 'loop_: loop { + let mut __do_while = true; + 'loop_: while __do_while || ((i) < (n)) { + __do_while = false; 'switch: { let __match_cond = i; match __match_cond { @@ -28,9 +30,6 @@ pub unsafe fn switch_in_dowhile_0(mut n: i32) -> i32 { } }; i.prefix_inc(); - if !((i) < (n)) { - break; - } } return r; }