Skip to content

Commit 738f08d

Browse files
authored
Avoid moves when creating variadic pointer arguments (#233)
1 parent be5eec4 commit 738f08d

5 files changed

Lines changed: 85 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
@@ -1827,7 +1827,13 @@ bool ConverterRefCount::VisitImplicitValueInitExpr(
18271827
return Converter::VisitImplicitValueInitExpr(expr);
18281828
}
18291829

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

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

tests/unit/out/refcount/va_arg_non_primitive_ptrs.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,12 @@ fn main_0() -> i32 {
109109
);
110110
assert!((((!((*s.borrow()).is_null())) as i32) != 0));
111111
assert!(
112-
(((({ dispatch_0((opt::OPT_FILE as i32), &[(libcc2rs::cout()).into(),]) }) == 1) as i32)
112+
(((({
113+
dispatch_0(
114+
(opt::OPT_FILE as i32),
115+
&[((libcc2rs::cout()).clone()).into()],
116+
)
117+
}) == 1) as i32)
113118
!= 0)
114119
);
115120
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)