Skip to content

Commit d942d94

Browse files
committed
Translate empty unions in unsafe
1 parent a863d43 commit d942d94

4 files changed

Lines changed: 52 additions & 0 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,9 @@ void Converter::EmitRustUnion(clang::RecordDecl *decl) {
957957
StrCat(keyword::kPub, keyword::kUnion, GetRecordName(decl));
958958
{
959959
PushBrace brace(*this);
960+
if (decl->field_empty()) {
961+
StrCat("__empty: u8,");
962+
}
960963
for (auto *field : decl->fields()) {
961964
VisitFieldDecl(field);
962965
}

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,45 @@ impl ByteRepr for basic {
4444
}
4545
}
4646
}
47+
pub struct empty {
48+
__bytes: Value<Box<[u8]>>,
49+
}
50+
impl empty {}
51+
impl Clone for empty {
52+
fn clone(&self) -> Self {
53+
empty {
54+
__bytes: Rc::new(RefCell::new(self.__bytes.borrow().clone())),
55+
}
56+
}
57+
}
58+
impl Default for empty {
59+
fn default() -> Self {
60+
empty {
61+
__bytes: Rc::new(RefCell::new(Box::from([0u8; 1]))),
62+
}
63+
}
64+
}
65+
impl ByteRepr for empty {
66+
fn byte_size() -> usize {
67+
1
68+
}
69+
fn to_bytes(&self, buf: &mut [u8]) {
70+
buf.copy_from_slice(&self.__bytes.borrow());
71+
}
72+
fn from_bytes(buf: &[u8]) -> Self {
73+
empty {
74+
__bytes: Rc::new(RefCell::new(Box::from(buf))),
75+
}
76+
}
77+
}
4778
pub fn main() {
4879
__cpp2rust_init_globals();
4980
std::process::exit(main_0());
5081
}
5182
fn main_0() -> i32 {
5283
let u: Value<basic> = Rc::new(RefCell::new(<basic>::default()));
84+
let e: Value<empty> = Rc::new(RefCell::new(<empty>::default()));
85+
&(*e.borrow_mut());
5386
(*u.borrow_mut()).i().write(42);
5487
assert!((((*u.borrow()).i().read()) == 42));
5588
(*u.borrow_mut()).f().write(3.140000105E+0);

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ impl Default for basic {
1717
unsafe { std::mem::zeroed() }
1818
}
1919
}
20+
#[repr(C)]
21+
#[derive(Copy, Clone)]
22+
pub union empty {
23+
__empty: u8,
24+
}
25+
impl Default for empty {
26+
fn default() -> Self {
27+
unsafe { std::mem::zeroed() }
28+
}
29+
}
2030
pub fn main() {
2131
unsafe {
2232
__cpp2rust_init_globals();
@@ -25,6 +35,8 @@ pub fn main() {
2535
}
2636
unsafe fn main_0() -> i32 {
2737
let mut u: basic = <basic>::default();
38+
let mut e: empty = <empty>::default();
39+
&(e);
2840
u.i = 42;
2941
assert!(((u.i) == (42)));
3042
u.f = 3.140000105E+0;

‎tests/unit/union_basic.cpp‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@ union basic {
55
float f;
66
};
77

8+
union empty {};
9+
810
int main(void) {
911
union basic u;
12+
union empty e;
13+
(void)e;
1014

1115
u.i = 42;
1216
assert(u.i == 42);

0 commit comments

Comments
 (0)