Skip to content

Commit 3f03664

Browse files
Copilotnunoplopes
andauthored
Fix #319: add reinterpret_cast for implicit pointer casts with different Rust types
Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com>
1 parent a6eac06 commit 3f03664

5 files changed

Lines changed: 76 additions & 5 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2257,6 +2257,7 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
22572257
}
22582258
case clang::CastKind::CK_NoOp: {
22592259
const char *suffix = nullptr;
2260+
bool type_changed = false;
22602261
if (expr->getType()->isPointerType() &&
22612262
sub_expr->getType()->isPointerType() &&
22622263
!clang::isa<clang::CXXThisExpr>(expr->IgnoreImplicit())) {
@@ -2269,15 +2270,22 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
22692270
suffix = ".cast_mut()";
22702271
break;
22712272
default:
2273+
type_changed = !IsCastRedundantInRust(sub_expr, type);
22722274
break;
22732275
}
22742276
}
2275-
{
2276-
PushParen paren(*this, suffix);
2277+
if (type_changed) {
2278+
PushParen paren(*this);
22772279
Convert(sub_expr);
2278-
}
2279-
if (suffix) {
2280-
StrCat(suffix);
2280+
ConvertCast(type);
2281+
} else {
2282+
{
2283+
PushParen paren(*this, suffix);
2284+
Convert(sub_expr);
2285+
}
2286+
if (suffix) {
2287+
StrCat(suffix);
2288+
}
22812289
}
22822290
break;
22832291
}

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,15 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
12401240
}
12411241

12421242
if (expr->getCastKind() == clang::CastKind::CK_NoOp) {
1243+
if (expr->getType()->isPointerType() && sub_expr->getType()->isPointerType()) {
1244+
auto dest_type = ConvertPointeeType(expr->getType());
1245+
if (dest_type != ConvertPointeeType(sub_expr->getType())) {
1246+
Convert(sub_expr);
1247+
StrCat(std::format(".reinterpret_cast::<{}>()", dest_type));
1248+
computed_expr_type_ = ComputedExprType::FreshPointer;
1249+
return false;
1250+
}
1251+
}
12431252
Convert(sub_expr);
12441253
return false;
12451254
}

‎tests/unit/implicit_ptr_cast.c‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <assert.h>
2+
#include <stddef.h>
3+
4+
static void write_ulong(unsigned long *p) { *p = 42; }
5+
6+
int main(void) {
7+
size_t x = 0;
8+
write_ulong(&x);
9+
assert(x == 42);
10+
return 0;
11+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
extern crate libcc2rs;
2+
use libcc2rs::*;
3+
use std::cell::RefCell;
4+
use std::collections::BTreeMap;
5+
use std::io::prelude::*;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::AsFd;
8+
use std::rc::{Rc, Weak};
9+
pub fn write_ulong_0(p: Ptr<u64>) {
10+
let p: Value<Ptr<u64>> = Rc::new(RefCell::new(p));
11+
(*p.borrow()).write(42_u64);
12+
}
13+
pub fn main() {
14+
std::process::exit(main_0());
15+
}
16+
fn main_0() -> i32 {
17+
let x: Value<usize> = Rc::new(RefCell::new(0_usize));
18+
({ write_ulong_0((x.as_pointer().reinterpret_cast::<u64>())) });
19+
assert!(((((*x.borrow()) == 42_usize) as i32) != 0));
20+
return 0;
21+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
extern crate libc;
2+
use libc::*;
3+
extern crate libcc2rs;
4+
use libcc2rs::*;
5+
use std::collections::BTreeMap;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
8+
use std::rc::Rc;
9+
pub unsafe fn write_ulong_0(p: *mut u64) {
10+
(*p) = 42_u64;
11+
}
12+
pub fn main() {
13+
unsafe {
14+
std::process::exit(main_0() as i32);
15+
}
16+
}
17+
unsafe fn main_0() -> i32 {
18+
let mut x: usize = 0_usize;
19+
(unsafe { write_ulong_0((&mut x as *mut usize as *mut u64)) });
20+
assert!(((((x) == (42_usize)) as i32) != 0));
21+
return 0;
22+
}

0 commit comments

Comments
 (0)