diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index f2247a35..c25ea3b0 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1632,11 +1632,15 @@ bool ConverterRefCount::VisitInitListExpr(clang::InitListExpr *expr) { StrCat(GetUnsafeTypeAsString(qual_type)); { PushBrace brace(*this); - int i = 0; + unsigned i = 0; PushConversionKind push(*this, ConversionKind::FullRefCount); for (const auto *field : record->fields()) { StrCat(GetNamedDeclAsString(field), token::kColon); - ConvertVarInit(field->getType(), expr->getInit(i++)); + if (i < expr->getNumInits()) { + ConvertVarInit(field->getType(), expr->getInit(i++)); + } else { + StrCat(GetDefaultAsString(field->getType())); + } StrCat(token::kComma); } } diff --git a/tests/unit/new_struct.cpp b/tests/unit/new_struct.cpp index 3a4c0324..e98e6116 100644 --- a/tests/unit/new_struct.cpp +++ b/tests/unit/new_struct.cpp @@ -4,10 +4,27 @@ struct Pair { int x, y; }; +struct Triple { + int a; + int b; + Pair p; +}; + int main() { Pair *p = new Pair{1, 2}; int out = p->x + p->y; delete p; assert(out == 3); + + Triple t{1}; + assert(t.a == 1); + assert(t.b == 0); + assert(t.p.x == 0 && t.p.y == 0); + + Triple *q = new Triple{2, 3}; + assert(q->a == 2); + assert(q->b == 3); + assert(q->p.x == 0 && q->p.y == 0); + delete q; return 0; } diff --git a/tests/unit/out/refcount/new_struct.rs b/tests/unit/out/refcount/new_struct.rs index 85b039db..bb27e89b 100644 --- a/tests/unit/out/refcount/new_struct.rs +++ b/tests/unit/out/refcount/new_struct.rs @@ -36,6 +36,40 @@ impl ByteRepr for Pair { } } } +#[derive(Default)] +pub struct Triple { + pub a: Value, + pub b: Value, + pub p: Value, +} +impl Clone for Triple { + fn clone(&self) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + a: Rc::new(RefCell::new((*self.a.borrow()))), + b: Rc::new(RefCell::new((*self.b.borrow()))), + p: Rc::new(RefCell::new((*self.p.borrow()).clone())), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl ByteRepr for Triple { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.a.borrow()).to_bytes(&mut buf[0..4]); + (*self.b.borrow()).to_bytes(&mut buf[4..8]); + (*self.p.borrow()).to_bytes(&mut buf[8..16]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + a: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + b: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + p: Rc::new(RefCell::new(::from_bytes(&buf[8..16]))), + } + } +} pub fn main() { __cpp2rust_init_globals(); std::process::exit(main_0()); @@ -51,6 +85,35 @@ fn main_0() -> i32 { })); (*p.borrow()).delete(); assert!(((*out.borrow()) == 3)); + let t: Value = Rc::new(RefCell::new(Triple { + a: Rc::new(RefCell::new(1)), + b: Rc::new(RefCell::new(::default())), + p: Rc::new(RefCell::new(Pair { + x: Rc::new(RefCell::new(::default())), + y: Rc::new(RefCell::new(::default())), + })), + })); + assert!(((*(*t.borrow()).a.borrow()) == 1)); + assert!(((*(*t.borrow()).b.borrow()) == 0)); + assert!( + ((*(*(*t.borrow()).p.borrow()).x.borrow()) == 0) + && ((*(*(*t.borrow()).p.borrow()).y.borrow()) == 0) + ); + let q: Value> = Rc::new(RefCell::new(Ptr::alloc(Triple { + a: Rc::new(RefCell::new(2)), + b: Rc::new(RefCell::new(3)), + p: Rc::new(RefCell::new(Pair { + x: Rc::new(RefCell::new(::default())), + y: Rc::new(RefCell::new(::default())), + })), + }))); + assert!(((*(*(*q.borrow()).upgrade().deref()).a.borrow()) == 2)); + assert!(((*(*(*q.borrow()).upgrade().deref()).b.borrow()) == 3)); + assert!( + ((*(*(*(*q.borrow()).upgrade().deref()).p.borrow()).x.borrow()) == 0) + && ((*(*(*(*q.borrow()).upgrade().deref()).p.borrow()).y.borrow()) == 0) + ); + (*q.borrow()).delete(); return 0; } pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/new_struct.rs b/tests/unit/out/unsafe/new_struct.rs index 9228459f..ccf4e4f8 100644 --- a/tests/unit/out/unsafe/new_struct.rs +++ b/tests/unit/out/unsafe/new_struct.rs @@ -12,6 +12,13 @@ pub struct Pair { pub x: i32, pub y: i32, } +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct Triple { + pub a: i32, + pub b: i32, + pub p: Pair, +} pub fn main() { unsafe { __cpp2rust_init_globals(); @@ -23,6 +30,23 @@ unsafe fn main_0() -> i32 { let mut out: i32 = (((*p).x) + ((*p).y)); ::std::mem::drop(Box::from_raw(p)); assert!(((out) == (3))); + let mut t: Triple = Triple { + a: 1, + b: 0_i32, + p: Pair { x: 0_i32, y: 0_i32 }, + }; + assert!(((t.a) == (1))); + assert!(((t.b) == (0))); + assert!(((t.p.x) == (0)) && ((t.p.y) == (0))); + let mut q: *mut Triple = (Box::leak(Box::new(Triple { + a: 2, + b: 3, + p: Pair { x: 0_i32, y: 0_i32 }, + })) as *mut Triple); + assert!((((*q).a) == (2))); + assert!((((*q).b) == (3))); + assert!((((*q).p.x) == (0)) && (((*q).p.y) == (0))); + ::std::mem::drop(Box::from_raw(q)); return 0; } pub unsafe fn __cpp2rust_init_globals() {}