diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 4f53bc6b8..22fe1a390 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -3440,12 +3440,16 @@ bool Converter::VisitCXXNewExpr(clang::CXXNewExpr *expr) { if (!curr_init_type_.empty() && curr_init_type_.back()->isPointerType()) { StrCat(".as_mut_ptr()"); } + SetFreshType(expr->getType()); } else { - auto initializer_as_string = ToString(expr->getInitializer()); + auto initializer_as_string = + expr->getInitializer() ? ToString(expr->getInitializer()) + : GetDefaultAsString(expr->getAllocatedType()); auto new_as_string = std::format("(Box::leak(Box::new({})) as {})", initializer_as_string, ToString(expr->getType())); StrCat(new_as_string); + SetFreshType(expr->getType()); } return false; } diff --git a/tests/unit/new.cpp b/tests/unit/new.cpp index 30f42be01..2b76dda6c 100644 --- a/tests/unit/new.cpp +++ b/tests/unit/new.cpp @@ -1,9 +1,24 @@ #include +struct Pair { + int x, y; +}; + int main() { int *x = new int(5); int out = *x; delete x; assert(out == 5); + + int *y = new int; + *y = 9; + assert(*y == 9); + delete y; + + Pair *p = new Pair; + p->x = 1; + p->y = 2; + assert(p->x + p->y == 3); + delete p; return 0; } diff --git a/tests/unit/new_array.cpp b/tests/unit/new_array.cpp index 96d29ac6b..dac2079e3 100644 --- a/tests/unit/new_array.cpp +++ b/tests/unit/new_array.cpp @@ -1,5 +1,22 @@ +static int sum(int *p, int n) { + int total = 0; + for (int i = 0; i < n; ++i) { + total += p[i]; + } + return total; +} + int main() { int *array = new int[100]; delete[] array; + + int *filled = new int[4]; + for (int i = 0; i < 4; ++i) { + filled[i] = i + 1; + } + if (sum(filled, 4) != 10) { + return 1; + } + delete[] filled; return 0; } diff --git a/tests/unit/out/refcount/new.rs b/tests/unit/out/refcount/new.rs index 002991001..bc25b52a5 100644 --- a/tests/unit/out/refcount/new.rs +++ b/tests/unit/out/refcount/new.rs @@ -6,6 +6,36 @@ use std::io::prelude::*; use std::io::{Read, Seek, Write}; use std::os::fd::AsFd; use std::rc::{Rc, Weak}; +#[derive(Default)] +pub struct Pair { + pub x: Value, + pub y: Value, +} +impl Clone for Pair { + fn clone(&self) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + x: Rc::new(RefCell::new((*self.x.borrow()))), + y: Rc::new(RefCell::new((*self.y.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl ByteRepr for Pair { + fn byte_size() -> usize { + 8 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.x.borrow()).to_bytes(&mut buf[0..4]); + (*self.y.borrow()).to_bytes(&mut buf[4..8]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + x: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + y: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + } + } +} pub fn main() { __cpp2rust_init_globals(); std::process::exit(main_0()); @@ -15,6 +45,20 @@ fn main_0() -> i32 { let out: Value = Rc::new(RefCell::new(((*x.borrow()).read()))); (*x.borrow()).delete(); assert!(((*out.borrow()) == 5)); + let y: Value> = Rc::new(RefCell::new(Ptr::alloc(Default::default()))); + (*y.borrow()).write(9); + assert!((((*y.borrow()).read()) == 9)); + (*y.borrow()).delete(); + let p: Value> = Rc::new(RefCell::new(Ptr::alloc(::default()))); + (*(*(*p.borrow()).upgrade().deref()).x.borrow_mut()) = 1; + (*(*(*p.borrow()).upgrade().deref()).y.borrow_mut()) = 2; + assert!( + ({ + let _lhs = (*(*(*p.borrow()).upgrade().deref()).x.borrow()); + _lhs + (*(*(*p.borrow()).upgrade().deref()).y.borrow()) + } == 3) + ); + (*p.borrow()).delete(); return 0; } pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/refcount/new_array.rs b/tests/unit/out/refcount/new_array.rs index f6f06091c..d5d2babef 100644 --- a/tests/unit/out/refcount/new_array.rs +++ b/tests/unit/out/refcount/new_array.rs @@ -6,6 +6,18 @@ use std::io::prelude::*; use std::io::{Read, Seek, Write}; use std::os::fd::AsFd; use std::rc::{Rc, Weak}; +pub fn sum_0(p: Ptr, n: i32) -> i32 { + let p: Value> = Rc::new(RefCell::new(p)); + let n: Value = Rc::new(RefCell::new(n)); + let total: Value = Rc::new(RefCell::new(0)); + let i: Value = Rc::new(RefCell::new(0)); + 'loop_: while ((*i.borrow()) < (*n.borrow())) { + let __rhs = ((*p.borrow()).offset((*i.borrow()) as isize).read()); + (*total.borrow_mut()) += __rhs; + (*i.borrow_mut()).prefix_inc(); + } + return (*total.borrow()); +} pub fn main() { __cpp2rust_init_globals(); std::process::exit(main_0()); @@ -17,6 +29,27 @@ fn main_0() -> i32 { .collect::>(), ))); (*array.borrow()).delete_array(); + let filled: Value> = Rc::new(RefCell::new(Ptr::alloc_array( + (0..4_usize) + .map(|_| ::default()) + .collect::>(), + ))); + let i: Value = Rc::new(RefCell::new(0)); + 'loop_: while ((*i.borrow()) < 4) { + let __rhs = ((*i.borrow()) + 1); + (*filled.borrow()) + .offset((*i.borrow()) as isize) + .write(__rhs); + (*i.borrow_mut()).prefix_inc(); + } + if (({ + let _p: Ptr = (*filled.borrow()).clone(); + sum_0(_p, 4) + }) != 10) + { + return 1; + } + (*filled.borrow()).delete_array(); return 0; } pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/new.rs b/tests/unit/out/unsafe/new.rs index e44244361..8cd8f319c 100644 --- a/tests/unit/out/unsafe/new.rs +++ b/tests/unit/out/unsafe/new.rs @@ -6,6 +6,12 @@ use std::collections::BTreeMap; use std::io::{Read, Seek, Write}; use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct Pair { + pub x: i32, + pub y: i32, +} pub fn main() { unsafe { __cpp2rust_init_globals(); @@ -17,6 +23,15 @@ unsafe fn main_0() -> i32 { let mut out: i32 = (*x); ::std::mem::drop(Box::from_raw(x)); assert!(((out) == (5))); + let mut y: *mut i32 = (Box::leak(Box::new(0_i32)) as *mut i32); + (*y) = 9; + assert!(((*y) == (9))); + ::std::mem::drop(Box::from_raw(y)); + let mut p: *mut Pair = (Box::leak(Box::new(::default())) as *mut Pair); + (*p).x = 1; + (*p).y = 2; + assert!(((((*p).x) + ((*p).y)) == (3))); + ::std::mem::drop(Box::from_raw(p)); return 0; } pub unsafe fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/new_array.rs b/tests/unit/out/unsafe/new_array.rs index c4d91846b..f8ca9c639 100644 --- a/tests/unit/out/unsafe/new_array.rs +++ b/tests/unit/out/unsafe/new_array.rs @@ -6,6 +6,15 @@ use std::collections::BTreeMap; use std::io::{Read, Seek, Write}; use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; +pub unsafe fn sum_0(mut p: *mut i32, mut n: i32) -> i32 { + let mut total: i32 = 0; + let mut i: i32 = 0; + 'loop_: while ((i) < (n)) { + total += (*p.offset((i) as isize)); + i.prefix_inc(); + } + return total; +} pub fn main() { unsafe { __cpp2rust_init_globals(); @@ -20,6 +29,24 @@ unsafe fn main_0() -> i32 { array, libcc2rs::malloc_usable_size(array as *mut ::libc::c_void) / ::std::mem::size_of::(), ))); + let mut filled: *mut i32 = + Box::leak((0..4_usize).map(|_| 0_i32).collect::>()).as_mut_ptr(); + let mut i: i32 = 0; + 'loop_: while ((i) < (4)) { + (*filled.offset((i) as isize)) = ((i) + (1)); + i.prefix_inc(); + } + if ((unsafe { + let _p: *mut i32 = filled; + sum_0(_p, 4) + }) != (10)) + { + return 1; + } + ::std::mem::drop(Box::from_raw(::std::slice::from_raw_parts_mut( + filled, + libcc2rs::malloc_usable_size(filled as *mut ::libc::c_void) / ::std::mem::size_of::(), + ))); return 0; } pub unsafe fn __cpp2rust_init_globals() {}