diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index f80398de..044bd580 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -203,7 +203,7 @@ std::string ConverterRefCount::BuildFnAdapter( closure += std::format("a{}", i); } else if (src_pty->isPointerType() && tgt_pty->isPointerType()) { if (tgt_pty->isVoidPointerType()) { - closure += std::format("a{}.cast::<{}>().unwrap()", i, + closure += std::format("a{}.reinterpret_cast::<{}>()", i, ConvertPointeeType(src_pty)); } else if (src_pty->isVoidPointerType()) { closure += std::format("a{}.to_any()", i); @@ -1301,7 +1301,7 @@ bool ConverterRefCount::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) { expr->getType()->isPointerType()) { Convert(expr->getSubExpr()); PushConversionKind push(*this, ConversionKind::Unboxed); - StrCat(std::format(".cast::<{}>().expect(\"ub:wrong type\")", + StrCat(std::format(".reinterpret_cast::<{}>()", ConvertPointeeType(expr->getType()))); return false; } else if (expr->getType()->isVoidPointerType() && diff --git a/libcc2rs/src/io.rs b/libcc2rs/src/io.rs index 3073f369..02389447 100644 --- a/libcc2rs/src/io.rs +++ b/libcc2rs/src/io.rs @@ -86,10 +86,7 @@ pub unsafe fn cerr_unsafe() -> *mut std::fs::File { pub fn fread_refcount(a0: AnyPtr, a1: usize, a2: usize, a3: Ptr<::std::fs::File>) -> usize { let total = a1.saturating_mul(a2); - let mut dst = a0 - .cast::() - .expect("fread: only supporting u8 pointers") - .clone(); + let mut dst = a0.reinterpret_cast::(); let f = (*a3.upgrade().deref()) .try_clone() @@ -123,10 +120,7 @@ pub fn fread_refcount(a0: AnyPtr, a1: usize, a2: usize, a3: Ptr<::std::fs::File> pub fn fwrite_refcount(a0: AnyPtr, a1: usize, a2: usize, a3: Ptr<::std::fs::File>) -> usize { let total = a1.saturating_mul(a2); - let mut src = a0 - .cast::() - .expect("fwrite: only supporting u8 pointers") - .clone(); + let mut src = a0.reinterpret_cast::(); let f = (*a3.upgrade().deref()) .try_clone() diff --git a/libcc2rs/src/rc.rs b/libcc2rs/src/rc.rs index 8155d0cf..f13be101 100644 --- a/libcc2rs/src/rc.rs +++ b/libcc2rs/src/rc.rs @@ -1100,11 +1100,14 @@ impl Default for AnyPtr { } impl AnyPtr { - pub fn cast(&self) -> Option> { + pub fn reinterpret_cast(&self) -> Ptr { if self.ptr.is_null() { - return Some(Ptr::::null()); + return Ptr::::null(); } - self.ptr.as_any().downcast_ref::>().cloned() + if let Some(p) = self.ptr.as_any().downcast_ref::>() { + return p.clone(); + } + self.ptr.as_bytes().reinterpret_cast::() } } @@ -1265,27 +1268,23 @@ mod tests { fn anyptr_null_cast() { // void* nullptr let any = Ptr::<()>::null().to_any(); - let p: Option> = any.cast::(); - assert!(p.is_some()); - assert!(p.unwrap().is_null()); + let p = any.reinterpret_cast::(); + assert!(p.is_null()); - let p2: Option> = any.cast::(); - assert!(p2.is_some()); - assert!(p2.unwrap().is_null()); + let p2 = any.reinterpret_cast::(); + assert!(p2.is_null()); // int* nullptr let any2 = Ptr::::null().to_any(); - let p3: Option> = any2.cast::(); - assert!(p3.is_some()); - assert!(p3.unwrap().is_null()); + let p3 = any2.reinterpret_cast::(); + assert!(p3.is_null()); } #[test] fn to_any_without_clone() { let p: Ptr = Ptr::null(); // std::fs::File is not Clone let any = p.to_any(); - let recovered = any.cast::(); - assert!(recovered.is_some()); - assert!(recovered.unwrap().is_null()); + let recovered = any.reinterpret_cast::(); + assert!(recovered.is_null()); } } diff --git a/libcc2rs/src/va_args.rs b/libcc2rs/src/va_args.rs index 6adfaad5..9a4606f2 100644 --- a/libcc2rs/src/va_args.rs +++ b/libcc2rs/src/va_args.rs @@ -119,10 +119,10 @@ impl VaArgGet for *const T { } } -impl VaArgGet for crate::rc::Ptr { +impl VaArgGet for crate::rc::Ptr { fn get(v: &VaArg) -> Self { match v { - VaArg::Ptr(any) => any.cast::().expect("VaArgGet: Ptr type mismatch"), + VaArg::Ptr(any) => any.reinterpret_cast::(), _ => panic!("VaArgGet: expected Ptr"), } } diff --git a/tests/unit/out/refcount/fn_ptr.rs b/tests/unit/out/refcount/fn_ptr.rs index 3e73daab..8eff0e2d 100644 --- a/tests/unit/out/refcount/fn_ptr.rs +++ b/tests/unit/out/refcount/fn_ptr.rs @@ -8,7 +8,7 @@ use std::os::fd::AsFd; use std::rc::{Rc, Weak}; pub fn my_foo_0(p: AnyPtr) -> i32 { let p: Value = Rc::new(RefCell::new(p)); - return ((*p.borrow()).cast::().expect("ub:wrong type").read()); + return ((*p.borrow()).reinterpret_cast::().read()); } pub fn foo_1(fn_: FnPtr i32>, pi: Ptr) -> i32 { let fn_: Value i32>> = Rc::new(RefCell::new(fn_)); diff --git a/tests/unit/out/refcount/fn_ptr_cast.rs b/tests/unit/out/refcount/fn_ptr_cast.rs index e6b78b22..c609f6fc 100644 --- a/tests/unit/out/refcount/fn_ptr_cast.rs +++ b/tests/unit/out/refcount/fn_ptr_cast.rs @@ -88,7 +88,7 @@ pub fn add_offset_4(base: Ptr, offset: i32) -> i32 { pub fn test_call_through_cast_5() { let gfn: Value i32>> = Rc::new(RefCell::new( FnPtr::, i32) -> i32>::new(add_offset_4).cast:: i32>(Some( - (|a0: AnyPtr, a1: i32| -> i32 { add_offset_4(a0.cast::().unwrap(), a1) }) + (|a0: AnyPtr, a1: i32| -> i32 { add_offset_4(a0.reinterpret_cast::(), a1) }) as fn(AnyPtr, i32) -> i32, )), )); diff --git a/tests/unit/out/refcount/fn_ptr_stdlib_compare.rs b/tests/unit/out/refcount/fn_ptr_stdlib_compare.rs index 0c19f591..96ed54c2 100644 --- a/tests/unit/out/refcount/fn_ptr_stdlib_compare.rs +++ b/tests/unit/out/refcount/fn_ptr_stdlib_compare.rs @@ -41,7 +41,12 @@ fn main_0() -> i32 { ) .cast::, usize, usize, AnyPtr) -> usize>(Some( (|a0: Ptr, a1: usize, a2: usize, a3: AnyPtr| -> usize { - libcc2rs::fread_refcount(a0.to_any(), a1, a2, a3.cast::<::std::fs::File>().unwrap()) + libcc2rs::fread_refcount( + a0.to_any(), + a1, + a2, + a3.reinterpret_cast::<::std::fs::File>(), + ) }) as fn(Ptr, usize, usize, AnyPtr) -> usize, )), )); @@ -56,7 +61,7 @@ fn main_0() -> i32 { FnPtr::, usize, usize, AnyPtr) -> usize>::new(my_alternative_fread_0) .cast::) -> usize>(Some( (|a0: AnyPtr, a1: usize, a2: usize, a3: Ptr<::std::fs::File>| -> usize { - my_alternative_fread_0(a0.cast::().unwrap(), a1, a2, a3.to_any()) + my_alternative_fread_0(a0.reinterpret_cast::(), a1, a2, a3.to_any()) }) as fn(AnyPtr, usize, usize, Ptr<::std::fs::File>) -> usize, )), )); @@ -195,7 +200,7 @@ fn main_0() -> i32 { a0.to_any(), a1, a2, - a3.cast::<::std::fs::File>().unwrap(), + a3.reinterpret_cast::<::std::fs::File>(), ) }) as fn(Ptr, usize, usize, AnyPtr) -> usize, )), @@ -211,7 +216,7 @@ fn main_0() -> i32 { FnPtr::, usize, usize, AnyPtr) -> usize>::new(my_alternative_fwrite_1) .cast::) -> usize>(Some( (|a0: AnyPtr, a1: usize, a2: usize, a3: Ptr<::std::fs::File>| -> usize { - my_alternative_fwrite_1(a0.cast::().unwrap(), a1, a2, a3.to_any()) + my_alternative_fwrite_1(a0.reinterpret_cast::(), a1, a2, a3.to_any()) }) as fn(AnyPtr, usize, usize, Ptr<::std::fs::File>) -> usize, )), )); diff --git a/tests/unit/out/refcount/fn_ptr_vtable.rs b/tests/unit/out/refcount/fn_ptr_vtable.rs index b8a8d10a..20a17cb9 100644 --- a/tests/unit/out/refcount/fn_ptr_vtable.rs +++ b/tests/unit/out/refcount/fn_ptr_vtable.rs @@ -62,11 +62,11 @@ pub fn int_create_1(val: i32) -> AnyPtr { } pub fn int_get_2(p: AnyPtr) -> i32 { let p: Value = Rc::new(RefCell::new(p)); - return ((*p.borrow()).cast::().expect("ub:wrong type").read()); + return ((*p.borrow()).reinterpret_cast::().read()); } pub fn int_destroy_3(p: AnyPtr) { let p: Value = Rc::new(RefCell::new(p)); - (*p.borrow()).cast::().expect("ub:wrong type").write(0); + (*p.borrow()).reinterpret_cast::().write(0); } pub fn main() { std::process::exit(main_0()); diff --git a/tests/unit/out/refcount/ptr_to_incomplete_struct.rs b/tests/unit/out/refcount/ptr_to_incomplete_struct.rs index 2c4cf29e..853df2c8 100644 --- a/tests/unit/out/refcount/ptr_to_incomplete_struct.rs +++ b/tests/unit/out/refcount/ptr_to_incomplete_struct.rs @@ -13,10 +13,7 @@ fn main_0() -> i32 { let fp: Value> = Rc::new(RefCell::new((libcc2rs::cout()).clone())); let p: Value = Rc::new(RefCell::new((*fp.borrow()).clone().to_any())); let fp2: Value> = Rc::new(RefCell::new( - ((*p.borrow()) - .cast::<::std::fs::File>() - .expect("ub:wrong type")) - .clone(), + ((*p.borrow()).reinterpret_cast::<::std::fs::File>()).clone(), )); assert!( ((({ diff --git a/tests/unit/out/refcount/union_cross_arm_cast.rs b/tests/unit/out/refcount/union_cross_arm_cast.rs index ee56415e..e14b8762 100644 --- a/tests/unit/out/refcount/union_cross_arm_cast.rs +++ b/tests/unit/out/refcount/union_cross_arm_cast.rs @@ -157,8 +157,7 @@ fn main_0() -> i32 { (*(*(((*(*c.borrow()).u.borrow()).a()) .clone() .to_any() - .cast::() - .expect("ub:wrong type")) + .reinterpret_cast::()) .upgrade() .deref()) .tail diff --git a/tests/unit/out/refcount/union_void_ptr_sized_deref.rs b/tests/unit/out/refcount/union_void_ptr_sized_deref.rs index a1c6b80d..80a09a34 100644 --- a/tests/unit/out/refcount/union_void_ptr_sized_deref.rs +++ b/tests/unit/out/refcount/union_void_ptr_sized_deref.rs @@ -106,8 +106,7 @@ pub fn write_count_1(s: Ptr, count: i64) { ((*(*(*s.borrow()).upgrade().deref()).out.borrow()) .handle() .read()) - .cast::() - .expect("ub:wrong type") + .reinterpret_cast::() .write((*count.borrow())); break 'switch; } @@ -115,8 +114,7 @@ pub fn write_count_1(s: Ptr, count: i64) { ((*(*(*s.borrow()).upgrade().deref()).out.borrow()) .handle() .read()) - .cast::() - .expect("ub:wrong type") + .reinterpret_cast::() .write(((*count.borrow()) as i32)); break 'switch; } @@ -124,8 +122,7 @@ pub fn write_count_1(s: Ptr, count: i64) { ((*(*(*s.borrow()).upgrade().deref()).out.borrow()) .handle() .read()) - .cast::() - .expect("ub:wrong type") + .reinterpret_cast::() .write(((*count.borrow()) as i16)); break 'switch; } diff --git a/tests/unit/out/refcount/va_arg_non_primitive_ptrs.rs b/tests/unit/out/refcount/va_arg_non_primitive_ptrs.rs index 46429329..836ccef8 100644 --- a/tests/unit/out/refcount/va_arg_non_primitive_ptrs.rs +++ b/tests/unit/out/refcount/va_arg_non_primitive_ptrs.rs @@ -116,10 +116,7 @@ fn main_0() -> i32 { (((({ dispatch_0( (opt::OPT_FILE as i32), - &[((AnyPtr::default()) - .cast::<::std::fs::File>() - .expect("ub:wrong type")) - .into()], + &[((AnyPtr::default()).reinterpret_cast::<::std::fs::File>()).into()], ) }) == 0) as i32) != 0) diff --git a/tests/unit/out/refcount/void_round_trip.rs b/tests/unit/out/refcount/void_round_trip.rs new file mode 100644 index 00000000..b9cfec3c --- /dev/null +++ b/tests/unit/out/refcount/void_round_trip.rs @@ -0,0 +1,16 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let a: Value = Rc::new(RefCell::new(42_u32)); + assert!((((((a.as_pointer()).to_any().reinterpret_cast::().read()) == 42) as i32) != 0)); + return 0; +} diff --git a/tests/unit/out/refcount/z_bit_cast.rs b/tests/unit/out/refcount/z_bit_cast.rs index 7b942e03..c627013a 100644 --- a/tests/unit/out/refcount/z_bit_cast.rs +++ b/tests/unit/out/refcount/z_bit_cast.rs @@ -30,7 +30,7 @@ fn main_0() -> i32 { _lhs == ((a1.as_pointer() as Ptr) as Ptr).to_any() }); assert!({ - let _lhs = (((*ptr.borrow()).cast::().expect("ub:wrong type")) + let _lhs = (((*ptr.borrow()).reinterpret_cast::()) .offset((0) as isize) .read()); _lhs == (*a1.borrow())[(0) as usize] diff --git a/tests/unit/out/unsafe/void_round_trip.rs b/tests/unit/out/unsafe/void_round_trip.rs new file mode 100644 index 00000000..f4e99e2d --- /dev/null +++ b/tests/unit/out/unsafe/void_round_trip.rs @@ -0,0 +1,20 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut a: u32 = 42_u32; + assert!( + ((((*(((&mut a as *mut u32) as *mut ::libc::c_void) as *mut i32)) == (42)) as i32) != 0) + ); + return 0; +} diff --git a/tests/unit/void_round_trip.c b/tests/unit/void_round_trip.c new file mode 100644 index 00000000..01b4ba98 --- /dev/null +++ b/tests/unit/void_round_trip.c @@ -0,0 +1,8 @@ +#include +#include + +int main() { + uint32_t a = 42; + assert(*(int32_t *)(void *)&a == 42); + return 0; +}