Skip to content

Commit f813977

Browse files
authored
Default initialize object allocated with new (#390)
1 parent 119f77b commit f813977

7 files changed

Lines changed: 156 additions & 1 deletion

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3440,12 +3440,16 @@ bool Converter::VisitCXXNewExpr(clang::CXXNewExpr *expr) {
34403440
if (!curr_init_type_.empty() && curr_init_type_.back()->isPointerType()) {
34413441
StrCat(".as_mut_ptr()");
34423442
}
3443+
SetFreshType(expr->getType());
34433444
} else {
3444-
auto initializer_as_string = ToString(expr->getInitializer());
3445+
auto initializer_as_string =
3446+
expr->getInitializer() ? ToString(expr->getInitializer())
3447+
: GetDefaultAsString(expr->getAllocatedType());
34453448
auto new_as_string =
34463449
std::format("(Box::leak(Box::new({})) as {})", initializer_as_string,
34473450
ToString(expr->getType()));
34483451
StrCat(new_as_string);
3452+
SetFreshType(expr->getType());
34493453
}
34503454
return false;
34513455
}

‎tests/unit/new.cpp‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
11
#include <cassert>
22

3+
struct Pair {
4+
int x, y;
5+
};
6+
37
int main() {
48
int *x = new int(5);
59
int out = *x;
610
delete x;
711
assert(out == 5);
12+
13+
int *y = new int;
14+
*y = 9;
15+
assert(*y == 9);
16+
delete y;
17+
18+
Pair *p = new Pair;
19+
p->x = 1;
20+
p->y = 2;
21+
assert(p->x + p->y == 3);
22+
delete p;
823
return 0;
924
}

‎tests/unit/new_array.cpp‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
1+
static int sum(int *p, int n) {
2+
int total = 0;
3+
for (int i = 0; i < n; ++i) {
4+
total += p[i];
5+
}
6+
return total;
7+
}
8+
19
int main() {
210
int *array = new int[100];
311
delete[] array;
12+
13+
int *filled = new int[4];
14+
for (int i = 0; i < 4; ++i) {
15+
filled[i] = i + 1;
16+
}
17+
if (sum(filled, 4) != 10) {
18+
return 1;
19+
}
20+
delete[] filled;
421
return 0;
522
}

‎tests/unit/out/refcount/new.rs‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,36 @@ use std::io::prelude::*;
66
use std::io::{Read, Seek, Write};
77
use std::os::fd::AsFd;
88
use std::rc::{Rc, Weak};
9+
#[derive(Default)]
10+
pub struct Pair {
11+
pub x: Value<i32>,
12+
pub y: Value<i32>,
13+
}
14+
impl Clone for Pair {
15+
fn clone(&self) -> Self {
16+
let __this: Value<Pair> = Rc::new(RefCell::new(Self {
17+
x: Rc::new(RefCell::new((*self.x.borrow()))),
18+
y: Rc::new(RefCell::new((*self.y.borrow()))),
19+
}));
20+
let this: Ptr<Pair> = __this.as_pointer();
21+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
22+
}
23+
}
24+
impl ByteRepr for Pair {
25+
fn byte_size() -> usize {
26+
8
27+
}
28+
fn to_bytes(&self, buf: &mut [u8]) {
29+
(*self.x.borrow()).to_bytes(&mut buf[0..4]);
30+
(*self.y.borrow()).to_bytes(&mut buf[4..8]);
31+
}
32+
fn from_bytes(buf: &[u8]) -> Self {
33+
Self {
34+
x: Rc::new(RefCell::new(<i32>::from_bytes(&buf[0..4]))),
35+
y: Rc::new(RefCell::new(<i32>::from_bytes(&buf[4..8]))),
36+
}
37+
}
38+
}
939
pub fn main() {
1040
__cpp2rust_init_globals();
1141
std::process::exit(main_0());
@@ -15,6 +45,20 @@ fn main_0() -> i32 {
1545
let out: Value<i32> = Rc::new(RefCell::new(((*x.borrow()).read())));
1646
(*x.borrow()).delete();
1747
assert!(((*out.borrow()) == 5));
48+
let y: Value<Ptr<i32>> = Rc::new(RefCell::new(Ptr::alloc(Default::default())));
49+
(*y.borrow()).write(9);
50+
assert!((((*y.borrow()).read()) == 9));
51+
(*y.borrow()).delete();
52+
let p: Value<Ptr<Pair>> = Rc::new(RefCell::new(Ptr::alloc(<Pair>::default())));
53+
(*(*(*p.borrow()).upgrade().deref()).x.borrow_mut()) = 1;
54+
(*(*(*p.borrow()).upgrade().deref()).y.borrow_mut()) = 2;
55+
assert!(
56+
({
57+
let _lhs = (*(*(*p.borrow()).upgrade().deref()).x.borrow());
58+
_lhs + (*(*(*p.borrow()).upgrade().deref()).y.borrow())
59+
} == 3)
60+
);
61+
(*p.borrow()).delete();
1862
return 0;
1963
}
2064
pub fn __cpp2rust_init_globals() {}

‎tests/unit/out/refcount/new_array.rs‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@ use std::io::prelude::*;
66
use std::io::{Read, Seek, Write};
77
use std::os::fd::AsFd;
88
use std::rc::{Rc, Weak};
9+
pub fn sum_0(p: Ptr<i32>, n: i32) -> i32 {
10+
let p: Value<Ptr<i32>> = Rc::new(RefCell::new(p));
11+
let n: Value<i32> = Rc::new(RefCell::new(n));
12+
let total: Value<i32> = Rc::new(RefCell::new(0));
13+
let i: Value<i32> = Rc::new(RefCell::new(0));
14+
'loop_: while ((*i.borrow()) < (*n.borrow())) {
15+
let __rhs = ((*p.borrow()).offset((*i.borrow()) as isize).read());
16+
(*total.borrow_mut()) += __rhs;
17+
(*i.borrow_mut()).prefix_inc();
18+
}
19+
return (*total.borrow());
20+
}
921
pub fn main() {
1022
__cpp2rust_init_globals();
1123
std::process::exit(main_0());
@@ -17,6 +29,27 @@ fn main_0() -> i32 {
1729
.collect::<Box<[i32]>>(),
1830
)));
1931
(*array.borrow()).delete_array();
32+
let filled: Value<Ptr<i32>> = Rc::new(RefCell::new(Ptr::alloc_array(
33+
(0..4_usize)
34+
.map(|_| <i32>::default())
35+
.collect::<Box<[i32]>>(),
36+
)));
37+
let i: Value<i32> = Rc::new(RefCell::new(0));
38+
'loop_: while ((*i.borrow()) < 4) {
39+
let __rhs = ((*i.borrow()) + 1);
40+
(*filled.borrow())
41+
.offset((*i.borrow()) as isize)
42+
.write(__rhs);
43+
(*i.borrow_mut()).prefix_inc();
44+
}
45+
if (({
46+
let _p: Ptr<i32> = (*filled.borrow()).clone();
47+
sum_0(_p, 4)
48+
}) != 10)
49+
{
50+
return 1;
51+
}
52+
(*filled.borrow()).delete_array();
2053
return 0;
2154
}
2255
pub fn __cpp2rust_init_globals() {}

