Skip to content

Commit 12c7116

Browse files
authored
Add Ptr::from_int and Ptr::to_int (#229)
1 parent a081b41 commit 12c7116

5 files changed

Lines changed: 103 additions & 0 deletions

File tree

cpp2rust/converter/models/converter_refcount.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,8 +1341,29 @@ bool ConverterRefCount::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
13411341
return false;
13421342
case clang::Stmt::CStyleCastExprClass:
13431343
case clang::Stmt::CXXStaticCastExprClass:
1344+
if (expr->getCastKind() == clang::CastKind::CK_PointerToIntegral ||
1345+
expr->getCastKind() == clang::CastKind::CK_IntegralToPointer) {
1346+
std::string dst_type;
1347+
{
1348+
PushConversionKind push(*this, ConversionKind::Unboxed);
1349+
dst_type = ToString(expr->getType());
1350+
}
1351+
if (expr->getCastKind() == clang::CastKind::CK_PointerToIntegral) {
1352+
StrCat(std::format("{}.to_int()", ToString(expr->getSubExpr())));
1353+
computed_expr_type_ = ComputedExprType::FreshValue;
1354+
} else {
1355+
StrCat(std::format("<{}>::from_int({})", dst_type,
1356+
ToString(expr->getSubExpr())));
1357+
computed_expr_type_ = ComputedExprType::FreshPointer;
1358+
}
1359+
return false;
1360+
}
1361+
13441362
if (!VisitFunctionPointerCast(expr)) {
13451363
return false;
1364+
} else if (expr->getSubExpr()->getType()->isVoidPointerType() &&
1365+
expr->getType()->isVoidPointerType()) {
1366+
return Convert(expr->getSubExpr());
13461367
} else if (expr->getSubExpr()->getType()->isVoidPointerType() &&
13471368
expr->getType()->isPointerType()) {
13481369
Convert(expr->getSubExpr());

libcc2rs/src/rc.rs

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

1224+
impl<T: 'static> Ptr<T> {
1225+
pub fn to_int(&self) -> usize {
1226+
let mut buf = vec![0u8; Self::byte_size()];
1227+
self.to_bytes(&mut buf);
1228+
usize::from_bytes(&buf[..std::mem::size_of::<usize>()])
1229+
}
1230+
1231+
pub fn from_int(value: usize) -> Self {
1232+
let mut buf = vec![0u8; Self::byte_size()];
1233+
value.to_bytes(&mut buf[..std::mem::size_of::<usize>()]);
1234+
Self::from_bytes(&buf)
1235+
}
1236+
}
1237+
1238+
impl AnyPtr {
1239+
pub fn to_int(&self) -> usize {
1240+
self.reinterpret_cast::<u8>().to_int()
1241+
}
1242+
1243+
pub fn from_int(value: usize) -> Self {
1244+
Ptr::<u8>::from_int(value).to_any()
1245+
}
1246+
}
1247+
12241248
#[cfg(test)]
12251249
mod tests {
12261250
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()))
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)