Skip to content

Commit eeea213

Browse files
committed
Fix void cast for pointer dereference
1 parent 1ac73cc commit eeea213

4 files changed

Lines changed: 94 additions & 30 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,6 +1924,8 @@ bool Converter::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
19241924
auto type = expr->getTypeAsWritten();
19251925
auto *sub_expr = expr->getSubExpr();
19261926
if (type->isVoidType()) {
1927+
StrCat(token::kRef);
1928+
PushParen paren(*this);
19271929
PushExprKind push(*this, ExprKind::Void);
19281930
Convert(expr->getSubExpr());
19291931
return false;

tests/unit/out/refcount/void_cast.rs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,30 @@ pub fn unused_param_0(x: i32) {
1010
let x: Value<i32> = Rc::new(RefCell::new(x));
1111
(*x.borrow_mut());
1212
}
13+
#[derive(Default)]
14+
pub struct NonTrivial {
15+
pub data: Value<Vec<i32>>,
16+
}
17+
impl Clone for NonTrivial {
18+
fn clone(&self) -> Self {
19+
let mut this = Self {
20+
data: Rc::new(RefCell::new((*self.data.borrow()).clone())),
21+
};
22+
this
23+
}
24+
}
25+
impl ByteRepr for NonTrivial {}
26+
pub fn unused_ref_param_1(x: Ptr<NonTrivial>) {
27+
(*x.upgrade().deref()).clone();
28+
}
29+
pub fn unused_ptr_param_2(p: Ptr<NonTrivial>) {
30+
let p: Value<Ptr<NonTrivial>> = Rc::new(RefCell::new(p));
31+
(*(*p.borrow()).upgrade().deref()).clone();
32+
}
1333
thread_local!(
1434
pub static side_effect_counter: Value<i32> = Rc::new(RefCell::new(0));
1535
);
16-
pub fn bump_and_return_1() -> i32 {
36+
pub fn bump_and_return_3() -> i32 {
1737
(*side_effect_counter.with(Value::clone).borrow_mut()).prefix_inc();
1838
return (*side_effect_counter.with(Value::clone).borrow());
1939
}
@@ -53,10 +73,10 @@ fn main_0() -> i32 {
5373
}));
5474
assert!(((*w.borrow()) == 3));
5575
assert!(((*counter.borrow()) == 3));
56-
({ bump_and_return_1() });
76+
({ bump_and_return_3() });
5777
assert!(((*side_effect_counter.with(Value::clone).borrow()) == 1));
5878
let v: Value<i32> = Rc::new(RefCell::new({
59-
({ bump_and_return_1() });
79+
({ bump_and_return_3() });
6080
99
6181
}));
6282
assert!(((*side_effect_counter.with(Value::clone).borrow()) == 2));
@@ -75,11 +95,11 @@ fn main_0() -> i32 {
7595
}));
7696
assert!(((*err.borrow()) == 7));
7797
assert!(((*chosen.borrow()) == 123));
78-
bump_and_return_1;
98+
bump_and_return_3;
7999
assert!(((*side_effect_counter.with(Value::clone).borrow()) == 2));
80-
(FnPtr::<fn() -> i32>::new(bump_and_return_1));
100+
(FnPtr::<fn() -> i32>::new(bump_and_return_3));
81101
assert!(((*side_effect_counter.with(Value::clone).borrow()) == 2));
82-
((FnPtr::<fn() -> i32>::new(bump_and_return_1)).cast::<fn() -> i32>(None));
102+
((FnPtr::<fn() -> i32>::new(bump_and_return_3)).cast::<fn() -> i32>(None));
83103
assert!(((*side_effect_counter.with(Value::clone).borrow()) == 2));
84104
let storage: Value<i32> = Rc::new(RefCell::new(11));
85105
let p: Value<Ptr<i32>> = Rc::new(RefCell::new((storage.as_pointer())));
@@ -93,5 +113,14 @@ fn main_0() -> i32 {
93113
(*(*h.borrow()).field.borrow_mut());
94114
let hp: Value<Ptr<Holder>> = Rc::new(RefCell::new((h.as_pointer())));
95115
(*(*(*hp.borrow()).upgrade().deref()).field.borrow_mut());
116+
let nt: Value<NonTrivial> = Rc::new(RefCell::new(<NonTrivial>::default()));
117+
({
118+
let _x: Ptr<NonTrivial> = nt.as_pointer();
119+
unused_ref_param_1(_x)
120+
});
121+
({
122+
let _p: Ptr<NonTrivial> = (nt.as_pointer());
123+
unused_ptr_param_2(_p)
124+
});
96125
return 0;
97126
}

