Skip to content

Commit d76fccc

Browse files
committed
Avoid moves when creating variadic pointer arguments
1 parent 22edd84 commit d76fccc

5 files changed

Lines changed: 93 additions & 2 deletions

File tree

cpp2rust/converter/models/converter_refcount.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1825,7 +1825,13 @@ bool ConverterRefCount::VisitImplicitValueInitExpr(
18251825
return Converter::VisitImplicitValueInitExpr(expr);
18261826
}
18271827

1828-
void ConverterRefCount::ConvertVariadicArg(clang::Expr *arg) { Convert(arg); }
1828+
void ConverterRefCount::ConvertVariadicArg(clang::Expr *arg) {
1829+
if (arg->getType()->isPointerType()) {
1830+
StrCat(ConvertFreshPointer(arg));
1831+
return;
1832+
}
1833+
Convert(arg);
1834+
}
18291835

18301836
bool ConverterRefCount::VisitVAArgExpr(clang::VAArgExpr *expr) {
18311837
auto va_list_expr = expr->getSubExpr();

tests/unit/out/refcount/va_arg_non_primitive_ptrs.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ pub struct node {
1111
pub data: Value<i32>,
1212
pub next: Value<Ptr<node>>,
1313
}
14+
impl Clone for node {
15+
fn clone(&self) -> Self {
16+
Self {
17+
data: Rc::new(RefCell::new((*self.data.borrow()).clone())),
18+
next: Rc::new(RefCell::new((*self.next.borrow()).clone())),
19+
}
20+
}
21+
}
1422
impl ByteRepr for node {
1523
fn byte_size() -> usize {
1624
16
@@ -109,7 +117,12 @@ fn main_0() -> i32 {
109117
);
110118
assert!((((!((*s.borrow()).is_null())) as i32) != 0));
111119
assert!(
112-
(((({ dispatch_0((opt::OPT_FILE as i32), &[(libcc2rs::cout()).into(),]) }) == 1) as i32)
120+
(((({
121+
dispatch_0(
122+
(opt::OPT_FILE as i32),
123+
&[((libcc2rs::cout()).clone()).into()],
124+
)
125+
}) == 1) as i32)
113126
!= 0)
114127
);
115128
assert!(

tests/unit/out/refcount/va_arg_printf.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ pub fn logf_1(fmt: Ptr<u8>, __args: &[VaArg]) -> i32 {
2424
));
2525
return (*result.borrow());
2626
}
27+
pub fn lenf_2(fmt: Ptr<u8>, __args: &[VaArg]) -> i32 {
28+
let fmt: Value<Ptr<u8>> = Rc::new(RefCell::new(fmt));
29+
let ap: Value<VaList> = Rc::new(RefCell::new(VaList::default()));
30+
(*ap.borrow_mut()) = VaList::new(__args);
31+
let s: Value<Ptr<u8>> = Rc::new(RefCell::new(((*ap.borrow_mut()).arg::<Ptr<u8>>()).clone()));
32+
let result: Value<i32> = Rc::new(RefCell::new(
33+
((*s.borrow()).to_string_iterator().count() as i32),
34+
));
35+
return (*result.borrow());
36+
}
2737
pub fn main() {
2838
std::process::exit(main_0());
2939
}
@@ -50,5 +60,30 @@ fn main_0() -> i32 {
5060
}) == 3) as i32)
5161
!= 0)
5262
);
63+
assert!(
64+
(((({
65+
lenf_2(
66+
Ptr::from_string_literal(b"%s"),
67+
&[((*dummy.borrow()).clone()).into()],
68+
)
69+
}) == 5) as i32)
70+
!= 0)
71+
);
72+
assert!(
73+
(((({
74+
lenf_2(
75+
Ptr::from_string_literal(b"%s"),
76+
&[
77+
(if ((((*dummy.borrow()).offset((0) as isize).read()) as i32) != 0) {
78+
(*dummy.borrow()).clone()
79+
} else {
80+
Ptr::from_string_literal(b"")
81+
})
82+
.into(),
83+
],
84+
)
85+
}) == 5) as i32)
86+
!= 0)
87+
);
5388
return 0;
5489
}

tests/unit/out/unsafe/va_arg_printf.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ pub unsafe fn logf_1(mut fmt: *const libc::c_char, __args: &[VaArg]) -> i32 {
1616
let mut result: i32 = (unsafe { logf_impl_0(fmt, ap) });
1717
return result;
1818
}
19+
pub unsafe fn lenf_2(mut fmt: *const libc::c_char, __args: &[VaArg]) -> i32 {
20+
let mut ap: VaList = VaList::default();
21+
ap = VaList::new(__args);
22+
let mut s: *const libc::c_char = ap.arg::<*const libc::c_char>();
23+
let mut result: i32 = (libc::strlen(s) as i32);
24+
return result;
25+
}
1926
pub fn main() {
2027
unsafe {
2128
std::process::exit(main_0() as i32);
@@ -41,5 +48,24 @@ unsafe fn main_0() -> i32 {
4148
}) == (3)) as i32)
4249
!= 0)
4350
);
51+
assert!(
52+
((((unsafe { lenf_2((c"%s".as_ptr().cast_mut()).cast_const(), &[(dummy).into(),]) }) == (5))
53+
as i32)
54+
!= 0)
55+
);
56+
assert!(
57+
((((unsafe {
58+
lenf_2(
59+
(c"%s".as_ptr().cast_mut()).cast_const(),
60+
&[(if (((*dummy.offset((0) as isize)) as i32) != 0) {
61+
dummy
62+
} else {
63+
(c"".as_ptr().cast_mut() as *const libc::c_char)
64+
})
65+
.into()],
66+
)
67+
}) == (5)) as i32)
68+
!= 0)
69+
);
4470
return 0;
4571
}

tests/unit/va_arg_printf.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,20 @@ int logf(const char *fmt, ...) {
1515
return result;
1616
}
1717

18+
int lenf(const char *fmt, ...) {
19+
va_list ap;
20+
va_start(ap, fmt);
21+
const char *s = va_arg(ap, const char *);
22+
int result = (int)strlen(s);
23+
va_end(ap);
24+
return result;
25+
}
26+
1827
int main() {
1928
const char *dummy = "dummy";
2029
assert(logf("hello %d %d", 10, strlen(dummy)) == 15);
2130
assert(logf("x %d %d", 1, 2) == 3);
31+
assert(lenf("%s", dummy) == 5);
32+
assert(lenf("%s", dummy[0] ? dummy : "") == 5);
2233
return 0;
2334
}

0 commit comments

Comments
 (0)