‎tests/unit/out/unsafe/new.rs‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ use std::collections::BTreeMap;
66
use std::io::{Read, Seek, Write};
77
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
88
use std::rc::Rc;
9+
#[repr(C)]
10+
#[derive(Copy, Clone, Default)]
11+
pub struct Pair {
12+
pub x: i32,
13+
pub y: i32,
14+
}
915
pub fn main() {
1016
unsafe {
1117
__cpp2rust_init_globals();
@@ -17,6 +23,15 @@ unsafe fn main_0() -> i32 {
1723
let mut out: i32 = (*x);
1824
::std::mem::drop(Box::from_raw(x));
1925
assert!(((out) == (5)));
26+
let mut y: *mut i32 = (Box::leak(Box::new(0_i32)) as *mut i32);
27+
(*y) = 9;
28+
assert!(((*y) == (9)));
29+
::std::mem::drop(Box::from_raw(y));
30+
let mut p: *mut Pair = (Box::leak(Box::new(<Pair>::default())) as *mut Pair);
31+
(*p).x = 1;
32+
(*p).y = 2;
33+
assert!(((((*p).x) + ((*p).y)) == (3)));
34+
::std::mem::drop(Box::from_raw(p));
2035
return 0;
2136
}
2237
pub unsafe fn __cpp2rust_init_globals() {}

‎tests/unit/out/unsafe/new_array.rs‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ use std::collections::BTreeMap;
66
use std::io::{Read, Seek, Write};
77
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
88
use std::rc::Rc;
9+
pub unsafe fn sum_0(mut p: *mut i32, mut n: i32) -> i32 {
10+
let mut total: i32 = 0;
11+
let mut i: i32 = 0;
12+
'loop_: while ((i) < (n)) {
13+
total += (*p.offset((i) as isize));
14+
i.prefix_inc();
15+
}
16+
return total;
17+
}
918
pub fn main() {
1019
unsafe {
1120
__cpp2rust_init_globals();
@@ -20,6 +29,24 @@ unsafe fn main_0() -> i32 {
2029
array,
2130
libcc2rs::malloc_usable_size(array as *mut ::libc::c_void) / ::std::mem::size_of::<i32>(),
2231
)));
32+
let mut filled: *mut i32 =
33+
Box::leak((0..4_usize).map(|_| 0_i32).collect::<Box<[i32]>>()).as_mut_ptr();
34+
let mut i: i32 = 0;
35+
'loop_: while ((i) < (4)) {
36+
(*filled.offset((i) as isize)) = ((i) + (1));
37+
i.prefix_inc();
38+
}
39+
if ((unsafe {
40+
let _p: *mut i32 = filled;
41+
sum_0(_p, 4)
42+
}) != (10))
43+
{
44+
return 1;
45+
}
46+
::std::mem::drop(Box::from_raw(::std::slice::from_raw_parts_mut(
47+
filled,
48+
libcc2rs::malloc_usable_size(filled as *mut ::libc::c_void) / ::std::mem::size_of::<i32>(),
49+
)));
2350
return 0;
2451
}
2552
pub unsafe fn __cpp2rust_init_globals() {}

0 commit comments

Comments
 (0)