Skip to content

Commit a2ce948

Browse files
committed
Add Ptr::from_int and Ptr::to_int
1 parent 22edd84 commit a2ce948

5 files changed

Lines changed: 104 additions & 0 deletions

File tree

cpp2rust/converter/models/converter_refcount.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,8 +1307,30 @@ bool ConverterRefCount::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
13071307
return false;
13081308
case clang::Stmt::CStyleCastExprClass:
13091309
case clang::Stmt::CXXStaticCastExprClass:
1310+
if (expr->getCastKind() == clang::CastKind::CK_PointerToIntegral ||
1311+
expr->getCastKind() == clang::CastKind::CK_IntegralToPointer) {
1312+
std::string dst_type;
1313+
{
1314+
PushConversionKind push(*this, ConversionKind::Unboxed);
1315+
dst_type = ToString(expr->getType());
1316+
}
1317+
if (expr->getCastKind() == clang::CastKind::CK_PointerToIntegral) {
1318+
StrCat(std::format("{}.to_int::<{}>()", ToString(expr->getSubExpr()),
1319+
dst_type));
1320+
computed_expr_type_ = ComputedExprType::FreshValue;
1321+
} else {
1322+
StrCat(std::format("<{}>::from_int({})", dst_type,
1323+
ToString(expr->getSubExpr())));
1324+
computed_expr_type_ = ComputedExprType::FreshPointer;
1325+
}
1326+
return false;
1327+
}
1328+
13101329
if (!VisitFunctionPointerCast(expr)) {
13111330
return false;
1331+
} else if (expr->getSubExpr()->getType()->isVoidPointerType() &&
1332+
expr->getType()->isVoidPointerType()) {
1333+
return Convert(expr->getSubExpr());
13121334
} else if (expr->getSubExpr()->getType()->isVoidPointerType() &&
13131335
expr->getType()->isPointerType()) {
13141336
Convert(expr->getSubExpr());

libcc2rs/src/rc.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,30 @@ impl<T: ?Sized> AsPointerDyn<T> for Rc<RefCell<T>> {
12111211
impl<T: 'static> ByteRepr for Ptr<T> {}
12121212
impl ByteRepr for AnyPtr {}
12131213

1214+
impl<T: 'static> Ptr<T> {
1215+
pub fn to_int<U: ByteRepr>(&self) -> U {
1216+
let mut buf = vec![0u8; Self::byte_size()];
1217+
self.to_bytes(&mut buf);
1218+
U::from_bytes(&buf[..U::byte_size()])
1219+
}
1220+
1221+
pub fn from_int<U: ByteRepr>(value: U) -> Self {
1222+
let mut buf = vec![0u8; Self::byte_size()];
1223+
value.to_bytes(&mut buf[..U::byte_size()]);
1224+
Self::from_bytes(&buf)
1225+
}
1226+
}
1227+
1228+
impl AnyPtr {
1229+
pub fn to_int<U: ByteRepr>(&self) -> U {
1230+
self.reinterpret_cast::<u8>().to_int()
1231+
}
1232+
1233+
pub fn from_int<U: ByteRepr>(value: U) -> Self {
1234+
Ptr::<u8>::from_int(value).to_any()
1235+
}
1236+
}
1237+
12141238
#[cfg(test)]
12151239
mod tests {
12161240
use super::*;

tests/unit/out/refcount/unconst.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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 main() {
10+
std::process::exit(main_0());
11+
}
12+
fn main_0() -> i32 {
13+
let a: Value<i32> = Rc::new(RefCell::new(1));
14+
let p: Value<Ptr<i32>> = Rc::new(RefCell::new((a.as_pointer())));
15+
let q: Value<Ptr<i32>> = Rc::new(RefCell::new(
16+
(<AnyPtr>::from_int(((*p.borrow()).clone() as Ptr<i32>).to_any().to_int::<u64>()))
17+
.reinterpret_cast::<i32>(),
18+
));
19+
assert!({
20+
let _lhs = (*p.borrow()).clone();
21+
_lhs == (*q.borrow()).clone()
22+
});
23+
return 0;
24+
}

tests/unit/out/unsafe/unconst.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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 fn main() {
10+
unsafe {
11+
std::process::exit(main_0() as i32);
12+
}
13+
}
14+
unsafe fn main_0() -> i32 {
15+
let a: i32 = 1;
16+
let mut p: *const i32 = (&a as *const i32);
17+
let mut q: *mut i32 = (((((p) as *const i32 as *const ::libc::c_void) as u64)
18+
as *mut ::libc::c_void) as *mut i32);
19+
assert!(((p) == ((q).cast_const())));
20+
return 0;
21+
}

tests/unit/unconst.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// panic: refcount
2+
#include <assert.h>
3+
#include <stdint.h>
4+
5+
#define UNCONST(p) ((void *)(uintptr_t)(const void *)(p))
6+
7+
int main() {
8+
const int a = 1;
9+
const int *p = &a;
10+
auto q = static_cast<int *>(UNCONST(p));
11+
assert(p == q);
12+
return 0;
13+
}

0 commit comments

Comments
 (0)