From 73a154f7002b4cb9b8845337c271bac820241d9a Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 6 Jul 2026 14:45:22 +0100 Subject: [PATCH] Add void pointer implicit conversion --- .../converter/models/converter_refcount.cpp | 6 ++++ .../refcount/void_ptr_implicit_conversion.rs | 34 +++++++++++++++++++ .../unsafe/void_ptr_implicit_conversion.rs | 29 ++++++++++++++++ tests/unit/void_ptr_implicit_conversion.c | 19 +++++++++++ 4 files changed, 88 insertions(+) create mode 100644 tests/unit/out/refcount/void_ptr_implicit_conversion.rs create mode 100644 tests/unit/out/unsafe/void_ptr_implicit_conversion.rs create mode 100644 tests/unit/void_ptr_implicit_conversion.c diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index c7a2be2b..87d27035 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1160,6 +1160,12 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { ToString(sub_expr->getType()))); } computed_expr_type_ = ComputedExprType::FreshPointer; + } else if (sub_expr->getType()->isVoidPointerType() && + expr->getType()->isPointerType()) { + Convert(sub_expr); + PushConversionKind push(*this, ConversionKind::Unboxed); + StrCat(std::format(".reinterpret_cast::<{}>()", + ConvertPointeeType(expr->getType()))); } else { Convert(sub_expr); } diff --git a/tests/unit/out/refcount/void_ptr_implicit_conversion.rs b/tests/unit/out/refcount/void_ptr_implicit_conversion.rs new file mode 100644 index 00000000..1ddcd67f --- /dev/null +++ b/tests/unit/out/refcount/void_ptr_implicit_conversion.rs @@ -0,0 +1,34 @@ +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 bump_0(arg: AnyPtr) -> i32 { + let arg: Value = Rc::new(RefCell::new(arg)); + let value: Value> = Rc::new(RefCell::new( + ((*arg.borrow()).reinterpret_cast::()).clone(), + )); + { + let _ptr = (*value.borrow()).clone(); + _ptr.write(_ptr.read() + 1) + }; + return ((*value.borrow()).read()); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let value: Value = Rc::new(RefCell::new(41)); + let opaque: Value = Rc::new(RefCell::new(((value.as_pointer()) as Ptr).to_any())); + let typed: Value> = Rc::new(RefCell::new( + ((*opaque.borrow()).reinterpret_cast::()).clone(), + )); + assert!((((({ bump_0((*opaque.borrow()).clone(),) }) == 42) as i32) != 0)); + assert!((((((*typed.borrow()).read()) == 42) as i32) != 0)); + (*typed.borrow()).write(7); + assert!(((((*value.borrow()) == 7) as i32) != 0)); + return 0; +} diff --git a/tests/unit/out/unsafe/void_ptr_implicit_conversion.rs b/tests/unit/out/unsafe/void_ptr_implicit_conversion.rs new file mode 100644 index 00000000..57fadd9c --- /dev/null +++ b/tests/unit/out/unsafe/void_ptr_implicit_conversion.rs @@ -0,0 +1,29 @@ +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 unsafe fn bump_0(mut arg: *mut ::libc::c_void) -> i32 { + let mut value: *mut i32 = (arg as *mut i32); + (*value) += 1; + return (*value); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut value: i32 = 41; + let mut opaque: *mut ::libc::c_void = + ((&mut value as *mut i32) as *mut i32 as *mut ::libc::c_void); + let mut typed: *mut i32 = (opaque as *mut i32); + assert!(((((unsafe { bump_0(opaque,) }) == (42)) as i32) != 0)); + assert!(((((*typed) == (42)) as i32) != 0)); + (*typed) = 7; + assert!(((((value) == (7)) as i32) != 0)); + return 0; +} diff --git a/tests/unit/void_ptr_implicit_conversion.c b/tests/unit/void_ptr_implicit_conversion.c new file mode 100644 index 00000000..2f5c8edd --- /dev/null +++ b/tests/unit/void_ptr_implicit_conversion.c @@ -0,0 +1,19 @@ +#include +#include + +static int32_t bump(void *arg) { + int32_t *value = arg; + *value += 1; + return *value; +} + +int main() { + int32_t value = 41; + void *opaque = &value; + int32_t *typed = opaque; + assert(bump(opaque) == 42); + assert(*typed == 42); + *typed = 7; + assert(value == 7); + return 0; +}