tests/unit/out/unsafe/void_cast.rs

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,21 @@ use std::io::{Read, Seek, Write};
77
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
88
use std::rc::Rc;
99
pub unsafe fn unused_param_0(mut x: i32) {
10-
x;
10+
&(x);
1111
}
12-
pub static mut side_effect_counter: i32 = 0;
13-
pub unsafe fn bump_and_return_1() -> i32 {
12+
#[repr(C)]
13+
#[derive(Clone, Default)]
14+
pub struct NonTrivial {
15+
pub data: Vec<i32>,
16+
}
17+
pub unsafe fn unused_ref_param_1(x: *const NonTrivial) {
18+
&(*x);
19+
}
20+
pub unsafe fn unused_ptr_param_2(mut p: *const NonTrivial) {
21+
&(*p);
22+
}
23+
pub static mut side_effect_counter: i32 = unsafe { 0 };
24+
pub unsafe fn bump_and_return_3() -> i32 {
1425
side_effect_counter.prefix_inc();
1526
return side_effect_counter;
1627
}
@@ -30,59 +41,68 @@ unsafe fn main_0() -> i32 {
3041
unused_param_0(_x)
3142
});
3243
let mut y: i32 = 5;
33-
y;
44+
&(y);
3445
let mut z: i32 = {
35-
y;
46+
&(y);
3647
7
3748
};
3849
assert!(((z) == (7)));
3950
let mut counter: i32 = 0;
4051
let mut w: i32 = {
41-
counter;
52+
&(counter);
4253
counter = 3;
4354
counter
4455
};
4556
assert!(((w) == (3)));
4657
assert!(((counter) == (3)));
47-
(unsafe { bump_and_return_1() });
58+
&(unsafe { bump_and_return_3() });
4859
assert!(((side_effect_counter) == (1)));
4960
let mut v: i32 = {
50-
(unsafe { bump_and_return_1() });
61+
&(unsafe { bump_and_return_3() });
5162
99
5263
};
5364
assert!(((side_effect_counter) == (2)));
5465
assert!(((v) == (99)));
55-
0;
56-
(0);
57-
(y);
58-
(0);
59-
(y);
66+
&(0);
67+
&(0);
68+
&(y);
69+
(&(0));
70+
(&(y));
6071
let mut err: i32 = 0;
61-
(err = 42);
72+
(&(err = 42));
6273
assert!(((err) == (42)));
6374
let mut chosen: i32 = {
64-
(err = 7);
75+
&(err = 7);
6576
123
6677
};
6778
assert!(((err) == (7)));
6879
assert!(((chosen) == (123)));
69-
bump_and_return_1;
80+
&(bump_and_return_3);
7081
assert!(((side_effect_counter) == (2)));
71-
(Some(bump_and_return_1));
82+
&(Some(bump_and_return_3));
7283
assert!(((side_effect_counter) == (2)));
73-
(std::mem::transmute::<Option<unsafe fn() -> i32>, Option<unsafe fn() -> i32>>(
74-
(Some(bump_and_return_1)),
84+
&(std::mem::transmute::<Option<unsafe fn() -> i32>, Option<unsafe fn() -> i32>>(
85+
(Some(bump_and_return_3)),
7586
));
7687
assert!(((side_effect_counter) == (2)));
7788
let mut storage: i32 = 11;
7889
let mut p: *mut i32 = (&mut storage as *mut i32);
79-
(*p);
80-
(p);
90+
&(*p);
91+
&(p);
8192
let mut arr: [i32; 3] = [1, 2, 3];
82-
(arr[(1) as usize]);
93+
&(arr[(1) as usize]);
8394
let mut h: Holder = Holder { field: 17 };
84-
(h.field);
95+
&(h.field);
8596
let mut hp: *mut Holder = (&mut h as *mut Holder);
86-
((*hp).field);
97+
&((*hp).field);
98+
let mut nt: NonTrivial = <NonTrivial>::default();
99+
(unsafe {
100+
let _x: *const NonTrivial = &nt as *const NonTrivial;
101+
unused_ref_param_1(_x)
102+
});
103+
(unsafe {
104+
let _p: *const NonTrivial = (&mut nt as *mut NonTrivial).cast_const();
105+
unused_ptr_param_2(_p)
106+
});
87107
return 0;
88108
}

tests/unit/void_cast.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
#include <cassert>
2+
#include <vector>
23

34
void unused_param(int x) { (void)x; }
45

6+
struct NonTrivial {
7+
std::vector<int> data;
8+
};
9+
10+
void unused_ref_param(const NonTrivial &x) { (void)x; }
11+
12+
void unused_ptr_param(const NonTrivial *p) { (void)(*p); }
13+
514
int side_effect_counter = 0;
615
int bump_and_return() {
716
++side_effect_counter;
@@ -71,5 +80,9 @@ int main() {
7180
Holder *hp = &h;
7281
(void)(hp->field);
7382

83+
NonTrivial nt;
84+
unused_ref_param(nt);
85+
unused_ptr_param(&nt);
86+
7487
return 0;
7588
}

0 commit comments

Comments
 (0)