Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions cpp2rust/converter/converter_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ bool IsInMainFile(const clang::Decl *decl) {
return src_mgr.isInMainFile(src_mgr.getExpansionLoc(loc));
}

bool IsUnionArrayMember(const clang::Expr *base) {
if (auto *me =
clang::dyn_cast<clang::MemberExpr>(base->IgnoreParenImpCasts())) {
if (auto *fd = clang::dyn_cast<clang::FieldDecl>(me->getMemberDecl())) {
return fd->getParent()->isUnion() && fd->getType()->isArrayType();
}
}
return false;
}

bool IsUserDefinedDecl(const clang::Decl *decl) {
const auto &ctx = decl->getASTContext();
const auto &src_mgr = ctx.getSourceManager();
Expand Down
2 changes: 2 additions & 0 deletions cpp2rust/converter/converter_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ bool IsComparisonWithNullOp(const clang::BinaryOperator *expr);

bool IsInMainFile(const clang::Decl *decl);

bool IsUnionArrayMember(const clang::Expr *base);

bool IsUserDefinedDecl(const clang::Decl *decl);

bool RefersToUserDefinedDecl(const clang::Expr *expr);
Expand Down
14 changes: 9 additions & 5 deletions cpp2rust/converter/models/converter_refcount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,8 @@ std::string ConverterRefCount::ConvertPtrType(clang::QualType type) {
bool ConverterRefCount::VisitArraySubscriptExpr(
clang::ArraySubscriptExpr *expr) {
auto *base = expr->getBase();
if (base->IgnoreCasts()->getType()->isPointerType()) {
if (base->IgnoreCasts()->getType()->isPointerType() ||
IsUnionArrayMember(base)) {
ConvertPointerSubscript(expr);
} else {
if (!base->IgnoreCasts()->getType()->isArrayType()) {
Expand Down Expand Up @@ -504,13 +505,16 @@ void ConverterRefCount::EmitRustUnion(clang::RecordDecl *decl) {
{
PushBrace impl_brace(*this);
for (auto *field : decl->fields()) {
PushConversionKind push(*this, ConversionKind::FullRefCount);
std::string storage_ty = ToString(field->getType());
Unwrap(storage_ty, "Value<", ">");
PushConversionKind push(*this, ConversionKind::Unboxed);
auto ty =
field->getType()->isArrayType()
? ToString(
field->getType()->getAsArrayTypeUnsafe()->getElementType())
: ToString(field->getType());
StrCat(std::format(
"pub fn {}(&self) -> Ptr<{}> {{ (self.__bytes.as_pointer() "
"as Ptr<u8>).reinterpret_cast() }}",
GetNamedDeclAsString(field), storage_ty));
GetNamedDeclAsString(field), ty));
}
}

Expand Down
17 changes: 13 additions & 4 deletions tests/unit/out/refcount/union_addrof_external.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl anon_0 {
pub fn h(&self) -> Ptr<record> {
(self.__bytes.as_pointer() as Ptr<u8>).reinterpret_cast()
}
pub fn raw_(&self) -> Ptr<Box<[u8]>> {
pub fn raw_(&self) -> Ptr<u8> {
(self.__bytes.as_pointer() as Ptr<u8>).reinterpret_cast()
}
}
Expand Down Expand Up @@ -187,12 +187,21 @@ fn main_0() -> i32 {
!= 0)
);
assert!(
((((((*(*c.borrow()).view.borrow()).raw_().read())[(0) as usize] as i32) == 2) as i32)
(((((((*(*c.borrow()).view.borrow())
.raw_()
.reinterpret_cast::<u8>() as Ptr::<u8>)
.offset((0) as isize)
.read()) as i32)
== 2) as i32)
!= 0)
);
assert!(
(((((((*(*c.borrow()).view.borrow()).raw_().read())[(3) as usize] as u8) as i32) == 80)
as i32)
((((((((*(*c.borrow()).view.borrow())
.raw_()
.reinterpret_cast::<u8>() as Ptr::<u8>)
.offset((3) as isize)
.read()) as u8) as i32)
== 80) as i32)
!= 0)
);
return 0;
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/out/refcount/union_cross_arm_cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl anon_0 {
pub fn b(&self) -> Ptr<shape_b> {
(self.__bytes.as_pointer() as Ptr<u8>).reinterpret_cast()
}
pub fn raw_(&self) -> Ptr<Box<[u8]>> {
pub fn raw_(&self) -> Ptr<u8> {
(self.__bytes.as_pointer() as Ptr<u8>).reinterpret_cast()
}
}
Expand Down
84 changes: 84 additions & 0 deletions tests/unit/out/refcount/union_field_alignment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
extern crate libcc2rs;
use libcc2rs::*;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::io::prelude::*;
use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
pub struct anon_0 {
__bytes: Value<Box<[u8]>>,
}
impl anon_0 {
pub fn bytes(&self) -> Ptr<u8> {
(self.__bytes.as_pointer() as Ptr<u8>).reinterpret_cast()
}
pub fn aligner(&self) -> Ptr<AnyPtr> {
(self.__bytes.as_pointer() as Ptr<u8>).reinterpret_cast()
}
}
impl Clone for anon_0 {
fn clone(&self) -> Self {
anon_0 {
__bytes: Rc::new(RefCell::new(self.__bytes.borrow().clone())),
}
}
}
impl Default for anon_0 {
fn default() -> Self {
anon_0 {
__bytes: Rc::new(RefCell::new(Box::from([0u8; 8]))),
}
}
}
impl ByteRepr for anon_0 {
fn byte_size() -> usize {
8
}
fn to_bytes(&self, buf: &mut [u8]) {
buf.copy_from_slice(&self.__bytes.borrow());
}
fn from_bytes(buf: &[u8]) -> Self {
anon_0 {
__bytes: Rc::new(RefCell::new(Box::from(buf))),
}
}
}
#[derive(Default)]
pub struct node {
pub next: Value<Ptr<node>>,
pub x: Value<anon_0>,
}
impl ByteRepr for node {
fn byte_size() -> usize {
16
}
fn to_bytes(&self, buf: &mut [u8]) {
(*self.next.borrow()).to_bytes(&mut buf[0..8]);
(*self.x.borrow()).to_bytes(&mut buf[8..16]);
}
fn from_bytes(buf: &[u8]) -> Self {
Self {
next: Rc::new(RefCell::new(<Ptr<node>>::from_bytes(&buf[0..8]))),
x: Rc::new(RefCell::new(<anon_0>::from_bytes(&buf[8..16]))),
}
}
}
pub fn main() {
std::process::exit(main_0());
}
fn main_0() -> i32 {
let n: Value<node> = <Value<node>>::default();
(*(*n.borrow()).next.borrow_mut()) = Ptr::<node>::null();
((*(*n.borrow()).x.borrow()).bytes().reinterpret_cast::<u8>() as Ptr<u8>)
.offset((0) as isize)
.write(171_u8);
assert!(
(((((((*(*n.borrow()).x.borrow()).bytes().reinterpret_cast::<u8>() as Ptr::<u8>)
.offset((0) as isize)
.read()) as i32)
== 171) as i32)
!= 0)
);
return 0;
}
16 changes: 13 additions & 3 deletions tests/unit/out/refcount/union_memset_memcpy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl anon_0 {
pub fn b(&self) -> Ptr<shape_b> {
(self.__bytes.as_pointer() as Ptr<u8>).reinterpret_cast()
}
pub fn raw_(&self) -> Ptr<Box<[u8]>> {
pub fn raw_(&self) -> Ptr<u8> {
(self.__bytes.as_pointer() as Ptr<u8>).reinterpret_cast()
}
}
Expand Down Expand Up @@ -158,11 +158,21 @@ fn main_0() -> i32 {
!= 0)
);
assert!(
((((((*(*c.borrow()).view.borrow()).raw_().read())[(0) as usize] as i32) == 0) as i32)
(((((((*(*c.borrow()).view.borrow())
.raw_()
.reinterpret_cast::<u8>() as Ptr::<u8>)
.offset((0) as isize)
.read()) as i32)
== 0) as i32)
!= 0)
);
assert!(
((((((*(*c.borrow()).view.borrow()).raw_().read())[(255) as usize] as i32) == 0) as i32)
(((((((*(*c.borrow()).view.borrow())
.raw_()
.reinterpret_cast::<u8>() as Ptr::<u8>)
.offset((255) as isize)
.read()) as i32)
== 0) as i32)
!= 0)
);
let src: Value<Box<[u8]>> = Rc::new(RefCell::new(Box::new([
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/out/refcount/union_nested.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl anon_0 {
pub fn h(&self) -> Ptr<record> {
(self.__bytes.as_pointer() as Ptr<u8>).reinterpret_cast()
}
pub fn raw_(&self) -> Ptr<Box<[u8]>> {
pub fn raw_(&self) -> Ptr<u8> {
(self.__bytes.as_pointer() as Ptr<u8>).reinterpret_cast()
}
}
Expand Down
18 changes: 13 additions & 5 deletions tests/unit/out/refcount/union_struct_dual_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl anon_1 {
pub fn inner(&self) -> Ptr<Inner> {
(self.__bytes.as_pointer() as Ptr<u8>).reinterpret_cast()
}
pub fn raw_(&self) -> Ptr<Box<[u8]>> {
pub fn raw_(&self) -> Ptr<u8> {
(self.__bytes.as_pointer() as Ptr<u8>).reinterpret_cast()
}
}
Expand Down Expand Up @@ -114,13 +114,21 @@ fn main_0() -> i32 {
!= 0)
);
assert!(
(((((((*(*outer.borrow()).u.borrow()).raw_().read())[(0) as usize] as u8) as i32) == 3)
as i32)
((((((((*(*outer.borrow()).u.borrow())
.raw_()
.reinterpret_cast::<u8>() as Ptr::<u8>)
.offset((0) as isize)
.read()) as u8) as i32)
== 3) as i32)
!= 0)
);
assert!(
(((((((*(*outer.borrow()).u.borrow()).raw_().read())[(4) as usize] as u8) as i32) == 4)
as i32)
((((((((*(*outer.borrow()).u.borrow())
.raw_()
.reinterpret_cast::<u8>() as Ptr::<u8>)
.offset((4) as isize)
.read()) as u8) as i32)
== 4) as i32)
!= 0)
);
return 0;
Expand Down
1 change: 0 additions & 1 deletion tests/unit/union_field_alignment.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// no-compile: refcount
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
Expand Down
Loading