Skip to content

Commit 7456a57

Browse files
committed
Fix pointer destruction
1 parent ed34f63 commit 7456a57

4 files changed

Lines changed: 327 additions & 2 deletions

File tree

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,8 +1743,8 @@ bool ConverterRefCount::VisitCXXDeleteExpr(clang::CXXDeleteExpr *expr) {
17431743
}
17441744

17451745
PushBrace brace(*this);
1746-
StrCat(keyword::kLet, "__p", token::kAssign, ToString(expr->getArgument()),
1747-
token::kSemiColon);
1746+
StrCat(keyword::kLet, "__p", token::kAssign,
1747+
ConvertFreshPointer(expr->getArgument()), token::kSemiColon);
17481748
if (expr->isArrayForm()) {
17491749
StrCat(std::format("for __i in 0..__p.len() {{ __p.offset(__i as "
17501750
"isize).{}(); }}",
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include <cassert>
2+
3+
int order[8];
4+
int n = 0;
5+
6+
struct Base {
7+
~Base() { order[n++] = 1; }
8+
};
9+
10+
struct Member {
11+
~Member() { order[n++] = 2; }
12+
};
13+
14+
struct Derived : Base {
15+
Member m;
16+
~Derived() { order[n++] = 3; }
17+
};
18+
19+
struct Implicit : Base {
20+
Member m;
21+
};
22+
23+
int main() {
24+
{
25+
Derived d;
26+
}
27+
assert(n == 3);
28+
assert(order[0] == 3 && order[1] == 2 && order[2] == 1);
29+
30+
n = 0;
31+
{
32+
Implicit i;
33+
}
34+
assert(n == 2);
35+
assert(order[0] == 2 && order[1] == 1);
36+
37+
n = 0;
38+
Derived *p = new Derived;
39+
delete p;
40+
assert(n == 3);
41+
assert(order[0] == 3 && order[1] == 2 && order[2] == 1);
42+
return 0;
43+
}
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
extern crate libcc2rs;
2+
use libcc2rs::*;
3+
use std::cell::RefCell;
4+
use std::collections::BTreeMap;
5+
use std::io::prelude::*;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::AsFd;
8+
use std::rc::{Rc, Weak};
9+
thread_local!(
10+
pub static order_0: Value<Box<[i32]>> = Rc::new(RefCell::new(
11+
(0..8).map(|_| <i32>::default()).collect::<Box<[i32]>>(),
12+
));
13+
);
14+
thread_local!(
15+
pub static n_1: Value<i32> = Rc::new(RefCell::new(0));
16+
);
17+
#[derive(Default)]
18+
pub struct Base {}
19+
impl Clone for Base {
20+
fn clone(&self) -> Self {
21+
let __this: Value<Base> = Rc::new(RefCell::new(Self {}));
22+
let this: Ptr<Base> = __this.as_pointer();
23+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
24+
}
25+
}
26+
impl ByteRepr for Base {
27+
fn byte_size() -> usize {
28+
1
29+
}
30+
fn to_bytes(&self, buf: &mut [u8]) {}
31+
fn from_bytes(buf: &[u8]) -> Self {
32+
Self {}
33+
}
34+
}
35+
#[derive(Default)]
36+
pub struct Member {}
37+
impl Clone for Member {
38+
fn clone(&self) -> Self {
39+
let __this: Value<Member> = Rc::new(RefCell::new(Self {}));
40+
let this: Ptr<Member> = __this.as_pointer();
41+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
42+
}
43+
}
44+
impl ByteRepr for Member {
45+
fn byte_size() -> usize {
46+
1
47+
}
48+
fn to_bytes(&self, buf: &mut [u8]) {}
49+
fn from_bytes(buf: &[u8]) -> Self {
50+
Self {}
51+
}
52+
}
53+
#[derive(Default)]
54+
pub struct Derived {
55+
pub base_Base: Value<Base>,
56+
pub m: Value<Member>,
57+
}
58+
impl Clone for Derived {
59+
fn clone(&self) -> Self {
60+
let __this: Value<Derived> = Rc::new(RefCell::new(Self {
61+
base_Base: Rc::new(RefCell::new((*self.base_Base.borrow()).clone())),
62+
m: Rc::new(RefCell::new((*self.m.borrow()).clone())),
63+
}));
64+
let this: Ptr<Derived> = __this.as_pointer();
65+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
66+
}
67+
}
68+
impl ByteRepr for Derived {
69+
fn byte_size() -> usize {
70+
1
71+
}
72+
fn to_bytes(&self, buf: &mut [u8]) {
73+
(*self.base_Base.borrow()).to_bytes(&mut buf[0..1]);
74+
(*self.m.borrow()).to_bytes(&mut buf[0..1]);
75+
}
76+
fn from_bytes(buf: &[u8]) -> Self {
77+
Self {
78+
base_Base: Rc::new(RefCell::new(<Base>::from_bytes(&buf[0..1]))),
79+
m: Rc::new(RefCell::new(<Member>::from_bytes(&buf[0..1]))),
80+
}
81+
}
82+
}
83+
#[derive(Default)]
84+
pub struct Implicit {
85+
pub base_Base: Value<Base>,
86+
pub m: Value<Member>,
87+
}
88+
impl Clone for Implicit {
89+
fn clone(&self) -> Self {
90+
let __this: Value<Implicit> = Rc::new(RefCell::new(Self {
91+
base_Base: Rc::new(RefCell::new((*self.base_Base.borrow()).clone())),
92+
m: Rc::new(RefCell::new((*self.m.borrow()).clone())),
93+
}));
94+
let this: Ptr<Implicit> = __this.as_pointer();
95+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
96+
}
97+
}
98+
impl ByteRepr for Implicit {
99+
fn byte_size() -> usize {
100+
1
101+
}
102+
fn to_bytes(&self, buf: &mut [u8]) {
103+
(*self.base_Base.borrow()).to_bytes(&mut buf[0..1]);
104+
(*self.m.borrow()).to_bytes(&mut buf[0..1]);
105+
}
106+
fn from_bytes(buf: &[u8]) -> Self {
107+
Self {
108+
base_Base: Rc::new(RefCell::new(<Base>::from_bytes(&buf[0..1]))),
109+
m: Rc::new(RefCell::new(<Member>::from_bytes(&buf[0..1]))),
110+
}
111+
}
112+
}
113+
pub fn main() {
114+
std::process::exit(main_0());
115+
}
116+
fn main_0() -> i32 {
117+
{
118+
let d: Value<Derived> = Rc::new(RefCell::new(<Derived>::default()));
119+
let _dtor_d = ScopedDestructor::new(&d, |__p| __p.destructor());
120+
}
121+
assert!(((*n_1.with(Value::clone).borrow()) == 3));
122+
assert!(
123+
(((*order_0.with(Value::clone).borrow())[(0) as usize] == 3)
124+
&& ((*order_0.with(Value::clone).borrow())[(1) as usize] == 2))
125+
&& ((*order_0.with(Value::clone).borrow())[(2) as usize] == 1)
126+
);
127+
(*n_1.with(Value::clone).borrow_mut()) = 0;
128+
{
129+
let i: Value<Implicit> = Rc::new(RefCell::new(<Implicit>::default()));
130+
let _dtor_i = ScopedDestructor::new(&i, |__p| __p.destructor());
131+
}
132+
assert!(((*n_1.with(Value::clone).borrow()) == 2));
133+
assert!(
134+
((*order_0.with(Value::clone).borrow())[(0) as usize] == 2)
135+
&& ((*order_0.with(Value::clone).borrow())[(1) as usize] == 1)
136+
);
137+
(*n_1.with(Value::clone).borrow_mut()) = 0;
138+
let p: Value<Ptr<Derived>> = Rc::new(RefCell::new(Ptr::alloc(<Derived>::default())));
139+
{
140+
let __p = (*p.borrow()).clone();
141+
__p.destructor();
142+
__p.delete();
143+
};
144+
assert!(((*n_1.with(Value::clone).borrow()) == 3));
145+
assert!(
146+
(((*order_0.with(Value::clone).borrow())[(0) as usize] == 3)
147+
&& ((*order_0.with(Value::clone).borrow())[(1) as usize] == 2))
148+
&& ((*order_0.with(Value::clone).borrow())[(2) as usize] == 1)
149+
);
150+
return 0;
151+
}
152+
pub trait BaseImpl {
153+
fn destructor(&self);
154+
}
155+
impl BaseImpl for Ptr<Base> {
156+
fn destructor(&self) {
157+
(*order_0.with(Value::clone).borrow_mut())
158+
[((*n_1.with(Value::clone).borrow_mut()).postfix_inc()) as usize] = 1;
159+
}
160+
}
161+
pub trait DerivedImpl {
162+
fn destructor(&self);
163+
}
164+
impl DerivedImpl for Ptr<Derived> {
165+
fn destructor(&self) {
166+
(*order_0.with(Value::clone).borrow_mut())
167+
[((*n_1.with(Value::clone).borrow_mut()).postfix_inc()) as usize] = 3;
168+
(*self.upgrade().deref()).m.as_pointer().destructor();
169+
(*self.upgrade().deref())
170+
.base_Base
171+
.as_pointer()
172+
.destructor();
173+
}
174+
}
175+
pub trait ImplicitImpl {
176+
fn destructor(&self);
177+
}
178+
impl ImplicitImpl for Ptr<Implicit> {
179+
fn destructor(&self) {
180+
(*self.upgrade().deref()).m.as_pointer().destructor();
181+
(*self.upgrade().deref())
182+
.base_Base
183+
.as_pointer()
184+
.destructor();
185+
}
186+
}
187+
pub trait MemberImpl {
188+
fn destructor(&self);
189+
}
190+
impl MemberImpl for Ptr<Member> {
191+
fn destructor(&self) {
192+
(*order_0.with(Value::clone).borrow_mut())
193+
[((*n_1.with(Value::clone).borrow_mut()).postfix_inc()) as usize] = 2;
194+
}
195+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
extern crate libc;
2+
use libc::*;
3+
extern crate libcc2rs;
4+
use libcc2rs::*;
5+
use std::collections::BTreeMap;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
8+
use std::rc::Rc;
9+
pub static mut order_0: [i32; 8] = unsafe { [0_i32; 8] };
10+
pub static mut n_1: i32 = unsafe { 0 };
11+
#[repr(C)]
12+
#[derive(Clone, Default)]
13+
pub struct Base {}
14+
impl Base {
15+
pub unsafe fn destructor(&mut self) {
16+
order_0[(n_1.postfix_inc()) as usize] = 1;
17+
}
18+
}
19+
#[repr(C)]
20+
#[derive(Clone, Default)]
21+
pub struct Member {}
22+
impl Member {
23+
pub unsafe fn destructor(&mut self) {
24+
order_0[(n_1.postfix_inc()) as usize] = 2;
25+
}
26+
}
27+
#[repr(C)]
28+
#[derive(Clone, Default)]
29+
pub struct Derived {
30+
pub base_Base: Base,
31+
pub m: Member,
32+
}
33+
impl Derived {
34+
pub unsafe fn destructor(&mut self) {
35+
order_0[(n_1.postfix_inc()) as usize] = 3;
36+
Member::destructor(&mut self.m);
37+
Base::destructor(&mut self.base_Base);
38+
}
39+
}
40+
#[repr(C)]
41+
#[derive(Clone, Default)]
42+
pub struct Implicit {
43+
pub base_Base: Base,
44+
pub m: Member,
45+
}
46+
impl Implicit {
47+
pub unsafe fn destructor(&mut self) {
48+
Member::destructor(&mut self.m);
49+
Base::destructor(&mut self.base_Base);
50+
}
51+
}
52+
pub fn main() {
53+
unsafe {
54+
std::process::exit(main_0() as i32);
55+
}
56+
}
57+
unsafe fn main_0() -> i32 {
58+
{
59+
let mut d: Derived = <Derived>::default();
60+
let _dtor_d = ScopedDestructorUnsafe::new(&raw mut d, Derived::destructor);
61+
}
62+
assert!(((n_1) == (3)));
63+
assert!(
64+
(((order_0[(0) as usize]) == (3)) && ((order_0[(1) as usize]) == (2)))
65+
&& ((order_0[(2) as usize]) == (1))
66+
);
67+
n_1 = 0;
68+
{
69+
let mut i: Implicit = <Implicit>::default();
70+
let _dtor_i = ScopedDestructorUnsafe::new(&raw mut i, Implicit::destructor);
71+
}
72+
assert!(((n_1) == (2)));
73+
assert!(((order_0[(0) as usize]) == (2)) && ((order_0[(1) as usize]) == (1)));
74+
n_1 = 0;
75+
let mut p: *mut Derived = (Box::leak(Box::new(<Derived>::default())) as *mut Derived);
76+
{
77+
let __p = p;
78+
Derived::destructor(&mut *__p);
79+
::std::mem::drop(Box::from_raw(__p))
80+
};
81+
assert!(((n_1) == (3)));
82+
assert!(
83+
(((order_0[(0) as usize]) == (3)) && ((order_0[(1) as usize]) == (2)))
84+
&& ((order_0[(2) as usize]) == (1))
85+
);
86+
return 0;
87+
}

0 commit comments

Comments
 (0)