Skip to content

Commit a5f6b22

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 f532aa4 commit a5f6b22

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
@@ -2165,6 +2165,7 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
21652165
}
21662166
case clang::CastKind::CK_NoOp: {
21672167
const char *suffix = nullptr;
2168+
bool type_changed = false;
21682169
if (expr->getType()->isPointerType() &&
21692170
sub_expr->getType()->isPointerType() &&
21702171
!clang::isa<clang::CXXThisExpr>(expr->IgnoreImplicit())) {
@@ -2177,15 +2178,22 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
21772178
suffix = ".cast_mut()";
21782179
break;
21792180
default:
2181+
type_changed = !IsCastRedundantInRust(sub_expr, type);
21802182
break;
21812183
}
21822184
}
2183-
{
2184-
PushParen paren(*this, suffix);
2185+
if (type_changed) {
2186+
PushParen paren(*this);
21852187
Convert(sub_expr);
2186-
}
2187-
if (suffix) {
2188-
StrCat(suffix);
2188+
ConvertCast(type);
2189+
} else {
2190+
{
2191+
PushParen paren(*this, suffix);
2192+
Convert(sub_expr);
2193+
}
2194+
if (suffix) {
2195+
StrCat(suffix);
2196+
}
21892197
}
21902198
break;
21912199
}

‎cpp2rust/converter/models/converter_refcount.cpp‎

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

12651265
if (expr->getCastKind() == clang::CastKind::CK_NoOp) {
1266+
if (expr->getType()->isPointerType() && sub_expr->getType()->isPointerType()) {
1267+
auto dest_type = ConvertPointeeType(expr->getType());
1268+
if (dest_type != ConvertPointeeType(sub_expr->getType())) {
1269+
Convert(sub_expr);
1270+
StrCat(std::format(".reinterpret_cast::<{}>()", dest_type));
1271+
computed_expr_type_ = ComputedExprType::FreshPointer;
1272+
return false;
1273+
}
1274+
}
12661275
Convert(sub_expr);
12671276
return false;
12681277
}

‎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)