From a21d2027e1cba01c3d46bf020b7b1411f6e9d3e4 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Sat, 19 Sep 2026 21:00:38 +0100 Subject: [PATCH] Ignore explicit casts to reference types --- cpp2rust/converter/converter.cpp | 5 +++ tests/unit/out/refcount/refs_as_args.rs | 57 +++++++++++++++++++++++++ tests/unit/out/unsafe/refs_as_args.rs | 30 +++++++++++++ tests/unit/refs_as_args.cpp | 12 ++++++ 4 files changed, 104 insertions(+) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index cf33029e6..b7cb0d64c 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -2520,6 +2520,11 @@ bool Converter::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) { Convert(expr->getSubExpr()); return false; } + // A cast to a reference type only rebinds the operand, it converts nothing + if (type->isReferenceType()) { + Convert(sub_expr); + return false; + } switch (expr->getStmtClass()) { case clang::Stmt::CXXReinterpretCastExprClass: case clang::Stmt::CXXStaticCastExprClass: diff --git a/tests/unit/out/refcount/refs_as_args.rs b/tests/unit/out/refcount/refs_as_args.rs index 1e2b439a8..43edc9a44 100644 --- a/tests/unit/out/refcount/refs_as_args.rs +++ b/tests/unit/out/refcount/refs_as_args.rs @@ -42,6 +42,37 @@ pub fn more_refs_0(x1: i32, x2: i32, r1: Ptr, r2: Ptr) { let __rhs = (rx2.read()); r1.write(__rhs); } +#[derive(Default)] +pub struct Val { + pub x: Value, +} +impl Clone for Val { + fn clone(&self) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + x: Rc::new(RefCell::new((*self.x.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl ByteRepr for Val { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.x.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + x: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +pub fn sum_1(a: Val, b: Val) -> i32 { + let a: Value = Rc::new(RefCell::new(a)); + let b: Value = Rc::new(RefCell::new(b)); + return ((*(*a.borrow()).x.borrow()) + (*(*b.borrow()).x.borrow())); +} pub fn main() { __cpp2rust_init_globals(); std::process::exit(main_0()); @@ -51,6 +82,32 @@ fn main_0() -> i32 { let x2: Value = Rc::new(RefCell::new(2)); ({ more_refs_0(3, 4, x1.as_pointer(), x2.as_pointer()) }); assert!((((*x1.borrow()) + (*x2.borrow())) == 21)); + let v: Value = Rc::new(RefCell::new(Val { + x: Rc::new(RefCell::new(5)), + })); + let acc: Value = Rc::new(RefCell::new( + ({ + let _a: Val = (*v.borrow()).clone(); + let _b: Val = (*v.borrow()).clone(); + sum_1(_a, _b) + }), + )); + (*acc.borrow_mut()) += ({ + let _a: Val = (*v.borrow()).clone(); + let _b: Val = (*v.borrow()).clone(); + sum_1(_a, _b) + }); + (*acc.borrow_mut()) += ({ + let _a: Val = (*v.borrow()).clone(); + let _b: Val = (*v.borrow()).clone(); + sum_1(_a, _b) + }); + (*acc.borrow_mut()) += ({ + let _a: Val = (*v.borrow()).clone(); + let _b: Val = (*v.borrow()).clone(); + sum_1(_a, _b) + }); + assert!(((*acc.borrow()) == 40)); return 0; } pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/refs_as_args.rs b/tests/unit/out/unsafe/refs_as_args.rs index d75586040..0d6d91a1a 100644 --- a/tests/unit/out/unsafe/refs_as_args.rs +++ b/tests/unit/out/unsafe/refs_as_args.rs @@ -17,6 +17,14 @@ pub unsafe fn more_refs_0(mut x1: i32, mut x2: i32, r1: *mut i32, r2: *const i32 (*rx2) += ((((((((1) + (*rx1)) + (*rx2)) + (*pr1)) + (*pr2)) + (*rpr1)) + (*rpr2)) + (*r)); (*r1) = (*rx2); } +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct Val { + pub x: i32, +} +pub unsafe fn sum_1(mut a: Val, mut b: Val) -> i32 { + return ((a.x) + (b.x)); +} pub fn main() { unsafe { __cpp2rust_init_globals(); @@ -28,6 +36,28 @@ unsafe fn main_0() -> i32 { let x2: i32 = 2; (unsafe { more_refs_0(3, 4, &mut x1, &x2) }); assert!((((x1) + (x2)) == (21))); + let mut v: Val = Val { x: 5 }; + let mut acc: i32 = (unsafe { + let _a: Val = v; + let _b: Val = v; + sum_1(_a, _b) + }); + acc += (unsafe { + let _a: Val = v; + let _b: Val = v; + sum_1(_a, _b) + }); + acc += (unsafe { + let _a: Val = v; + let _b: Val = v; + sum_1(_a, _b) + }); + acc += (unsafe { + let _a: Val = v; + let _b: Val = v; + sum_1(_a, _b) + }); + assert!(((acc) == (40))); return 0; } pub unsafe fn __cpp2rust_init_globals() {} diff --git a/tests/unit/refs_as_args.cpp b/tests/unit/refs_as_args.cpp index 065a279b1..b6afd4205 100644 --- a/tests/unit/refs_as_args.cpp +++ b/tests/unit/refs_as_args.cpp @@ -12,10 +12,22 @@ void more_refs(int x1, int x2, int &r1, const int &r2) { r1 = rx2; } +struct Val { + int x; +}; + +static int sum(Val a, Val b) { return a.x + b.x; } + int main() { int x1 = 1; const int x2 = 2; more_refs(3, 4, x1, x2); assert(x1 + x2 == 21); + Val v{5}; + int acc = sum(static_cast(v), v); + acc += sum(static_cast(v), v); + acc += sum(static_cast(v), v); + acc += sum((const Val &)v, v); + assert(acc == 40); return 0; }