From 26279375a761ca3c453913f3abd75551d574e8c4 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 9 Oct 2026 13:51:16 +0100 Subject: [PATCH 1/2] Fix delete for const pointer --- cpp2rust/converter/converter.cpp | 5 +++-- tests/unit/05_new.cpp | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index b63c7fcb3..ed081f014 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -3748,8 +3748,9 @@ void Converter::EmitDeallocation(clang::CXXDeleteExpr *expr, argument_as_string, argument_as_string, destroyed_type_as_string)); } } else { - StrCat( - std::format("::std::mem::drop(Box::from_raw({}))", argument_as_string)); + bool cast_mut = !IsMut(expr->getDestroyedType()); + StrCat(std::format("::std::mem::drop(Box::from_raw({}{}))", + argument_as_string, cast_mut ? ".cast_mut()" : "")); } } diff --git a/tests/unit/05_new.cpp b/tests/unit/05_new.cpp index b39f9d911..903edf4f8 100644 --- a/tests/unit/05_new.cpp +++ b/tests/unit/05_new.cpp @@ -1,6 +1,15 @@ +struct A {}; + +struct D { + void operator()(const A *ptr) const { delete ptr; } +}; + int main() { int *d = new int(0); *d = 5; delete d; + const int *c = new int(3); + delete c; + D{}(new A); return 0; } From 58876b9fb827dd1bf09e9c94dd3be776a5b2e643 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 9 Oct 2026 19:06:20 +0100 Subject: [PATCH 2/2] Update tests --- tests/unit/out/refcount/05_new.rs | 22 ++++++++++++++++++++++ tests/unit/out/unsafe/05_new.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/tests/unit/out/refcount/05_new.rs b/tests/unit/out/refcount/05_new.rs index 349a89832..058936c70 100644 --- a/tests/unit/out/refcount/05_new.rs +++ b/tests/unit/out/refcount/05_new.rs @@ -6,6 +6,12 @@ use std::io::prelude::*; use std::io::{Read, Seek, Write}; use std::os::fd::AsFd; use std::rc::{Rc, Weak}; +#[derive(Clone, Record, ByteRepr, VaArg, FnPtrArg, Default)] +#[byte_size(1)] +pub struct A {} +#[derive(Clone, Record, ByteRepr, VaArg, FnPtrArg, Default)] +#[byte_size(1)] +pub struct D {} pub fn main() { __cpp2rust_init_globals(); std::process::exit(main_0()); @@ -14,6 +20,22 @@ fn main_0() -> i32 { let mut d: Ptr = Ptr::alloc(0); d.write(5); d.delete(); + let mut c: Ptr = Ptr::alloc(3); + c.delete(); + ({ + DImpl::operator_call( + &Rc::new(RefCell::new(::default())).as_pointer(), + Ptr::alloc(::default()), + ) + }); return 0; } +pub trait DImpl { + fn operator_call(&self, ptr: Ptr); +} +impl DImpl for Ptr { + fn operator_call(&self, mut ptr: Ptr) { + ptr.delete(); + } +} pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/05_new.rs b/tests/unit/out/unsafe/05_new.rs index c28809897..5df21a1f4 100644 --- a/tests/unit/out/unsafe/05_new.rs +++ b/tests/unit/out/unsafe/05_new.rs @@ -6,6 +6,22 @@ use std::collections::BTreeMap; use std::io::{Read, Seek, Write}; use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; +#[repr(C)] +#[derive(Copy, Clone, VaArg, FnPtrArg, Default)] +pub struct A {} +#[repr(C)] +#[derive(Copy, Clone, VaArg, FnPtrArg, Default)] +pub struct D {} +impl D { + pub unsafe fn operator_call(&self, mut ptr: *const A) { + { + let __p = ptr; + if !__p.is_null() { + ::std::mem::drop(Box::from_raw(__p.cast_mut())) + } + }; + } +} pub fn main() { unsafe { __cpp2rust_init_globals(); @@ -21,6 +37,19 @@ unsafe fn main_0() -> i32 { ::std::mem::drop(Box::from_raw(__p)) } }; + let mut c: *const i32 = (Box::leak(Box::new(3)) as *mut i32).cast_const(); + { + let __p = c; + if !__p.is_null() { + ::std::mem::drop(Box::from_raw(__p.cast_mut())) + } + }; + (unsafe { + D::operator_call( + &::default(), + (Box::leak(Box::new(::default())) as *mut A).cast_const(), + ) + }); return 0; } pub unsafe fn __cpp2rust_init_globals() {}