From 312a51c4ead1004744dd90914a4abeb204dd06b4 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 27 Apr 2026 22:08:14 +0100 Subject: [PATCH 01/14] Handle anonymous structs inside records --- cpp2rust/converter/converter_lib.cpp | 25 +++++++++++++++++++++++++ cpp2rust/converter/converter_lib.h | 2 ++ cpp2rust/converter/mapper.cpp | 16 ++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index a7f12c8d..44f87766 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "converter/lex.h" @@ -296,6 +297,25 @@ unsigned GetArraySize(clang::QualType array_type) { return constant_array_ty->getSize().getZExtValue(); } +unsigned GetAnonIndex(const clang::NamedDecl *decl) { + if (auto *parent = + clang::dyn_cast(decl->getDeclContext())) { + unsigned counter = 0; + for (auto *d : parent->decls()) { + if (d == decl) { + return counter; + } + auto *named = clang::dyn_cast(d); + if (named && named->getKind() == decl->getKind() && + named->getName().empty()) { + counter++; + } + } + return counter; + } + return 0; +} + std::string GetID(const clang::Decl *decl) { assert(decl); const auto file_name = GetFileName(decl); @@ -317,6 +337,11 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) { auto name = decl->getDeclName().isIdentifier() ? decl->getName().str() : decl->getNameAsString(); + if (auto *field = clang::dyn_cast(decl); + field && name.empty()) { + return std::format("anon_{}", GetAnonIndex(field)); + } + if (auto *fn = clang::dyn_cast(decl)) { if (!clang::isa(fn)) { auto mangled = diff --git a/cpp2rust/converter/converter_lib.h b/cpp2rust/converter/converter_lib.h index a5c8d692..cec1b4ab 100644 --- a/cpp2rust/converter/converter_lib.h +++ b/cpp2rust/converter/converter_lib.h @@ -82,6 +82,8 @@ std::string GetID(const clang::Decl *decl); std::string GetNamedDeclAsString(const clang::NamedDecl *decl); +unsigned GetAnonIndex(const clang::NamedDecl *decl); + const char *AccessSpecifierAsString(clang::AccessSpecifier spec); template llvm::SmallString<16> GetNumAsString(const T &num) { diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index fe36fc16..8c124c7f 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -723,7 +723,23 @@ std::string ToString(clang::QualType qual_type) { return normalizeTranslationRule(type); } +static std::string synthesizeAnonRecordName(const clang::RecordDecl *record) { + std::string parent_name; + if (auto *parent = + clang::dyn_cast(record->getDeclContext())) { + parent_name = + parent->getIdentifier() ? parent->getIdentifier()->getName().str(); + : synthesizeAnonRecordName(parent); + } + return std::format("{}_anon_{}", parent_name, GetAnonIndex(record)); +} + std::string ToString(const clang::NamedDecl *decl) { + if (auto *record = clang::dyn_cast(decl); + record && !record->getIdentifier()) { + return synthesizeAnonRecordName(record); + } + std::string out; llvm::raw_string_ostream os(out); From a172ec6777516ccb63e3945755c79c91fb78708b Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 27 Apr 2026 22:21:11 +0100 Subject: [PATCH 02/14] Fix build --- cpp2rust/converter/mapper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index 8c124c7f..0e31cf9e 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -727,8 +727,8 @@ static std::string synthesizeAnonRecordName(const clang::RecordDecl *record) { std::string parent_name; if (auto *parent = clang::dyn_cast(record->getDeclContext())) { - parent_name = - parent->getIdentifier() ? parent->getIdentifier()->getName().str(); + parent_name = parent->getIdentifier() + ? parent->getIdentifier()->getName().str() : synthesizeAnonRecordName(parent); } return std::format("{}_anon_{}", parent_name, GetAnonIndex(record)); From 172ea4fb4cc273eb149f48b399b11e0db811bcd4 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 28 Apr 2026 09:15:26 +0100 Subject: [PATCH 03/14] Use same index as anonymous type for record name --- cpp2rust/converter/converter_lib.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 44f87766..9a11f897 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -337,9 +337,15 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) { auto name = decl->getDeclName().isIdentifier() ? decl->getName().str() : decl->getNameAsString(); + // Anonymous record field if (auto *field = clang::dyn_cast(decl); field && name.empty()) { - return std::format("anon_{}", GetAnonIndex(field)); + const clang::NamedDecl *target = field; + if (auto *record = field->getType()->getAsRecordDecl(); + record && !record->getIdentifier()) { + target = record; + } + return std::format("anon_{}", GetAnonIndex(target)); } if (auto *fn = clang::dyn_cast(decl)) { From 89b66463e3ed6ad056b30f94b753f87311a74dcb Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 28 Apr 2026 09:15:46 +0100 Subject: [PATCH 04/14] Fix default initialization of struct fields --- cpp2rust/converter/models/converter_refcount.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 460d8479..5cf1dada 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1519,6 +1519,7 @@ bool ConverterRefCount::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) { bool ConverterRefCount::VisitImplicitValueInitExpr( clang::ImplicitValueInitExpr *expr) { + PushConversionKind push(*this, ConversionKind::Unboxed); if (auto arr_ty = clang::dyn_cast( expr->getType()->getCanonicalTypeInternal().getTypePtr())) { if (clang::isa(arr_ty)) { From 5b42b0ade8277273d719e1c934dd165cff482826 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 28 Apr 2026 09:17:02 +0100 Subject: [PATCH 05/14] Add anonymous struct tests --- tests/unit/anonymous-struct.cpp | 63 ++++++ tests/unit/anonymous-struct_c.c | 63 ++++++ tests/unit/out/refcount/anonymous-struct.rs | 201 ++++++++++++++++++ tests/unit/out/refcount/anonymous-struct_c.rs | 110 ++++++++++ tests/unit/out/unsafe/anonymous-struct.rs | 91 ++++++++ tests/unit/out/unsafe/anonymous-struct_c.rs | 87 ++++++++ 6 files changed, 615 insertions(+) create mode 100644 tests/unit/anonymous-struct.cpp create mode 100644 tests/unit/anonymous-struct_c.c create mode 100644 tests/unit/out/refcount/anonymous-struct.rs create mode 100644 tests/unit/out/refcount/anonymous-struct_c.rs create mode 100644 tests/unit/out/unsafe/anonymous-struct.rs create mode 100644 tests/unit/out/unsafe/anonymous-struct_c.rs diff --git a/tests/unit/anonymous-struct.cpp b/tests/unit/anonymous-struct.cpp new file mode 100644 index 00000000..643ee630 --- /dev/null +++ b/tests/unit/anonymous-struct.cpp @@ -0,0 +1,63 @@ +#include + +struct Outer { + struct Named { + int a; + int b; + } named; + + struct { + int c; + int d; + } anonymous_named_0; + + struct { + int g; + int h; + } anonymous_named_1; + + struct { + int e; + int f; + }; + + struct { + int i; + struct { + int j; + } inner_named; + struct { + int k; + }; + }; +}; + +int main() { + Outer o = {}; + + o.named.a = 1; + o.named.b = 2; + o.anonymous_named_0.c = 3; + o.anonymous_named_0.d = 4; + o.anonymous_named_1.g = 5; + o.anonymous_named_1.h = 6; + o.e = 7; + o.f = 8; + o.i = 9; + o.inner_named.j = 10; + o.k = 11; + + assert(o.named.a == 1); + assert(o.named.b == 2); + assert(o.anonymous_named_0.c == 3); + assert(o.anonymous_named_0.d == 4); + assert(o.anonymous_named_1.g == 5); + assert(o.anonymous_named_1.h == 6); + assert(o.e == 7); + assert(o.f == 8); + assert(o.i == 9); + assert(o.inner_named.j == 10); + assert(o.k == 11); + + return 0; +} diff --git a/tests/unit/anonymous-struct_c.c b/tests/unit/anonymous-struct_c.c new file mode 100644 index 00000000..763e21bd --- /dev/null +++ b/tests/unit/anonymous-struct_c.c @@ -0,0 +1,63 @@ +#include + +struct Outer { + struct Named { + int a; + int b; + } named; + + struct { + int c; + int d; + } anon0; + + struct { + int g; + int h; + } anon1; + + struct { + int e; + int f; + }; + + struct { + int i; + struct { + int j; + } inner_named; + struct { + int k; + }; + }; +}; + +int main(void) { + struct Outer o = {0}; + + o.named.a = 1; + o.named.b = 2; + o.anon0.c = 3; + o.anon0.d = 4; + o.anon1.g = 5; + o.anon1.h = 6; + o.e = 7; + o.f = 8; + o.i = 9; + o.inner_named.j = 10; + o.k = 11; + + assert(o.named.a == 1); + assert(o.named.b == 2); + assert(o.anon0.c == 3); + assert(o.anon0.d == 4); + assert(o.anon1.g == 5); + assert(o.anon1.h == 6); + assert(o.e == 7); + assert(o.f == 8); + assert(o.i == 9); + assert(o.inner_named.j == 10); + assert(o.k == 11); + + return 0; +} diff --git a/tests/unit/out/refcount/anonymous-struct.rs b/tests/unit/out/refcount/anonymous-struct.rs new file mode 100644 index 00000000..4fad0525 --- /dev/null +++ b/tests/unit/out/refcount/anonymous-struct.rs @@ -0,0 +1,201 @@ +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}; +#[derive(Default)] +pub struct Outer_Named { + pub a: Value, + pub b: Value, +} +impl Clone for Outer_Named { + fn clone(&self) -> Self { + let mut this = Self { + a: Rc::new(RefCell::new((*self.a.borrow()))), + b: Rc::new(RefCell::new((*self.b.borrow()))), + }; + this + } +} +impl ByteRepr for Outer_Named {} +#[derive(Default)] +pub struct Outer_anon_0 { + pub c: Value, + pub d: Value, +} +impl Clone for Outer_anon_0 { + fn clone(&self) -> Self { + let mut this = Self { + c: Rc::new(RefCell::new((*self.c.borrow()))), + d: Rc::new(RefCell::new((*self.d.borrow()))), + }; + this + } +} +impl ByteRepr for Outer_anon_0 {} +#[derive(Default)] +pub struct Outer_anon_1 { + pub g: Value, + pub h: Value, +} +impl Clone for Outer_anon_1 { + fn clone(&self) -> Self { + let mut this = Self { + g: Rc::new(RefCell::new((*self.g.borrow()))), + h: Rc::new(RefCell::new((*self.h.borrow()))), + }; + this + } +} +impl ByteRepr for Outer_anon_1 {} +#[derive(Default)] +pub struct Outer_anon_2 { + pub e: Value, + pub f: Value, +} +impl Clone for Outer_anon_2 { + fn clone(&self) -> Self { + let mut this = Self { + e: Rc::new(RefCell::new((*self.e.borrow()))), + f: Rc::new(RefCell::new((*self.f.borrow()))), + }; + this + } +} +impl ByteRepr for Outer_anon_2 {} +#[derive(Default)] +pub struct Outer_anon_3_anon_0 { + pub j: Value, +} +impl Clone for Outer_anon_3_anon_0 { + fn clone(&self) -> Self { + let mut this = Self { + j: Rc::new(RefCell::new((*self.j.borrow()))), + }; + this + } +} +impl ByteRepr for Outer_anon_3_anon_0 {} +#[derive(Default)] +pub struct Outer_anon_3_anon_1 { + pub k: Value, +} +impl Clone for Outer_anon_3_anon_1 { + fn clone(&self) -> Self { + let mut this = Self { + k: Rc::new(RefCell::new((*self.k.borrow()))), + }; + this + } +} +impl ByteRepr for Outer_anon_3_anon_1 {} +#[derive(Default)] +pub struct Outer_anon_3 { + pub i: Value, + pub inner_named: Value, + pub anon_1: Value, +} +impl Clone for Outer_anon_3 { + fn clone(&self) -> Self { + let mut this = Self { + i: Rc::new(RefCell::new((*self.i.borrow()))), + inner_named: Rc::new(RefCell::new((*self.inner_named.borrow()).clone())), + anon_1: Rc::new(RefCell::new((*self.anon_1.borrow()).clone())), + }; + this + } +} +impl ByteRepr for Outer_anon_3 {} +#[derive(Default)] +pub struct Outer { + pub named: Value, + pub anonymous_named_0: Value, + pub anonymous_named_1: Value, + pub anon_2: Value, + pub anon_3: Value, +} +impl Clone for Outer { + fn clone(&self) -> Self { + let mut this = Self { + named: Rc::new(RefCell::new((*self.named.borrow()).clone())), + anonymous_named_0: Rc::new(RefCell::new((*self.anonymous_named_0.borrow()).clone())), + anonymous_named_1: Rc::new(RefCell::new((*self.anonymous_named_1.borrow()).clone())), + anon_2: Rc::new(RefCell::new((*self.anon_2.borrow()).clone())), + anon_3: Rc::new(RefCell::new((*self.anon_3.borrow()).clone())), + }; + this + } +} +impl ByteRepr for Outer {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let o: Value = Rc::new(RefCell::new(Outer { + named: Rc::new(RefCell::new(Outer_Named { + a: Rc::new(RefCell::new(::default())), + b: Rc::new(RefCell::new(::default())), + })), + anonymous_named_0: Rc::new(RefCell::new(Outer_anon_0 { + c: Rc::new(RefCell::new(::default())), + d: Rc::new(RefCell::new(::default())), + })), + anonymous_named_1: Rc::new(RefCell::new(Outer_anon_1 { + g: Rc::new(RefCell::new(::default())), + h: Rc::new(RefCell::new(::default())), + })), + anon_2: Rc::new(RefCell::new(Outer_anon_2 { + e: Rc::new(RefCell::new(::default())), + f: Rc::new(RefCell::new(::default())), + })), + anon_3: Rc::new(RefCell::new(Outer_anon_3 { + i: Rc::new(RefCell::new(::default())), + inner_named: Rc::new(RefCell::new(Outer_anon_3_anon_0 { + j: Rc::new(RefCell::new(::default())), + })), + anon_1: Rc::new(RefCell::new(Outer_anon_3_anon_1 { + k: Rc::new(RefCell::new(::default())), + })), + })), + })); + (*(*(*o.borrow()).named.borrow()).a.borrow_mut()) = 1; + (*(*(*o.borrow()).named.borrow()).b.borrow_mut()) = 2; + (*(*(*o.borrow()).anonymous_named_0.borrow()).c.borrow_mut()) = 3; + (*(*(*o.borrow()).anonymous_named_0.borrow()).d.borrow_mut()) = 4; + (*(*(*o.borrow()).anonymous_named_1.borrow()).g.borrow_mut()) = 5; + (*(*(*o.borrow()).anonymous_named_1.borrow()).h.borrow_mut()) = 6; + (*(*(*o.borrow()).anon_2.borrow()).e.borrow_mut()) = 7; + (*(*(*o.borrow()).anon_2.borrow()).f.borrow_mut()) = 8; + (*(*(*o.borrow()).anon_3.borrow()).i.borrow_mut()) = 9; + (*(*(*(*o.borrow()).anon_3.borrow()).inner_named.borrow()) + .j + .borrow_mut()) = 10; + (*(*(*(*o.borrow()).anon_3.borrow()).anon_1.borrow()) + .k + .borrow_mut()) = 11; + assert!(((*(*(*o.borrow()).named.borrow()).a.borrow()) == 1)); + assert!(((*(*(*o.borrow()).named.borrow()).b.borrow()) == 2)); + assert!(((*(*(*o.borrow()).anonymous_named_0.borrow()).c.borrow()) == 3)); + assert!(((*(*(*o.borrow()).anonymous_named_0.borrow()).d.borrow()) == 4)); + assert!(((*(*(*o.borrow()).anonymous_named_1.borrow()).g.borrow()) == 5)); + assert!(((*(*(*o.borrow()).anonymous_named_1.borrow()).h.borrow()) == 6)); + assert!(((*(*(*o.borrow()).anon_2.borrow()).e.borrow()) == 7)); + assert!(((*(*(*o.borrow()).anon_2.borrow()).f.borrow()) == 8)); + assert!(((*(*(*o.borrow()).anon_3.borrow()).i.borrow()) == 9)); + assert!( + ((*(*(*(*o.borrow()).anon_3.borrow()).inner_named.borrow()) + .j + .borrow()) + == 10) + ); + assert!( + ((*(*(*(*o.borrow()).anon_3.borrow()).anon_1.borrow()) + .k + .borrow()) + == 11) + ); + return 0; +} diff --git a/tests/unit/out/refcount/anonymous-struct_c.rs b/tests/unit/out/refcount/anonymous-struct_c.rs new file mode 100644 index 00000000..c4987572 --- /dev/null +++ b/tests/unit/out/refcount/anonymous-struct_c.rs @@ -0,0 +1,110 @@ +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}; +#[derive(Default)] +pub struct Named { + pub a: Value, + pub b: Value, +} +impl ByteRepr for Named {} +#[derive(Default)] +pub struct Outer_anon_0 { + pub c: Value, + pub d: Value, +} +impl ByteRepr for Outer_anon_0 {} +#[derive(Default)] +pub struct Outer_anon_1 { + pub g: Value, + pub h: Value, +} +impl ByteRepr for Outer_anon_1 {} +#[derive(Default)] +pub struct Outer_anon_2 { + pub e: Value, + pub f: Value, +} +impl ByteRepr for Outer_anon_2 {} +#[derive(Default)] +pub struct Outer_anon_3_anon_0 { + pub j: Value, +} +impl ByteRepr for Outer_anon_3_anon_0 {} +#[derive(Default)] +pub struct Outer_anon_3_anon_1 { + pub k: Value, +} +impl ByteRepr for Outer_anon_3_anon_1 {} +#[derive(Default)] +pub struct Outer_anon_3 { + pub i: Value, + pub inner_named: Value, + pub anon_1: Value, +} +impl ByteRepr for Outer_anon_3 {} +#[derive(Default)] +pub struct Outer { + pub named: Value, + pub anon0: Value, + pub anon1: Value, + pub anon_2: Value, + pub anon_3: Value, +} +impl ByteRepr for Outer {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let o: Value = Rc::new(RefCell::new(Outer { + named: Rc::new(RefCell::new(Named { + a: Rc::new(RefCell::new(0)), + b: Rc::new(RefCell::new(::default())), + })), + anon0: Rc::new(RefCell::new(::default())), + anon1: Rc::new(RefCell::new(::default())), + anon_2: Rc::new(RefCell::new(::default())), + anon_3: Rc::new(RefCell::new(::default())), + })); + (*(*(*o.borrow()).named.borrow()).a.borrow_mut()) = 1; + (*(*(*o.borrow()).named.borrow()).b.borrow_mut()) = 2; + (*(*(*o.borrow()).anon0.borrow()).c.borrow_mut()) = 3; + (*(*(*o.borrow()).anon0.borrow()).d.borrow_mut()) = 4; + (*(*(*o.borrow()).anon1.borrow()).g.borrow_mut()) = 5; + (*(*(*o.borrow()).anon1.borrow()).h.borrow_mut()) = 6; + (*(*(*o.borrow()).anon_2.borrow()).e.borrow_mut()) = 7; + (*(*(*o.borrow()).anon_2.borrow()).f.borrow_mut()) = 8; + (*(*(*o.borrow()).anon_3.borrow()).i.borrow_mut()) = 9; + (*(*(*(*o.borrow()).anon_3.borrow()).inner_named.borrow()) + .j + .borrow_mut()) = 10; + (*(*(*(*o.borrow()).anon_3.borrow()).anon_1.borrow()) + .k + .borrow_mut()) = 11; + assert!(((*(*(*o.borrow()).named.borrow()).a.borrow()) == 1)); + assert!(((*(*(*o.borrow()).named.borrow()).b.borrow()) == 2)); + assert!(((*(*(*o.borrow()).anon0.borrow()).c.borrow()) == 3)); + assert!(((*(*(*o.borrow()).anon0.borrow()).d.borrow()) == 4)); + assert!(((*(*(*o.borrow()).anon1.borrow()).g.borrow()) == 5)); + assert!(((*(*(*o.borrow()).anon1.borrow()).h.borrow()) == 6)); + assert!(((*(*(*o.borrow()).anon_2.borrow()).e.borrow()) == 7)); + assert!(((*(*(*o.borrow()).anon_2.borrow()).f.borrow()) == 8)); + assert!(((*(*(*o.borrow()).anon_3.borrow()).i.borrow()) == 9)); + assert!( + ((*(*(*(*o.borrow()).anon_3.borrow()).inner_named.borrow()) + .j + .borrow()) + == 10) + ); + assert!( + ((*(*(*(*o.borrow()).anon_3.borrow()).anon_1.borrow()) + .k + .borrow()) + == 11) + ); + return 0; +} diff --git a/tests/unit/out/unsafe/anonymous-struct.rs b/tests/unit/out/unsafe/anonymous-struct.rs new file mode 100644 index 00000000..ecbd9834 --- /dev/null +++ b/tests/unit/out/unsafe/anonymous-struct.rs @@ -0,0 +1,91 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Copy, Clone, Default)] +pub struct Outer_Named { + pub a: i32, + pub b: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Outer_anon_0 { + pub c: i32, + pub d: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Outer_anon_1 { + pub g: i32, + pub h: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Outer_anon_2 { + pub e: i32, + pub f: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Outer_anon_3_anon_0 { + pub j: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Outer_anon_3_anon_1 { + pub k: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Outer_anon_3 { + pub i: i32, + pub inner_named: Outer_anon_3_anon_0, + pub anon_1: Outer_anon_3_anon_1, +} +#[derive(Copy, Clone, Default)] +pub struct Outer { + pub named: Outer_Named, + pub anonymous_named_0: Outer_anon_0, + pub anonymous_named_1: Outer_anon_1, + pub anon_2: Outer_anon_2, + pub anon_3: Outer_anon_3, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut o: Outer = Outer { + named: Outer_Named { a: 0_i32, b: 0_i32 }, + anonymous_named_0: Outer_anon_0 { c: 0_i32, d: 0_i32 }, + anonymous_named_1: Outer_anon_1 { g: 0_i32, h: 0_i32 }, + anon_2: Outer_anon_2 { e: 0_i32, f: 0_i32 }, + anon_3: Outer_anon_3 { + i: 0_i32, + inner_named: Outer_anon_3_anon_0 { j: 0_i32 }, + anon_1: Outer_anon_3_anon_1 { k: 0_i32 }, + }, + }; + o.named.a = 1; + o.named.b = 2; + o.anonymous_named_0.c = 3; + o.anonymous_named_0.d = 4; + o.anonymous_named_1.g = 5; + o.anonymous_named_1.h = 6; + o.anon_2.e = 7; + o.anon_2.f = 8; + o.anon_3.i = 9; + o.anon_3.inner_named.j = 10; + o.anon_3.anon_1.k = 11; + assert!(((o.named.a) == (1))); + assert!(((o.named.b) == (2))); + assert!(((o.anonymous_named_0.c) == (3))); + assert!(((o.anonymous_named_0.d) == (4))); + assert!(((o.anonymous_named_1.g) == (5))); + assert!(((o.anonymous_named_1.h) == (6))); + assert!(((o.anon_2.e) == (7))); + assert!(((o.anon_2.f) == (8))); + assert!(((o.anon_3.i) == (9))); + assert!(((o.anon_3.inner_named.j) == (10))); + assert!(((o.anon_3.anon_1.k) == (11))); + return 0; +} diff --git a/tests/unit/out/unsafe/anonymous-struct_c.rs b/tests/unit/out/unsafe/anonymous-struct_c.rs new file mode 100644 index 00000000..1c2f72ed --- /dev/null +++ b/tests/unit/out/unsafe/anonymous-struct_c.rs @@ -0,0 +1,87 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Copy, Clone, Default)] +pub struct Named { + pub a: i32, + pub b: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Outer_anon_0 { + pub c: i32, + pub d: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Outer_anon_1 { + pub g: i32, + pub h: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Outer_anon_2 { + pub e: i32, + pub f: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Outer_anon_3_anon_0 { + pub j: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Outer_anon_3_anon_1 { + pub k: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Outer_anon_3 { + pub i: i32, + pub inner_named: Outer_anon_3_anon_0, + pub anon_1: Outer_anon_3_anon_1, +} +#[derive(Copy, Clone, Default)] +pub struct Outer { + pub named: Named, + pub anon0: Outer_anon_0, + pub anon1: Outer_anon_1, + pub anon_2: Outer_anon_2, + pub anon_3: Outer_anon_3, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut o: Outer = Outer { + named: Named { a: 0, b: 0_i32 }, + anon0: ::default(), + anon1: ::default(), + anon_2: ::default(), + anon_3: ::default(), + }; + o.named.a = 1; + o.named.b = 2; + o.anon0.c = 3; + o.anon0.d = 4; + o.anon1.g = 5; + o.anon1.h = 6; + o.anon_2.e = 7; + o.anon_2.f = 8; + o.anon_3.i = 9; + o.anon_3.inner_named.j = 10; + o.anon_3.anon_1.k = 11; + assert!(((o.named.a) == (1))); + assert!(((o.named.b) == (2))); + assert!(((o.anon0.c) == (3))); + assert!(((o.anon0.d) == (4))); + assert!(((o.anon1.g) == (5))); + assert!(((o.anon1.h) == (6))); + assert!(((o.anon_2.e) == (7))); + assert!(((o.anon_2.f) == (8))); + assert!(((o.anon_3.i) == (9))); + assert!(((o.anon_3.inner_named.j) == (10))); + assert!(((o.anon_3.anon_1.k) == (11))); + return 0; +} From cd6dfc3074644042973c49ac7b4d5898c71b9cf6 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 28 Apr 2026 09:20:50 +0100 Subject: [PATCH 06/14] Make synthesizeAnonRecordName static --- cpp2rust/converter/mapper.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index 0e31cf9e..1e5f0412 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -562,6 +562,17 @@ std::string normalizeTranslationRule(std::string rule) { return rule; } +static std::string synthesizeAnonRecordName(const clang::RecordDecl *record) { + std::string parent_name; + if (auto *parent = + clang::dyn_cast(record->getDeclContext())) { + parent_name = parent->getIdentifier() + ? parent->getIdentifier()->getName().str() + : synthesizeAnonRecordName(parent); + } + return std::format("{}_anon_{}", parent_name, GetAnonIndex(record)); +} + } // namespace PushASTContext::PushASTContext(clang::ASTContext &ctx) : prev_(ctx_) { @@ -723,17 +734,6 @@ std::string ToString(clang::QualType qual_type) { return normalizeTranslationRule(type); } -static std::string synthesizeAnonRecordName(const clang::RecordDecl *record) { - std::string parent_name; - if (auto *parent = - clang::dyn_cast(record->getDeclContext())) { - parent_name = parent->getIdentifier() - ? parent->getIdentifier()->getName().str() - : synthesizeAnonRecordName(parent); - } - return std::format("{}_anon_{}", parent_name, GetAnonIndex(record)); -} - std::string ToString(const clang::NamedDecl *decl) { if (auto *record = clang::dyn_cast(decl); record && !record->getIdentifier()) { From 9cde1760948f7a56a819127a7dd3ab5ae22d45d5 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 28 Apr 2026 09:45:19 +0100 Subject: [PATCH 07/14] Handle anon records inside functions --- cpp2rust/converter/mapper.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index 1e5f0412..425cf805 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -569,8 +569,9 @@ static std::string synthesizeAnonRecordName(const clang::RecordDecl *record) { parent_name = parent->getIdentifier() ? parent->getIdentifier()->getName().str() : synthesizeAnonRecordName(parent); + parent_name += '_'; } - return std::format("{}_anon_{}", parent_name, GetAnonIndex(record)); + return std::format("{}anon_{}", parent_name, GetAnonIndex(record)); } } // namespace From e45ba887be877338e0e4151a6494c6c6a9e9eefb Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 28 Apr 2026 09:45:48 +0100 Subject: [PATCH 08/14] Update tests --- tests/unit/anonymous-struct.cpp | 11 +++++++ tests/unit/anonymous-struct_c.c | 11 +++++++ tests/unit/out/refcount/anonymous-struct.rs | 30 +++++++++++++++++++ tests/unit/out/refcount/anonymous-struct_c.rs | 21 +++++++++++++ tests/unit/out/unsafe/anonymous-struct.rs | 20 +++++++++++++ tests/unit/out/unsafe/anonymous-struct_c.rs | 20 +++++++++++++ 6 files changed, 113 insertions(+) diff --git a/tests/unit/anonymous-struct.cpp b/tests/unit/anonymous-struct.cpp index 643ee630..7b04a5a6 100644 --- a/tests/unit/anonymous-struct.cpp +++ b/tests/unit/anonymous-struct.cpp @@ -59,5 +59,16 @@ int main() { assert(o.inner_named.j == 10); assert(o.k == 11); + struct { + int x; + int z; + } s; + + s.x = 1; + s.z = 2; + + assert(s.x = 1); + assert(s.z = 2); + return 0; } diff --git a/tests/unit/anonymous-struct_c.c b/tests/unit/anonymous-struct_c.c index 763e21bd..50ab1959 100644 --- a/tests/unit/anonymous-struct_c.c +++ b/tests/unit/anonymous-struct_c.c @@ -59,5 +59,16 @@ int main(void) { assert(o.inner_named.j == 10); assert(o.k == 11); + struct { + int x; + int z; + } s; + + s.x = 1; + s.z = 2; + + assert(s.x = 1); + assert(s.z = 2); + return 0; } diff --git a/tests/unit/out/refcount/anonymous-struct.rs b/tests/unit/out/refcount/anonymous-struct.rs index 4fad0525..980aff17 100644 --- a/tests/unit/out/refcount/anonymous-struct.rs +++ b/tests/unit/out/refcount/anonymous-struct.rs @@ -197,5 +197,35 @@ fn main_0() -> i32 { .borrow()) == 11) ); + #[derive(Default)] + pub struct anon_0 { + pub x: Value, + pub z: Value, + } + impl Clone for anon_0 { + fn clone(&self) -> Self { + let mut this = Self { + x: Rc::new(RefCell::new((*self.x.borrow()))), + z: Rc::new(RefCell::new((*self.z.borrow()))), + }; + this + } + } + impl ByteRepr for anon_0 {}; + let s: Value = Rc::new(RefCell::new(::default())); + (*(*s.borrow()).x.borrow_mut()) = 1; + (*(*s.borrow()).z.borrow_mut()) = 2; + assert!( + ({ + (*(*s.borrow()).x.borrow_mut()) = 1; + (*(*s.borrow()).x.borrow()) + } != 0) + ); + assert!( + ({ + (*(*s.borrow()).z.borrow_mut()) = 2; + (*(*s.borrow()).z.borrow()) + } != 0) + ); return 0; } diff --git a/tests/unit/out/refcount/anonymous-struct_c.rs b/tests/unit/out/refcount/anonymous-struct_c.rs index c4987572..ab870b0a 100644 --- a/tests/unit/out/refcount/anonymous-struct_c.rs +++ b/tests/unit/out/refcount/anonymous-struct_c.rs @@ -106,5 +106,26 @@ fn main_0() -> i32 { .borrow()) == 11) ); + #[derive(Default)] + pub struct anon_0 { + pub x: Value, + pub z: Value, + } + impl ByteRepr for anon_0 {}; + let s: Value = >::default(); + (*(*s.borrow()).x.borrow_mut()) = 1; + (*(*s.borrow()).z.borrow_mut()) = 2; + assert!( + ({ + (*(*s.borrow()).x.borrow_mut()) = 1; + (*(*s.borrow()).x.borrow()) + } != 0) + ); + assert!( + ({ + (*(*s.borrow()).z.borrow_mut()) = 2; + (*(*s.borrow()).z.borrow()) + } != 0) + ); return 0; } diff --git a/tests/unit/out/unsafe/anonymous-struct.rs b/tests/unit/out/unsafe/anonymous-struct.rs index ecbd9834..6b95a9f3 100644 --- a/tests/unit/out/unsafe/anonymous-struct.rs +++ b/tests/unit/out/unsafe/anonymous-struct.rs @@ -87,5 +87,25 @@ unsafe fn main_0() -> i32 { assert!(((o.anon_3.i) == (9))); assert!(((o.anon_3.inner_named.j) == (10))); assert!(((o.anon_3.anon_1.k) == (11))); + #[derive(Copy, Clone, Default)] + pub struct anon_0 { + pub x: i32, + pub z: i32, + }; + let mut s: anon_0 = ::default(); + s.x = 1; + s.z = 2; + assert!( + ({ + s.x = 1; + s.x + } != 0) + ); + assert!( + ({ + s.z = 2; + s.z + } != 0) + ); return 0; } diff --git a/tests/unit/out/unsafe/anonymous-struct_c.rs b/tests/unit/out/unsafe/anonymous-struct_c.rs index 1c2f72ed..578d1f81 100644 --- a/tests/unit/out/unsafe/anonymous-struct_c.rs +++ b/tests/unit/out/unsafe/anonymous-struct_c.rs @@ -83,5 +83,25 @@ unsafe fn main_0() -> i32 { assert!(((o.anon_3.i) == (9))); assert!(((o.anon_3.inner_named.j) == (10))); assert!(((o.anon_3.anon_1.k) == (11))); + #[derive(Copy, Clone, Default)] + pub struct anon_0 { + pub x: i32, + pub z: i32, + }; + let mut s: anon_0 = ::default(); + s.x = 1; + s.z = 2; + assert!( + ({ + s.x = 1; + s.x + } != 0) + ); + assert!( + ({ + s.z = 2; + s.z + } != 0) + ); return 0; } From d8151e2a3beb4b347876ac6a4e1029e61b0a698e Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 28 Apr 2026 10:05:23 +0100 Subject: [PATCH 09/14] Track no-compile tests with XFAIL --- tests/lit/lit/formats/Cpp2RustTest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lit/lit/formats/Cpp2RustTest.py b/tests/lit/lit/formats/Cpp2RustTest.py index 2daf1491..9ba658f3 100644 --- a/tests/lit/lit/formats/Cpp2RustTest.py +++ b/tests/lit/lit/formats/Cpp2RustTest.py @@ -163,7 +163,7 @@ def fail(str, code = fail_code): if should_not_compile: if returncode != 0: shutil.rmtree(tmp_dir, True) - return lit.Test.PASS, '' + return lit.Test.XFAIL, '' return fail('expected no-compile but compiled successfully') if returncode != 0: return fail('cargo failed\n' + err) From 056421b7d9420cc5103c22ea2c40c752077cc058 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 28 Apr 2026 10:05:44 +0100 Subject: [PATCH 10/14] Update test expectations for unions --- tests/unit/union_addrof_external.c | 3 ++- tests/unit/union_cross_arm_cast.c | 2 +- tests/unit/union_field_alignment.c | 2 +- tests/unit/union_flex_array_member.c | 2 +- tests/unit/union_memset_memcpy.c | 2 +- tests/unit/union_nested.c | 2 +- tests/unit/union_pointer_pun_address.c | 3 ++- tests/unit/union_pointer_pun_writethrough.c | 3 ++- tests/unit/union_struct_dual_use.c | 2 +- tests/unit/union_tagged_many_arms.c | 1 - tests/unit/union_tagged_simple.c | 1 - tests/unit/union_tagged_struct_arms.c | 2 +- tests/unit/union_void_ptr_sized_deref.c | 1 - 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/unit/union_addrof_external.c b/tests/unit/union_addrof_external.c index 2a7fab68..87a58268 100644 --- a/tests/unit/union_addrof_external.c +++ b/tests/unit/union_addrof_external.c @@ -1,4 +1,5 @@ -// translation-fail +// translation-fail: refcount +// no-compile: unsafe #include #include #include diff --git a/tests/unit/union_cross_arm_cast.c b/tests/unit/union_cross_arm_cast.c index 0dc5d05c..d9af701d 100644 --- a/tests/unit/union_cross_arm_cast.c +++ b/tests/unit/union_cross_arm_cast.c @@ -1,4 +1,4 @@ -// translation-fail +// no-compile #include #include #include diff --git a/tests/unit/union_field_alignment.c b/tests/unit/union_field_alignment.c index 564f33c7..4051ff9d 100644 --- a/tests/unit/union_field_alignment.c +++ b/tests/unit/union_field_alignment.c @@ -1,4 +1,4 @@ -// translation-fail +// no-compile #include #include #include diff --git a/tests/unit/union_flex_array_member.c b/tests/unit/union_flex_array_member.c index e8efd7c9..c9d65425 100644 --- a/tests/unit/union_flex_array_member.c +++ b/tests/unit/union_flex_array_member.c @@ -1,4 +1,4 @@ -// translation-fail +// no-compile #include #include #include diff --git a/tests/unit/union_memset_memcpy.c b/tests/unit/union_memset_memcpy.c index 75c1ff61..6311739b 100644 --- a/tests/unit/union_memset_memcpy.c +++ b/tests/unit/union_memset_memcpy.c @@ -1,4 +1,4 @@ -// translation-fail +// no-compile #include #include #include diff --git a/tests/unit/union_nested.c b/tests/unit/union_nested.c index de3fa625..d046dcc2 100644 --- a/tests/unit/union_nested.c +++ b/tests/unit/union_nested.c @@ -1,4 +1,4 @@ -// translation-fail +// no-compile #include #include #include diff --git a/tests/unit/union_pointer_pun_address.c b/tests/unit/union_pointer_pun_address.c index a5739639..50dfd767 100644 --- a/tests/unit/union_pointer_pun_address.c +++ b/tests/unit/union_pointer_pun_address.c @@ -1,4 +1,5 @@ -// translation-fail +// no-compile: refcount +// panic: unsafe #include struct node_a { diff --git a/tests/unit/union_pointer_pun_writethrough.c b/tests/unit/union_pointer_pun_writethrough.c index 203ef9d1..03fbc47f 100644 --- a/tests/unit/union_pointer_pun_writethrough.c +++ b/tests/unit/union_pointer_pun_writethrough.c @@ -1,4 +1,5 @@ -// translation-fail +// panic: refcount +// XFAIL: unsafe #include int main(void) { diff --git a/tests/unit/union_struct_dual_use.c b/tests/unit/union_struct_dual_use.c index ef128e6c..a160e07b 100644 --- a/tests/unit/union_struct_dual_use.c +++ b/tests/unit/union_struct_dual_use.c @@ -1,4 +1,4 @@ -// translation-fail +// no-compile #include #include diff --git a/tests/unit/union_tagged_many_arms.c b/tests/unit/union_tagged_many_arms.c index 42146906..e3677004 100644 --- a/tests/unit/union_tagged_many_arms.c +++ b/tests/unit/union_tagged_many_arms.c @@ -1,4 +1,3 @@ -// translation-fail #include #include diff --git a/tests/unit/union_tagged_simple.c b/tests/unit/union_tagged_simple.c index 09406893..6efa44de 100644 --- a/tests/unit/union_tagged_simple.c +++ b/tests/unit/union_tagged_simple.c @@ -1,4 +1,3 @@ -// translation-fail #include typedef enum { diff --git a/tests/unit/union_tagged_struct_arms.c b/tests/unit/union_tagged_struct_arms.c index bc93bcac..52a4de99 100644 --- a/tests/unit/union_tagged_struct_arms.c +++ b/tests/unit/union_tagged_struct_arms.c @@ -1,4 +1,4 @@ -// translation-fail +// no-compile: unsafe #include #include diff --git a/tests/unit/union_void_ptr_sized_deref.c b/tests/unit/union_void_ptr_sized_deref.c index 2f6bdeef..586a608e 100644 --- a/tests/unit/union_void_ptr_sized_deref.c +++ b/tests/unit/union_void_ptr_sized_deref.c @@ -1,4 +1,3 @@ -// translation-fail #include #include #include From 3dd34de5db8b9432cd192e3c8383f80eecd835a7 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 28 Apr 2026 10:06:03 +0100 Subject: [PATCH 11/14] Update expected output --- .../unit/out/refcount/union_cross_arm_cast.rs | 80 ++++++++++ .../out/refcount/union_field_alignment.rs | 30 ++++ .../out/refcount/union_flex_array_member.rs | 73 +++++++++ .../unit/out/refcount/union_memset_memcpy.rs | 107 +++++++++++++ tests/unit/out/refcount/union_nested.rs | 78 +++++++++ .../out/refcount/union_pointer_pun_address.rs | 41 +++++ .../union_pointer_pun_writethrough.rs | 25 +++ .../out/refcount/union_struct_dual_use.rs | 68 ++++++++ .../out/refcount/union_tagged_many_arms.rs | 69 ++++++++ .../unit/out/refcount/union_tagged_simple.rs | 49 ++++++ .../out/refcount/union_tagged_struct_arms.rs | 148 ++++++++++++++++++ .../refcount/union_void_ptr_sized_deref.rs | 103 ++++++++++++ .../unit/out/unsafe/union_addrof_external.rs | 81 ++++++++++ tests/unit/out/unsafe/union_cross_arm_cast.rs | 62 ++++++++ .../unit/out/unsafe/union_field_alignment.rs | 30 ++++ .../out/unsafe/union_flex_array_member.rs | 52 ++++++ tests/unit/out/unsafe/union_memset_memcpy.rs | 85 ++++++++++ tests/unit/out/unsafe/union_nested.rs | 60 +++++++ .../out/unsafe/union_pointer_pun_address.rs | 35 +++++ .../unsafe/union_pointer_pun_writethrough.rs | 26 +++ .../unit/out/unsafe/union_struct_dual_use.rs | 60 +++++++ .../unit/out/unsafe/union_tagged_many_arms.rs | 59 +++++++ tests/unit/out/unsafe/union_tagged_simple.rs | 45 ++++++ .../out/unsafe/union_tagged_struct_arms.rs | 86 ++++++++++ .../out/unsafe/union_void_ptr_sized_deref.rs | 83 ++++++++++ 25 files changed, 1635 insertions(+) create mode 100644 tests/unit/out/refcount/union_cross_arm_cast.rs create mode 100644 tests/unit/out/refcount/union_field_alignment.rs create mode 100644 tests/unit/out/refcount/union_flex_array_member.rs create mode 100644 tests/unit/out/refcount/union_memset_memcpy.rs create mode 100644 tests/unit/out/refcount/union_nested.rs create mode 100644 tests/unit/out/refcount/union_pointer_pun_address.rs create mode 100644 tests/unit/out/refcount/union_pointer_pun_writethrough.rs create mode 100644 tests/unit/out/refcount/union_struct_dual_use.rs create mode 100644 tests/unit/out/refcount/union_tagged_many_arms.rs create mode 100644 tests/unit/out/refcount/union_tagged_simple.rs create mode 100644 tests/unit/out/refcount/union_tagged_struct_arms.rs create mode 100644 tests/unit/out/refcount/union_void_ptr_sized_deref.rs create mode 100644 tests/unit/out/unsafe/union_addrof_external.rs create mode 100644 tests/unit/out/unsafe/union_cross_arm_cast.rs create mode 100644 tests/unit/out/unsafe/union_field_alignment.rs create mode 100644 tests/unit/out/unsafe/union_flex_array_member.rs create mode 100644 tests/unit/out/unsafe/union_memset_memcpy.rs create mode 100644 tests/unit/out/unsafe/union_nested.rs create mode 100644 tests/unit/out/unsafe/union_pointer_pun_address.rs create mode 100644 tests/unit/out/unsafe/union_pointer_pun_writethrough.rs create mode 100644 tests/unit/out/unsafe/union_struct_dual_use.rs create mode 100644 tests/unit/out/unsafe/union_tagged_many_arms.rs create mode 100644 tests/unit/out/unsafe/union_tagged_simple.rs create mode 100644 tests/unit/out/unsafe/union_tagged_struct_arms.rs create mode 100644 tests/unit/out/unsafe/union_void_ptr_sized_deref.rs diff --git a/tests/unit/out/refcount/union_cross_arm_cast.rs b/tests/unit/out/refcount/union_cross_arm_cast.rs new file mode 100644 index 00000000..20e0d2eb --- /dev/null +++ b/tests/unit/out/refcount/union_cross_arm_cast.rs @@ -0,0 +1,80 @@ +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}; +#[derive()] +pub struct shape_a { + pub code: Value, + pub pad: Value>, +} +impl ByteRepr for shape_a {} +#[derive()] +pub struct shape_b { + pub code: Value, + pub lo: Value, + pub mid: Value, + pub fill: Value>, + pub tail: Value, +} +impl ByteRepr for shape_b {} +#[derive()] +pub struct Container_anon_0 { + pub a: Value, + pub b: Value, + pub raw_: Value>, +} +impl ByteRepr for Container_anon_0 {} +#[derive(Default)] +pub struct Container { + pub len: Value, + pub u: Value, +} +impl ByteRepr for Container {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let c: Value = >::default(); + { + ((c.as_pointer()) as Ptr).to_any().memset( + (0) as u8, + ::std::mem::size_of::() as u64 as usize, + ); + ((c.as_pointer()) as Ptr).to_any().clone() + }; + (*(*(*(*c.borrow()).u.borrow()).a.borrow()).code.borrow_mut()) = 10_u16; + (*(*c.borrow()).len.borrow_mut()) = (::std::mem::size_of::() as u64 as u32); + (*(*((((*(*c.borrow()).u.borrow()).a.as_pointer()) + .to_strong() + .as_pointer() as AnyPtr) + .cast::() + .expect("ub:wrong type")) + .upgrade() + .deref()) + .tail + .borrow_mut()) = 3735928559_u32; + assert!(((*(*(*(*c.borrow()).u.borrow()).b.borrow()).tail.borrow()) == 3735928559_u32)); + assert!((((*(*(*(*c.borrow()).u.borrow()).b.borrow()).code.borrow()) as i32) == 10)); + (*(*(*(*c.borrow()).u.borrow()).b.borrow()).lo.borrow_mut()) = 8080_u16; + assert!( + ((((((*(*c.borrow()).u.borrow()).raw_.as_pointer()) + .to_strong() + .as_pointer() as Ptr::) + .offset((2) as isize) + .read()) as i32) + == 144) + ); + assert!( + ((((((*(*c.borrow()).u.borrow()).raw_.as_pointer()) + .to_strong() + .as_pointer() as Ptr::) + .offset((3) as isize) + .read()) as i32) + == 31) + ); + return 0; +} diff --git a/tests/unit/out/refcount/union_field_alignment.rs b/tests/unit/out/refcount/union_field_alignment.rs new file mode 100644 index 00000000..3601f78e --- /dev/null +++ b/tests/unit/out/refcount/union_field_alignment.rs @@ -0,0 +1,30 @@ +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}; +#[derive()] +pub struct node_anon_0 { + pub bytes: Value>, + pub aligner: Value, +} +impl ByteRepr for node_anon_0 {} +#[derive(Default)] +pub struct node { + pub next: Value>, + pub x: Value, +} +impl ByteRepr for node {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let n: Value = >::default(); + (*(*n.borrow()).next.borrow_mut()) = Default::default(); + (*(*(*n.borrow()).x.borrow()).bytes.borrow_mut())[(0) as usize] = 171_u8; + assert!((((*(*(*n.borrow()).x.borrow()).bytes.borrow())[(0) as usize] as i32) == 171)); + return 0; +} diff --git a/tests/unit/out/refcount/union_flex_array_member.rs b/tests/unit/out/refcount/union_flex_array_member.rs new file mode 100644 index 00000000..56d7ef0e --- /dev/null +++ b/tests/unit/out/refcount/union_flex_array_member.rs @@ -0,0 +1,73 @@ +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}; +#[derive()] +pub struct node_anon_0 { + pub bytes: Value>, + pub aligner: Value, +} +impl ByteRepr for node_anon_0 {} +#[derive(Default)] +pub struct node { + pub len: Value, + pub x: Value, +} +impl ByteRepr for node {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let tail_size: Value = Rc::new(RefCell::new(32_u64)); + let n: Value> = Rc::new(RefCell::new( + ({ + let ___size: u64 = + (::std::mem::size_of::() as u64 as u64).wrapping_add((*tail_size.borrow())); + malloc_0(___size) + }) + .cast::() + .expect("ub:wrong type"), + )); + (*(*(*n.borrow()).upgrade().deref()).len.borrow_mut()) = (*tail_size.borrow()); + let i: Value = Rc::new(RefCell::new(0_u64)); + 'loop_: while ((*i.borrow()) < (*tail_size.borrow())) { + let __rhs = ((((*i.borrow()) & 255_u64) as u64) as u8); + (*(*(*(*n.borrow()).upgrade().deref()).x.borrow()) + .bytes + .borrow_mut())[(*i.borrow()) as usize] = __rhs; + (*i.borrow_mut()).postfix_inc(); + } + let i: Value = Rc::new(RefCell::new(0_u64)); + 'loop_: while ((*i.borrow()) < (*tail_size.borrow())) { + assert!({ + let _lhs = ((*(*(*(*n.borrow()).upgrade().deref()).x.borrow()) + .bytes + .borrow())[(*i.borrow()) as usize] as i32); + _lhs == (((((*i.borrow()) & 255_u64) as u64) as u8) as i32) + }); + (*i.borrow_mut()).postfix_inc(); + } + let p: Value> = Rc::new(RefCell::new( + (((*(*(*n.borrow()).upgrade().deref()).x.borrow()) + .bytes + .as_pointer() as Ptr) + .offset(10 as isize)), + )); + assert!(((((*p.borrow()).read()) as i32) == 10)); + (*p.borrow()).write(170_u8); + assert!( + (((*(*(*(*n.borrow()).upgrade().deref()).x.borrow()) + .bytes + .borrow())[(10) as usize] as i32) + == 170) + ); + ({ + let ___ptr: AnyPtr = ((*n.borrow()).clone() as Ptr).to_any(); + free_1(___ptr) + }); + return 0; +} diff --git a/tests/unit/out/refcount/union_memset_memcpy.rs b/tests/unit/out/refcount/union_memset_memcpy.rs new file mode 100644 index 00000000..fbb55430 --- /dev/null +++ b/tests/unit/out/refcount/union_memset_memcpy.rs @@ -0,0 +1,107 @@ +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}; +#[derive()] +pub struct shape_a { + pub code: Value, + pub pad: Value>, +} +impl ByteRepr for shape_a {} +#[derive()] +pub struct shape_b { + pub code: Value, + pub lo: Value, + pub hi: Value, + pub fill: Value>, +} +impl ByteRepr for shape_b {} +#[derive()] +pub struct Container_anon_0 { + pub a: Value, + pub b: Value, + pub raw_: Value>, +} +impl ByteRepr for Container_anon_0 {} +#[derive(Default)] +pub struct Container { + pub view: Value, +} +impl ByteRepr for Container {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let c: Value = >::default(); + { + ((c.as_pointer()) as Ptr).to_any().memset( + (0) as u8, + ::std::mem::size_of::() as u64 as usize, + ); + ((c.as_pointer()) as Ptr).to_any().clone() + }; + assert!((((*(*(*(*c.borrow()).view.borrow()).a.borrow()).code.borrow()) as i32) == 0)); + assert!((((*(*(*(*c.borrow()).view.borrow()).b.borrow()).lo.borrow()) as i32) == 0)); + assert!((((*(*(*c.borrow()).view.borrow()).raw_.borrow())[(0) as usize] as i32) == 0)); + assert!((((*(*(*c.borrow()).view.borrow()).raw_.borrow())[(255) as usize] as i32) == 0)); + let src: Value> = Rc::new(RefCell::new(Box::new([ + 0_u8, + ::default(), + ::default(), + ::default(), + ::default(), + ::default(), + ::default(), + ::default(), + ::default(), + ::default(), + ::default(), + ::default(), + ::default(), + ::default(), + ::default(), + ::default(), + ]))); + (*src.borrow_mut())[(0) as usize] = 2_u8; + (*src.borrow_mut())[(2) as usize] = 80_u8; + (*src.borrow_mut())[(3) as usize] = 0_u8; + (*src.borrow_mut())[(4) as usize] = 127_u8; + (*src.borrow_mut())[(5) as usize] = 0_u8; + (*src.borrow_mut())[(6) as usize] = 0_u8; + (*src.borrow_mut())[(7) as usize] = 1_u8; + let len: Value = Rc::new(RefCell::new(16_u64)); + assert!(((*len.borrow()) <= ::std::mem::size_of::<[u8; 256]>() as u64)); + { + (((*(*c.borrow()).view.borrow()).raw_.as_pointer()) as Ptr) + .to_any() + .memcpy( + &((src.as_pointer() as Ptr) as Ptr).to_any(), + (*len.borrow()) as usize, + ); + (((*(*c.borrow()).view.borrow()).raw_.as_pointer()) as Ptr) + .to_any() + .clone() + }; + assert!((((*(*(*(*c.borrow()).view.borrow()).b.borrow()).code.borrow()) as i32) == 2)); + assert!( + ((((((*(*(*c.borrow()).view.borrow()).b.borrow()).lo.as_pointer()) + .to_strong() + .as_pointer() as Ptr::) + .offset((0) as isize) + .read()) as i32) + == 80) + ); + { + ((c.as_pointer()) as Ptr).to_any().memset( + (0) as u8, + ::std::mem::size_of::() as u64 as usize, + ); + ((c.as_pointer()) as Ptr).to_any().clone() + }; + assert!((((*(*(*(*c.borrow()).view.borrow()).b.borrow()).code.borrow()) as i32) == 0)); + return 0; +} diff --git a/tests/unit/out/refcount/union_nested.rs b/tests/unit/out/refcount/union_nested.rs new file mode 100644 index 00000000..d8322734 --- /dev/null +++ b/tests/unit/out/refcount/union_nested.rs @@ -0,0 +1,78 @@ +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}; +#[derive()] +pub struct record { + pub code: Value, + pub pad: Value>, +} +impl ByteRepr for record {} +#[derive()] +pub struct inner_anon_0 { + pub h: Value, + pub raw_: Value>, +} +impl ByteRepr for inner_anon_0 {} +#[derive(Default)] +pub struct inner { + pub view: Value, +} +impl ByteRepr for inner {} +#[derive(Default)] +pub struct Outer_anon_0 { + pub h: Value, + pub nested: Value, +} +impl ByteRepr for Outer_anon_0 {} +#[derive(Default)] +pub struct Outer { + pub kind: Value, + pub level: Value, + pub variant: Value, + pub len: Value, + pub body: Value, +} +impl ByteRepr for Outer {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let ex: Value = >::default(); + { + ((ex.as_pointer()) as Ptr) + .to_any() + .memset((0) as u8, ::std::mem::size_of::() as u64 as usize); + ((ex.as_pointer()) as Ptr).to_any().clone() + }; + (*(*ex.borrow()).kind.borrow_mut()) = 2; + (*(*ex.borrow()).level.borrow_mut()) = 1; + (*(*ex.borrow()).variant.borrow_mut()) = 6; + (*(*ex.borrow()).len.borrow_mut()) = (::std::mem::size_of::() as u64 as u32); + (*(*(*(*ex.borrow()).body.borrow()).h.borrow()) + .code + .borrow_mut()) = 2_u16; + (*(*(*(*ex.borrow()).body.borrow()).h.borrow()) + .pad + .borrow_mut())[(0) as usize] = (('X' as i32) as u8); + assert!((((*(*(*(*ex.borrow()).body.borrow()).h.borrow()).code.borrow()) as i32) == 2)); + assert!( + (((*(*(*(*ex.borrow()).body.borrow()).h.borrow()).pad.borrow())[(0) as usize] as i32) + == ('X' as i32)) + ); + assert!( + (((*(*(*(*(*(*ex.borrow()).body.borrow()).nested.borrow()) + .view + .borrow()) + .h + .borrow()) + .code + .borrow()) as i32) + == 2) + ); + return 0; +} diff --git a/tests/unit/out/refcount/union_pointer_pun_address.rs b/tests/unit/out/refcount/union_pointer_pun_address.rs new file mode 100644 index 00000000..bbe33b8a --- /dev/null +++ b/tests/unit/out/refcount/union_pointer_pun_address.rs @@ -0,0 +1,41 @@ +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}; +#[derive(Default)] +pub struct node_a { + pub n: Value, +} +impl ByteRepr for node_a {} +#[derive(Default)] +pub struct node_b { + pub data: Value, + pub next: Value>, +} +impl ByteRepr for node_b {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let a: Value = Rc::new(RefCell::new(node_a { + n: Rc::new(RefCell::new(123)), + })); + #[derive(Default)] + pub struct anon_0 { + pub to_a: Value>, + pub to_b: Value>, + } + impl ByteRepr for anon_0 {}; + let ptr: Value = >::default(); + (*(*ptr.borrow()).to_a.borrow_mut()) = (a.as_pointer()); + let out: Value> = Rc::new(RefCell::new((*(*ptr.borrow()).to_b.borrow()).clone())); + assert!({ + let _lhs = ((*out.borrow()).to_strong().as_pointer() as AnyPtr).clone(); + _lhs == ((a.as_pointer()).to_strong().as_pointer() as AnyPtr) + }); + return 0; +} diff --git a/tests/unit/out/refcount/union_pointer_pun_writethrough.rs b/tests/unit/out/refcount/union_pointer_pun_writethrough.rs new file mode 100644 index 00000000..c6c6960b --- /dev/null +++ b/tests/unit/out/refcount/union_pointer_pun_writethrough.rs @@ -0,0 +1,25 @@ +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 fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let x: Value = Rc::new(RefCell::new((-1_i32 as i64))); + #[derive(Default)] + pub struct anon_0 { + pub as_unsigned: Value>, + pub as_signed: Value>, + } + impl ByteRepr for anon_0 {}; + let pp: Value = >::default(); + (*(*pp.borrow()).as_signed.borrow_mut()) = (x.as_pointer()); + (*(*pp.borrow()).as_unsigned.borrow()).write(42_u64); + assert!(((*x.borrow()) == 42_i64)); + return 0; +} diff --git a/tests/unit/out/refcount/union_struct_dual_use.rs b/tests/unit/out/refcount/union_struct_dual_use.rs new file mode 100644 index 00000000..2e1989c3 --- /dev/null +++ b/tests/unit/out/refcount/union_struct_dual_use.rs @@ -0,0 +1,68 @@ +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}; +#[derive(Default)] +pub struct Inner { + pub a: Value, + pub b: Value, +} +impl ByteRepr for Inner {} +pub fn sum_inner_0(i: Ptr) -> i32 { + let i: Value> = Rc::new(RefCell::new(i)); + return { + let _lhs = (*(*(*i.borrow()).upgrade().deref()).a.borrow()); + _lhs + (*(*(*i.borrow()).upgrade().deref()).b.borrow()) + }; +} +#[derive()] +pub struct Outer_anon_0 { + pub inner: Value, + pub raw_: Value>, +} +impl ByteRepr for Outer_anon_0 {} +#[derive(Default)] +pub struct Outer { + pub u: Value, +} +impl ByteRepr for Outer {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let standalone: Value = >::default(); + (*(*standalone.borrow()).a.borrow_mut()) = 3; + (*(*standalone.borrow()).b.borrow_mut()) = 4; + assert!( + (({ + let _i: Ptr = (standalone.as_pointer()); + sum_inner_0(_i) + }) == 7) + ); + let outer: Value = >::default(); + { + ((outer.as_pointer()) as Ptr) + .to_any() + .memset((0) as u8, ::std::mem::size_of::() as u64 as usize); + ((outer.as_pointer()) as Ptr).to_any().clone() + }; + (*(*(*(*outer.borrow()).u.borrow()).inner.borrow()) + .a + .borrow_mut()) = 3; + (*(*(*(*outer.borrow()).u.borrow()).inner.borrow()) + .b + .borrow_mut()) = 4; + assert!( + (({ + let _i: Ptr = ((*(*outer.borrow()).u.borrow()).inner.as_pointer()); + sum_inner_0(_i) + }) == 7) + ); + assert!(((((*(*(*outer.borrow()).u.borrow()).raw_.borrow())[(0) as usize] as u8) as i32) == 3)); + assert!(((((*(*(*outer.borrow()).u.borrow()).raw_.borrow())[(4) as usize] as u8) as i32) == 4)); + return 0; +} diff --git a/tests/unit/out/refcount/union_tagged_many_arms.rs b/tests/unit/out/refcount/union_tagged_many_arms.rs new file mode 100644 index 00000000..87d63663 --- /dev/null +++ b/tests/unit/out/refcount/union_tagged_many_arms.rs @@ -0,0 +1,69 @@ +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}; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Tag { + #[default] + T_NUM_S = 0, + T_NUM_U = 1, + T_TEXT = 2, + T_FLOAT = 3, + T_REF = 4, +} +#[derive(Default)] +pub struct Slot_anon_0 { + pub text: Value>, + pub handle: Value, + pub signed_n: Value, + pub unsigned_n: Value, + pub f: Value, +} +impl ByteRepr for Slot_anon_0 {} +#[derive(Default)] +pub struct Slot { + pub tag: Value, + pub payload: Value, +} +impl ByteRepr for Slot {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let a: Value = >::default(); + (*(*a.borrow()).tag.borrow_mut()) = (Tag::T_NUM_S as Tag); + (*(*(*a.borrow()).payload.borrow()).signed_n.borrow_mut()) = (-7_i32 as i64); + assert!(((*(*(*a.borrow()).payload.borrow()).signed_n.borrow()) == (-7_i32 as i64))); + let b: Value = >::default(); + (*(*b.borrow()).tag.borrow_mut()) = (Tag::T_NUM_U as Tag); + (*(*(*b.borrow()).payload.borrow()).unsigned_n.borrow_mut()) = 3735928559_u64; + assert!(((*(*(*b.borrow()).payload.borrow()).unsigned_n.borrow()) == 3735928559_u64)); + let c: Value = >::default(); + (*(*c.borrow()).tag.borrow_mut()) = (Tag::T_TEXT as Tag); + (*(*(*c.borrow()).payload.borrow()).text.borrow_mut()) = + (Ptr::from_string_literal("hello")).clone(); + assert!( + ((((*(*(*c.borrow()).payload.borrow()).text.borrow()) + .offset((0) as isize) + .read()) as i32) + == ('h' as i32)) + ); + let d: Value = >::default(); + (*(*d.borrow()).tag.borrow_mut()) = (Tag::T_FLOAT as Tag); + (*(*(*d.borrow()).payload.borrow()).f.borrow_mut()) = 1.5E+0; + assert!(((*(*(*d.borrow()).payload.borrow()).f.borrow()) == 1.5E+0)); + let x: Value = Rc::new(RefCell::new(0)); + let e: Value = >::default(); + (*(*e.borrow()).tag.borrow_mut()) = (Tag::T_REF as Tag); + (*(*(*e.borrow()).payload.borrow()).handle.borrow_mut()) = + ((x.as_pointer()) as Ptr).to_any(); + assert!({ + let _lhs = (*(*(*e.borrow()).payload.borrow()).handle.borrow()).clone(); + _lhs == ((x.as_pointer()) as Ptr).to_any() + }); + return 0; +} diff --git a/tests/unit/out/refcount/union_tagged_simple.rs b/tests/unit/out/refcount/union_tagged_simple.rs new file mode 100644 index 00000000..fcb54840 --- /dev/null +++ b/tests/unit/out/refcount/union_tagged_simple.rs @@ -0,0 +1,49 @@ +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}; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Kind { + #[default] + KIND_NONE = 0, + KIND_DONE = 1, +} +#[derive(Default)] +pub struct Event_anon_0 { + pub obj: Value, + pub code: Value, +} +impl ByteRepr for Event_anon_0 {} +#[derive(Default)] +pub struct Event { + pub kind: Value, + pub handle: Value, + pub payload: Value, +} +impl ByteRepr for Event {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let dummy: Value = Rc::new(RefCell::new(0)); + let m1: Value = >::default(); + (*(*m1.borrow()).kind.borrow_mut()) = (Kind::KIND_DONE as Kind); + (*(*m1.borrow()).handle.borrow_mut()) = ((dummy.as_pointer()) as Ptr).to_any(); + (*(*(*m1.borrow()).payload.borrow()).code.borrow_mut()) = 42; + assert!((((*(*m1.borrow()).kind.borrow()) as u32) == (Kind::KIND_DONE as u32))); + assert!(((*(*(*m1.borrow()).payload.borrow()).code.borrow()) == 42)); + let m2: Value = >::default(); + (*(*m2.borrow()).kind.borrow_mut()) = (Kind::KIND_NONE as Kind); + (*(*m2.borrow()).handle.borrow_mut()) = ((dummy.as_pointer()) as Ptr).to_any(); + (*(*(*m2.borrow()).payload.borrow()).obj.borrow_mut()) = + ((dummy.as_pointer()) as Ptr).to_any(); + assert!({ + let _lhs = (*(*(*m2.borrow()).payload.borrow()).obj.borrow()).clone(); + _lhs == ((dummy.as_pointer()) as Ptr).to_any() + }); + return 0; +} diff --git a/tests/unit/out/refcount/union_tagged_struct_arms.rs b/tests/unit/out/refcount/union_tagged_struct_arms.rs new file mode 100644 index 00000000..52dc5c9a --- /dev/null +++ b/tests/unit/out/refcount/union_tagged_struct_arms.rs @@ -0,0 +1,148 @@ +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}; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Choice { + #[default] + C_LIST = 1, + C_LETTERS = 2, + C_INTEGERS = 3, +} +#[derive(Default)] +pub struct Branch_anon_0_anon_0 { + pub items: Value>>, + pub count: Value, + pub cursor: Value, +} +impl ByteRepr for Branch_anon_0_anon_0 {} +#[derive(Default)] +pub struct Branch_anon_0_anon_1 { + pub lo: Value, + pub hi: Value, + pub curr: Value, + pub step: Value, +} +impl ByteRepr for Branch_anon_0_anon_1 {} +#[derive(Default)] +pub struct Branch_anon_0_anon_2 { + pub lo: Value, + pub hi: Value, + pub curr: Value, + pub step: Value, + pub width: Value, +} +impl ByteRepr for Branch_anon_0_anon_2 {} +#[derive(Default)] +pub struct Branch_anon_0 { + pub list: Value, + pub letters: Value, + pub integers: Value, +} +impl ByteRepr for Branch_anon_0 {} +#[derive(Default)] +pub struct Branch { + pub choice: Value, + pub index: Value, + pub v: Value, +} +impl ByteRepr for Branch {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + thread_local!( + static items: Value]>> = Rc::new(RefCell::new(Box::new([ + Ptr::from_string_literal("a"), + Ptr::from_string_literal("b"), + Ptr::from_string_literal("c"), + ]))); + ); + let p_list: Value = >::default(); + (*(*p_list.borrow()).choice.borrow_mut()) = (Choice::C_LIST as Choice); + (*(*p_list.borrow()).index.borrow_mut()) = 0; + (*(*(*(*p_list.borrow()).v.borrow()).list.borrow()) + .items + .borrow_mut()) = (items.with(Value::clone).as_pointer() as Ptr>); + (*(*(*(*p_list.borrow()).v.borrow()).list.borrow()) + .count + .borrow_mut()) = 3_i64; + (*(*(*(*p_list.borrow()).v.borrow()).list.borrow()) + .cursor + .borrow_mut()) = 1_i64; + assert!( + ((*(*(*(*p_list.borrow()).v.borrow()).list.borrow()) + .count + .borrow()) + == 3_i64) + ); + assert!( + (((((*(*(*(*p_list.borrow()).v.borrow()).list.borrow()) + .items + .borrow()) + .offset((1) as isize) + .read()) + .offset((0) as isize) + .read()) as i32) + == ('b' as i32)) + ); + let p_letters: Value = >::default(); + (*(*p_letters.borrow()).choice.borrow_mut()) = (Choice::C_LETTERS as Choice); + (*(*p_letters.borrow()).index.borrow_mut()) = 1; + (*(*(*(*p_letters.borrow()).v.borrow()).letters.borrow()) + .lo + .borrow_mut()) = ('a' as i32); + (*(*(*(*p_letters.borrow()).v.borrow()).letters.borrow()) + .hi + .borrow_mut()) = ('z' as i32); + (*(*(*(*p_letters.borrow()).v.borrow()).letters.borrow()) + .curr + .borrow_mut()) = ('m' as i32); + (*(*(*(*p_letters.borrow()).v.borrow()).letters.borrow()) + .step + .borrow_mut()) = 1_u8; + assert!( + (((*(*(*(*p_letters.borrow()).v.borrow()).letters.borrow()) + .hi + .borrow()) + - (*(*(*(*p_letters.borrow()).v.borrow()).letters.borrow()) + .lo + .borrow())) + == 25) + ); + let p_integers: Value = >::default(); + (*(*p_integers.borrow()).choice.borrow_mut()) = (Choice::C_INTEGERS as Choice); + (*(*p_integers.borrow()).index.borrow_mut()) = 2; + (*(*(*(*p_integers.borrow()).v.borrow()).integers.borrow()) + .lo + .borrow_mut()) = 1_i64; + (*(*(*(*p_integers.borrow()).v.borrow()).integers.borrow()) + .hi + .borrow_mut()) = 100_i64; + (*(*(*(*p_integers.borrow()).v.borrow()).integers.borrow()) + .curr + .borrow_mut()) = 1_i64; + (*(*(*(*p_integers.borrow()).v.borrow()).integers.borrow()) + .step + .borrow_mut()) = 1_i64; + (*(*(*(*p_integers.borrow()).v.borrow()).integers.borrow()) + .width + .borrow_mut()) = 3; + assert!( + ((*(*(*(*p_integers.borrow()).v.borrow()).integers.borrow()) + .hi + .borrow()) + == 100_i64) + ); + assert!( + ((*(*(*(*p_integers.borrow()).v.borrow()).integers.borrow()) + .width + .borrow()) + == 3) + ); + return 0; +} diff --git a/tests/unit/out/refcount/union_void_ptr_sized_deref.rs b/tests/unit/out/refcount/union_void_ptr_sized_deref.rs new file mode 100644 index 00000000..d07cc4a7 --- /dev/null +++ b/tests/unit/out/refcount/union_void_ptr_sized_deref.rs @@ -0,0 +1,103 @@ +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}; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Width { + #[default] + W_64 = 0, + W_32 = 1, + W_16 = 2, +} +#[derive(Default)] +pub struct Sink_anon_0 { + pub text: Value>, + pub handle: Value, + pub signed_n: Value, + pub f: Value, +} +impl ByteRepr for Sink_anon_0 {} +#[derive(Default)] +pub struct Sink { + pub width: Value, + pub out: Value, +} +impl ByteRepr for Sink {} +pub fn write_count_0(s: Ptr, count: i64) { + let s: Value> = Rc::new(RefCell::new(s)); + let count: Value = Rc::new(RefCell::new(count)); + 'switch: { + let __match_cond = ((*(*(*s.borrow()).upgrade().deref()).width.borrow()) as u32); + match __match_cond { + v if v == (Width::W_64 as u32) => { + (*(*(*(*s.borrow()).upgrade().deref()).out.borrow()) + .handle + .borrow()) + .cast::() + .expect("ub:wrong type") + .write((*count.borrow())); + break 'switch; + } + v if v == (Width::W_32 as u32) => { + (*(*(*(*s.borrow()).upgrade().deref()).out.borrow()) + .handle + .borrow()) + .cast::() + .expect("ub:wrong type") + .write(((*count.borrow()) as i32)); + break 'switch; + } + v if v == (Width::W_16 as u32) => { + (*(*(*(*s.borrow()).upgrade().deref()).out.borrow()) + .handle + .borrow()) + .cast::() + .expect("ub:wrong type") + .write(((*count.borrow()) as i16)); + break 'switch; + } + _ => {} + } + }; +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let buf64: Value = Rc::new(RefCell::new(0_i64)); + let buf32: Value = Rc::new(RefCell::new(0)); + let buf16: Value = Rc::new(RefCell::new(0_i16)); + let s: Value = >::default(); + (*(*s.borrow()).width.borrow_mut()) = (Width::W_64 as Width); + (*(*(*s.borrow()).out.borrow()).handle.borrow_mut()) = + ((buf64.as_pointer()) as Ptr).to_any(); + ({ + let _s: Ptr = (s.as_pointer()); + let _count: i64 = 1234605616436508552_i64; + write_count_0(_s, _count) + }); + assert!(((*buf64.borrow()) == 1234605616436508552_i64)); + (*(*s.borrow()).width.borrow_mut()) = (Width::W_32 as Width); + (*(*(*s.borrow()).out.borrow()).handle.borrow_mut()) = + ((buf32.as_pointer()) as Ptr).to_any(); + ({ + let _s: Ptr = (s.as_pointer()); + let _count: i64 = 305419896_i64; + write_count_0(_s, _count) + }); + assert!(((*buf32.borrow()) == 305419896)); + (*(*s.borrow()).width.borrow_mut()) = (Width::W_16 as Width); + (*(*(*s.borrow()).out.borrow()).handle.borrow_mut()) = + ((buf16.as_pointer()) as Ptr).to_any(); + ({ + let _s: Ptr = (s.as_pointer()); + let _count: i64 = 4660_i64; + write_count_0(_s, _count) + }); + assert!((((*buf16.borrow()) as i32) == 4660)); + return 0; +} diff --git a/tests/unit/out/unsafe/union_addrof_external.rs b/tests/unit/out/unsafe/union_addrof_external.rs new file mode 100644 index 00000000..9181620f --- /dev/null +++ b/tests/unit/out/unsafe/union_addrof_external.rs @@ -0,0 +1,81 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Copy, Clone)] +pub struct record { + pub code: u16, + pub lo: u16, + pub hi: u32, + pub pad: [u8; 8], +} +#[derive(Copy, Clone)] +pub struct Container_anon_0 { + pub h: record, + pub raw_: [u8; 128], +} +#[derive(Copy, Clone, Default)] +pub struct Container { + pub view: Container_anon_0, +} +pub unsafe fn fill_0(mut out: *mut ::libc::c_void, mut cap: u64) { + let mut src: [u8; 16] = [ + 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, + 0_u8, + ]; + src[(0) as usize] = 2_u8; + src[(1) as usize] = 0_u8; + src[(2) as usize] = 0_u8; + src[(3) as usize] = 80_u8; + src[(4) as usize] = 127_u8; + src[(5) as usize] = 0_u8; + src[(6) as usize] = 0_u8; + src[(7) as usize] = 1_u8; + let mut n: u64 = if ((::std::mem::size_of::<[u8; 16]>() as u64) < (cap)) { + ::std::mem::size_of::<[u8; 16]>() as u64 + } else { + cap + }; + { + if n != 0 { + ::std::ptr::copy_nonoverlapping( + (src.as_mut_ptr() as *const u8 as *const ::libc::c_void), + out, + n as usize, + ) + } + out + }; +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut c: Container = ::default(); + { + let byte_0 = + ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) as *mut u8; + for offset in 0..::std::mem::size_of::() as u64 { + *byte_0.offset(offset as isize) = 0 as u8; + } + ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) + }; + (unsafe { + let _out: *mut ::libc::c_void = + ((&mut c.view as *mut Container_anon_0) as *mut ::libc::c_void); + let _cap: u64 = ::std::mem::size_of::() as u64; + fill_0(_out, _cap) + }); + assert!(((c.view.h.code as i32) == (2))); + assert!((((*((&mut c.view.h.lo as *mut u16) as *mut u8).offset((0) as isize)) as i32) == (0))); + assert!((((*((&mut c.view.h.lo as *mut u16) as *mut u8).offset((1) as isize)) as i32) == (80))); + assert!(((c.view.raw_[(0) as usize] as i32) == (2))); + assert!((((c.view.raw_[(3) as usize] as u8) as i32) == (80))); + return 0; +} diff --git a/tests/unit/out/unsafe/union_cross_arm_cast.rs b/tests/unit/out/unsafe/union_cross_arm_cast.rs new file mode 100644 index 00000000..d93385ce --- /dev/null +++ b/tests/unit/out/unsafe/union_cross_arm_cast.rs @@ -0,0 +1,62 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Copy, Clone)] +pub struct shape_a { + pub code: u16, + pub pad: [u8; 14], +} +#[derive(Copy, Clone)] +pub struct shape_b { + pub code: u16, + pub lo: u16, + pub mid: u32, + pub fill: [u8; 16], + pub tail: u32, +} +#[derive(Copy, Clone)] +pub struct Container_anon_0 { + pub a: shape_a, + pub b: shape_b, + pub raw_: [u8; 64], +} +#[derive(Copy, Clone, Default)] +pub struct Container { + pub len: u32, + pub u: Container_anon_0, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut c: Container = ::default(); + { + let byte_0 = + ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) as *mut u8; + for offset in 0..::std::mem::size_of::() as u64 { + *byte_0.offset(offset as isize) = 0 as u8; + } + ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) + }; + c.u.a.code = 10_u16; + c.len = (::std::mem::size_of::() as u64 as u32); + (*(((&mut c.u.a as *mut shape_a) as *mut ::libc::c_void) as *mut shape_b)).tail = + 3735928559_u32; + assert!(((c.u.b.tail) == (3735928559_u32))); + assert!(((c.u.b.code as i32) == (10))); + c.u.b.lo = 8080_u16; + assert!( + (((*((&mut c.u.raw_ as *mut [u8; 64]) as *mut u8).offset((2) as isize)) as i32) == (144)) + ); + assert!( + (((*((&mut c.u.raw_ as *mut [u8; 64]) as *mut u8).offset((3) as isize)) as i32) == (31)) + ); + return 0; +} diff --git a/tests/unit/out/unsafe/union_field_alignment.rs b/tests/unit/out/unsafe/union_field_alignment.rs new file mode 100644 index 00000000..8441c7d4 --- /dev/null +++ b/tests/unit/out/unsafe/union_field_alignment.rs @@ -0,0 +1,30 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Copy, Clone)] +pub struct node_anon_0 { + pub bytes: [u8; 1], + pub aligner: *mut ::libc::c_void, +} +#[derive(Copy, Clone, Default)] +pub struct node { + pub next: *mut node, + pub x: node_anon_0, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut n: node = ::default(); + n.next = Default::default(); + n.x.bytes[(0) as usize] = 171_u8; + assert!(((n.x.bytes[(0) as usize] as i32) == (171))); + return 0; +} diff --git a/tests/unit/out/unsafe/union_flex_array_member.rs b/tests/unit/out/unsafe/union_flex_array_member.rs new file mode 100644 index 00000000..fcf94b81 --- /dev/null +++ b/tests/unit/out/unsafe/union_flex_array_member.rs @@ -0,0 +1,52 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Copy, Clone)] +pub struct node_anon_0 { + pub bytes: [u8; 1], + pub aligner: *mut ::libc::c_void, +} +#[derive(Copy, Clone, Default)] +pub struct node { + pub len: u64, + pub x: node_anon_0, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut tail_size: u64 = 32_u64; + let mut n: *mut node = ((unsafe { + let ___size: u64 = (::std::mem::size_of::() as u64 as u64).wrapping_add(tail_size); + malloc_0(___size) + }) as *mut node); + (*n).len = tail_size; + let mut i: u64 = 0_u64; + 'loop_: while ((i) < (tail_size)) { + (*n).x.bytes[(i) as usize] = ((((i) & (255_u64)) as u64) as u8); + i.postfix_inc(); + } + let mut i: u64 = 0_u64; + 'loop_: while ((i) < (tail_size)) { + assert!( + (((*n).x.bytes[(i) as usize] as i32) == (((((i) & (255_u64)) as u64) as u8) as i32)) + ); + i.postfix_inc(); + } + let mut p: *mut u8 = (&mut (*n).x.bytes[(10) as usize] as *mut u8); + assert!((((*p) as i32) == (10))); + (*p) = 170_u8; + assert!((((*n).x.bytes[(10) as usize] as i32) == (170))); + (unsafe { + let ___ptr: *mut ::libc::c_void = (n as *mut node as *mut ::libc::c_void); + free_1(___ptr) + }); + return 0; +} diff --git a/tests/unit/out/unsafe/union_memset_memcpy.rs b/tests/unit/out/unsafe/union_memset_memcpy.rs new file mode 100644 index 00000000..47354e9d --- /dev/null +++ b/tests/unit/out/unsafe/union_memset_memcpy.rs @@ -0,0 +1,85 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Copy, Clone)] +pub struct shape_a { + pub code: u16, + pub pad: [u8; 14], +} +#[derive(Copy, Clone)] +pub struct shape_b { + pub code: u16, + pub lo: u16, + pub hi: u32, + pub fill: [u8; 8], +} +#[derive(Copy, Clone)] +pub struct Container_anon_0 { + pub a: shape_a, + pub b: shape_b, + pub raw_: [u8; 256], +} +#[derive(Copy, Clone, Default)] +pub struct Container { + pub view: Container_anon_0, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut c: Container = ::default(); + { + let byte_0 = + ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) as *mut u8; + for offset in 0..::std::mem::size_of::() as u64 { + *byte_0.offset(offset as isize) = 0 as u8; + } + ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) + }; + assert!(((c.view.a.code as i32) == (0))); + assert!(((c.view.b.lo as i32) == (0))); + assert!(((c.view.raw_[(0) as usize] as i32) == (0))); + assert!(((c.view.raw_[(255) as usize] as i32) == (0))); + let mut src: [u8; 16] = [ + 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, + 0_u8, + ]; + src[(0) as usize] = 2_u8; + src[(2) as usize] = 80_u8; + src[(3) as usize] = 0_u8; + src[(4) as usize] = 127_u8; + src[(5) as usize] = 0_u8; + src[(6) as usize] = 0_u8; + src[(7) as usize] = 1_u8; + let mut len: u64 = 16_u64; + assert!(((len) <= (::std::mem::size_of::<[u8; 256]>() as u64))); + { + if len != 0 { + ::std::ptr::copy_nonoverlapping( + (src.as_mut_ptr() as *const u8 as *const ::libc::c_void), + ((&mut c.view.raw_ as *mut [u8; 256]) as *mut [u8; 256] as *mut ::libc::c_void), + len as usize, + ) + } + ((&mut c.view.raw_ as *mut [u8; 256]) as *mut [u8; 256] as *mut ::libc::c_void) + }; + assert!(((c.view.b.code as i32) == (2))); + assert!((((*((&mut c.view.b.lo as *mut u16) as *mut u8).offset((0) as isize)) as i32) == (80))); + { + let byte_0 = + ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) as *mut u8; + for offset in 0..::std::mem::size_of::() as u64 { + *byte_0.offset(offset as isize) = 0 as u8; + } + ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) + }; + assert!(((c.view.b.code as i32) == (0))); + return 0; +} diff --git a/tests/unit/out/unsafe/union_nested.rs b/tests/unit/out/unsafe/union_nested.rs new file mode 100644 index 00000000..ba0822fb --- /dev/null +++ b/tests/unit/out/unsafe/union_nested.rs @@ -0,0 +1,60 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Copy, Clone)] +pub struct record { + pub code: u16, + pub pad: [u8; 14], +} +#[derive(Copy, Clone)] +pub struct inner_anon_0 { + pub h: record, + pub raw_: [u8; 128], +} +#[derive(Copy, Clone, Default)] +pub struct inner { + pub view: inner_anon_0, +} +#[derive(Copy, Clone, Default)] +pub struct Outer_anon_0 { + pub h: record, + pub nested: inner, +} +#[derive(Copy, Clone, Default)] +pub struct Outer { + pub kind: i32, + pub level: i32, + pub variant: i32, + pub len: u32, + pub body: Outer_anon_0, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut ex: Outer = ::default(); + { + let byte_0 = ((&mut ex as *mut Outer) as *mut Outer as *mut ::libc::c_void) as *mut u8; + for offset in 0..::std::mem::size_of::() as u64 { + *byte_0.offset(offset as isize) = 0 as u8; + } + ((&mut ex as *mut Outer) as *mut Outer as *mut ::libc::c_void) + }; + ex.kind = 2; + ex.level = 1; + ex.variant = 6; + ex.len = (::std::mem::size_of::() as u64 as u32); + ex.body.h.code = 2_u16; + ex.body.h.pad[(0) as usize] = (('X' as i32) as u8); + assert!(((ex.body.h.code as i32) == (2))); + assert!(((ex.body.h.pad[(0) as usize] as i32) == ('X' as i32))); + assert!(((ex.body.nested.view.h.code as i32) == (2))); + return 0; +} diff --git a/tests/unit/out/unsafe/union_pointer_pun_address.rs b/tests/unit/out/unsafe/union_pointer_pun_address.rs new file mode 100644 index 00000000..ad93126d --- /dev/null +++ b/tests/unit/out/unsafe/union_pointer_pun_address.rs @@ -0,0 +1,35 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Copy, Clone, Default)] +pub struct node_a { + pub n: i32, +} +#[derive(Copy, Clone, Default)] +pub struct node_b { + pub data: *mut ::libc::c_void, + pub next: *mut node_b, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut a: node_a = node_a { n: 123 }; + #[derive(Copy, Clone, Default)] + pub struct anon_0 { + pub to_a: *mut node_a, + pub to_b: *mut node_b, + }; + let mut ptr: anon_0 = ::default(); + ptr.to_a = (&mut a as *mut node_a); + let mut out: *mut node_b = ptr.to_b; + assert!(((out as *mut ::libc::c_void) == ((&mut a as *mut node_a) as *mut ::libc::c_void))); + return 0; +} diff --git a/tests/unit/out/unsafe/union_pointer_pun_writethrough.rs b/tests/unit/out/unsafe/union_pointer_pun_writethrough.rs new file mode 100644 index 00000000..40f7088e --- /dev/null +++ b/tests/unit/out/unsafe/union_pointer_pun_writethrough.rs @@ -0,0 +1,26 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut x: i64 = (-1_i32 as i64); + #[derive(Copy, Clone, Default)] + pub struct anon_0 { + pub as_unsigned: *mut u64, + pub as_signed: *mut i64, + }; + let mut pp: anon_0 = ::default(); + pp.as_signed = (&mut x as *mut i64); + (*pp.as_unsigned) = 42_u64; + assert!(((x) == (42_i64))); + return 0; +} diff --git a/tests/unit/out/unsafe/union_struct_dual_use.rs b/tests/unit/out/unsafe/union_struct_dual_use.rs new file mode 100644 index 00000000..76beecf2 --- /dev/null +++ b/tests/unit/out/unsafe/union_struct_dual_use.rs @@ -0,0 +1,60 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Copy, Clone, Default)] +pub struct Inner { + pub a: i32, + pub b: i32, +} +pub unsafe fn sum_inner_0(mut i: *mut Inner) -> i32 { + return (((*i).a) + ((*i).b)); +} +#[derive(Copy, Clone)] +pub struct Outer_anon_0 { + pub inner: Inner, + pub raw_: [u8; 16], +} +#[derive(Copy, Clone, Default)] +pub struct Outer { + pub u: Outer_anon_0, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut standalone: Inner = ::default(); + standalone.a = 3; + standalone.b = 4; + assert!( + ((unsafe { + let _i: *mut Inner = (&mut standalone as *mut Inner); + sum_inner_0(_i) + }) == (7)) + ); + let mut outer: Outer = ::default(); + { + let byte_0 = ((&mut outer as *mut Outer) as *mut Outer as *mut ::libc::c_void) as *mut u8; + for offset in 0..::std::mem::size_of::() as u64 { + *byte_0.offset(offset as isize) = 0 as u8; + } + ((&mut outer as *mut Outer) as *mut Outer as *mut ::libc::c_void) + }; + outer.u.inner.a = 3; + outer.u.inner.b = 4; + assert!( + ((unsafe { + let _i: *mut Inner = (&mut outer.u.inner as *mut Inner); + sum_inner_0(_i) + }) == (7)) + ); + assert!((((outer.u.raw_[(0) as usize] as u8) as i32) == (3))); + assert!((((outer.u.raw_[(4) as usize] as u8) as i32) == (4))); + return 0; +} diff --git a/tests/unit/out/unsafe/union_tagged_many_arms.rs b/tests/unit/out/unsafe/union_tagged_many_arms.rs new file mode 100644 index 00000000..81817191 --- /dev/null +++ b/tests/unit/out/unsafe/union_tagged_many_arms.rs @@ -0,0 +1,59 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Tag { + #[default] + T_NUM_S = 0, + T_NUM_U = 1, + T_TEXT = 2, + T_FLOAT = 3, + T_REF = 4, +} +#[derive(Copy, Clone, Default)] +pub struct Slot_anon_0 { + pub text: *const u8, + pub handle: *mut ::libc::c_void, + pub signed_n: i64, + pub unsigned_n: u64, + pub f: f64, +} +#[derive(Copy, Clone, Default)] +pub struct Slot { + pub tag: Tag, + pub payload: Slot_anon_0, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut a: Slot = ::default(); + a.tag = (Tag::T_NUM_S as Tag); + a.payload.signed_n = (-7_i32 as i64); + assert!(((a.payload.signed_n) == (-7_i32 as i64))); + let mut b: Slot = ::default(); + b.tag = (Tag::T_NUM_U as Tag); + b.payload.unsigned_n = 3735928559_u64; + assert!(((b.payload.unsigned_n) == (3735928559_u64))); + let mut c: Slot = ::default(); + c.tag = (Tag::T_TEXT as Tag); + c.payload.text = b"hello\0".as_ptr(); + assert!((((*c.payload.text.offset((0) as isize)) as i32) == ('h' as i32))); + let mut d: Slot = ::default(); + d.tag = (Tag::T_FLOAT as Tag); + d.payload.f = 1.5E+0; + assert!(((d.payload.f) == (1.5E+0))); + let mut x: i32 = 0; + let mut e: Slot = ::default(); + e.tag = (Tag::T_REF as Tag); + e.payload.handle = ((&mut x as *mut i32) as *mut i32 as *mut ::libc::c_void); + assert!(((e.payload.handle) == ((&mut x as *mut i32) as *mut i32 as *mut ::libc::c_void))); + return 0; +} diff --git a/tests/unit/out/unsafe/union_tagged_simple.rs b/tests/unit/out/unsafe/union_tagged_simple.rs new file mode 100644 index 00000000..0468df97 --- /dev/null +++ b/tests/unit/out/unsafe/union_tagged_simple.rs @@ -0,0 +1,45 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Kind { + #[default] + KIND_NONE = 0, + KIND_DONE = 1, +} +#[derive(Copy, Clone, Default)] +pub struct Event_anon_0 { + pub obj: *mut ::libc::c_void, + pub code: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Event { + pub kind: Kind, + pub handle: *mut ::libc::c_void, + pub payload: Event_anon_0, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut dummy: i32 = 0; + let mut m1: Event = ::default(); + m1.kind = (Kind::KIND_DONE as Kind); + m1.handle = ((&mut dummy as *mut i32) as *mut i32 as *mut ::libc::c_void); + m1.payload.code = 42; + assert!(((m1.kind as u32) == (Kind::KIND_DONE as u32))); + assert!(((m1.payload.code) == (42))); + let mut m2: Event = ::default(); + m2.kind = (Kind::KIND_NONE as Kind); + m2.handle = ((&mut dummy as *mut i32) as *mut i32 as *mut ::libc::c_void); + m2.payload.obj = ((&mut dummy as *mut i32) as *mut i32 as *mut ::libc::c_void); + assert!(((m2.payload.obj) == ((&mut dummy as *mut i32) as *mut i32 as *mut ::libc::c_void))); + return 0; +} diff --git a/tests/unit/out/unsafe/union_tagged_struct_arms.rs b/tests/unit/out/unsafe/union_tagged_struct_arms.rs new file mode 100644 index 00000000..541a1395 --- /dev/null +++ b/tests/unit/out/unsafe/union_tagged_struct_arms.rs @@ -0,0 +1,86 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Choice { + #[default] + C_LIST = 1, + C_LETTERS = 2, + C_INTEGERS = 3, +} +#[derive(Copy, Clone, Default)] +pub struct Branch_anon_0_anon_0 { + pub items: *mut *mut u8, + pub count: i64, + pub cursor: i64, +} +#[derive(Copy, Clone, Default)] +pub struct Branch_anon_0_anon_1 { + pub lo: i32, + pub hi: i32, + pub curr: i32, + pub step: u8, +} +#[derive(Copy, Clone, Default)] +pub struct Branch_anon_0_anon_2 { + pub lo: i64, + pub hi: i64, + pub curr: i64, + pub step: i64, + pub width: i32, +} +#[derive(Copy, Clone, Default)] +pub struct Branch_anon_0 { + pub list: Branch_anon_0_anon_0, + pub letters: Branch_anon_0_anon_1, + pub integers: Branch_anon_0_anon_2, +} +#[derive(Copy, Clone, Default)] +pub struct Branch { + pub choice: Choice, + pub index: i32, + pub v: Branch_anon_0, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + static mut items: [*mut u8; 3] = [b"a\0".as_ptr(), b"b\0".as_ptr(), b"c\0".as_ptr()];; + let mut p_list: Branch = ::default(); + p_list.choice = (Choice::C_LIST as Choice); + p_list.index = 0; + p_list.v.list.items = items.as_mut_ptr(); + p_list.v.list.count = 3_i64; + p_list.v.list.cursor = 1_i64; + assert!(((p_list.v.list.count) == (3_i64))); + assert!( + (((*(*p_list.v.list.items.offset((1) as isize)).offset((0) as isize)) as i32) + == ('b' as i32)) + ); + let mut p_letters: Branch = ::default(); + p_letters.choice = (Choice::C_LETTERS as Choice); + p_letters.index = 1; + p_letters.v.letters.lo = ('a' as i32); + p_letters.v.letters.hi = ('z' as i32); + p_letters.v.letters.curr = ('m' as i32); + p_letters.v.letters.step = 1_u8; + assert!((((p_letters.v.letters.hi) - (p_letters.v.letters.lo)) == (25))); + let mut p_integers: Branch = ::default(); + p_integers.choice = (Choice::C_INTEGERS as Choice); + p_integers.index = 2; + p_integers.v.integers.lo = 1_i64; + p_integers.v.integers.hi = 100_i64; + p_integers.v.integers.curr = 1_i64; + p_integers.v.integers.step = 1_i64; + p_integers.v.integers.width = 3; + assert!(((p_integers.v.integers.hi) == (100_i64))); + assert!(((p_integers.v.integers.width) == (3))); + return 0; +} diff --git a/tests/unit/out/unsafe/union_void_ptr_sized_deref.rs b/tests/unit/out/unsafe/union_void_ptr_sized_deref.rs new file mode 100644 index 00000000..6b542afb --- /dev/null +++ b/tests/unit/out/unsafe/union_void_ptr_sized_deref.rs @@ -0,0 +1,83 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Width { + #[default] + W_64 = 0, + W_32 = 1, + W_16 = 2, +} +#[derive(Copy, Clone, Default)] +pub struct Sink_anon_0 { + pub text: *const u8, + pub handle: *mut ::libc::c_void, + pub signed_n: i64, + pub f: f64, +} +#[derive(Copy, Clone, Default)] +pub struct Sink { + pub width: Width, + pub out: Sink_anon_0, +} +pub unsafe fn write_count_0(mut s: *mut Sink, mut count: i64) { + 'switch: { + let __match_cond = ((*s).width as u32); + match __match_cond { + v if v == (Width::W_64 as u32) => { + (*((*s).out.handle as *mut i64)) = count; + break 'switch; + } + v if v == (Width::W_32 as u32) => { + (*((*s).out.handle as *mut i32)) = (count as i32); + break 'switch; + } + v if v == (Width::W_16 as u32) => { + (*((*s).out.handle as *mut i16)) = (count as i16); + break 'switch; + } + _ => {} + } + }; +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut buf64: i64 = 0_i64; + let mut buf32: i32 = 0; + let mut buf16: i16 = 0_i16; + let mut s: Sink = ::default(); + s.width = (Width::W_64 as Width); + s.out.handle = ((&mut buf64 as *mut i64) as *mut i64 as *mut ::libc::c_void); + (unsafe { + let _s: *mut Sink = (&mut s as *mut Sink); + let _count: i64 = 1234605616436508552_i64; + write_count_0(_s, _count) + }); + assert!(((buf64) == (1234605616436508552_i64))); + s.width = (Width::W_32 as Width); + s.out.handle = ((&mut buf32 as *mut i32) as *mut i32 as *mut ::libc::c_void); + (unsafe { + let _s: *mut Sink = (&mut s as *mut Sink); + let _count: i64 = 305419896_i64; + write_count_0(_s, _count) + }); + assert!(((buf32) == (305419896))); + s.width = (Width::W_16 as Width); + s.out.handle = ((&mut buf16 as *mut i16) as *mut i16 as *mut ::libc::c_void); + (unsafe { + let _s: *mut Sink = (&mut s as *mut Sink); + let _count: i64 = 4660_i64; + write_count_0(_s, _count) + }); + assert!(((buf16 as i32) == (4660))); + return 0; +} From e8c8a86954b108e74031ec7efec50a7f1b7b13cf Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 28 Apr 2026 11:13:59 +0100 Subject: [PATCH 12/14] Delete no-compile generated files --- tests/lit/lit/formats/Cpp2RustTest.py | 22 +++- .../unit/out/refcount/union_cross_arm_cast.rs | 80 ------------- .../out/refcount/union_field_alignment.rs | 30 ----- .../out/refcount/union_flex_array_member.rs | 73 ------------ .../unit/out/refcount/union_memset_memcpy.rs | 107 ------------------ tests/unit/out/refcount/union_nested.rs | 78 ------------- .../out/refcount/union_pointer_pun_address.rs | 41 ------- .../out/refcount/union_struct_dual_use.rs | 68 ----------- .../unit/out/unsafe/union_addrof_external.rs | 81 ------------- tests/unit/out/unsafe/union_cross_arm_cast.rs | 62 ---------- .../unit/out/unsafe/union_field_alignment.rs | 30 ----- .../out/unsafe/union_flex_array_member.rs | 52 --------- tests/unit/out/unsafe/union_memset_memcpy.rs | 85 -------------- tests/unit/out/unsafe/union_nested.rs | 60 ---------- .../unit/out/unsafe/union_struct_dual_use.rs | 60 ---------- .../out/unsafe/union_tagged_struct_arms.rs | 86 -------------- 16 files changed, 16 insertions(+), 999 deletions(-) delete mode 100644 tests/unit/out/refcount/union_cross_arm_cast.rs delete mode 100644 tests/unit/out/refcount/union_field_alignment.rs delete mode 100644 tests/unit/out/refcount/union_flex_array_member.rs delete mode 100644 tests/unit/out/refcount/union_memset_memcpy.rs delete mode 100644 tests/unit/out/refcount/union_nested.rs delete mode 100644 tests/unit/out/refcount/union_pointer_pun_address.rs delete mode 100644 tests/unit/out/refcount/union_struct_dual_use.rs delete mode 100644 tests/unit/out/unsafe/union_addrof_external.rs delete mode 100644 tests/unit/out/unsafe/union_cross_arm_cast.rs delete mode 100644 tests/unit/out/unsafe/union_field_alignment.rs delete mode 100644 tests/unit/out/unsafe/union_flex_array_member.rs delete mode 100644 tests/unit/out/unsafe/union_memset_memcpy.rs delete mode 100644 tests/unit/out/unsafe/union_nested.rs delete mode 100644 tests/unit/out/unsafe/union_struct_dual_use.rs delete mode 100644 tests/unit/out/unsafe/union_tagged_struct_arms.rs diff --git a/tests/lit/lit/formats/Cpp2RustTest.py b/tests/lit/lit/formats/Cpp2RustTest.py index 9ba658f3..de276e97 100644 --- a/tests/lit/lit/formats/Cpp2RustTest.py +++ b/tests/lit/lit/formats/Cpp2RustTest.py @@ -4,9 +4,12 @@ import lit.Test import lit.util from .base import TestFormat -import difflib, os, re, shutil, random +import difflib, os, re, shutil, random, sys import tomli +CURRENT_OS = 'macos' if sys.platform == 'darwin' else 'linux' +ENTRY_RE = re.compile(r'(\w+)(?:\s*\(([^)]*)\))?') + def read_rust_version(): toolchain_path = os.path.join(os.path.dirname(__file__), '../../../../libcc2rs/rust-toolchain.toml') @@ -69,17 +72,24 @@ def execute(self, test, litConfig): def matches_model(match, model): if match is None: return False - models = match.group(1) - if models is None or models.strip() == '': + spec = match.group(1) + if spec is None or spec.strip() == '': return True - return model in re.split(r'\s*,\s*', models.strip()) + for entry in ENTRY_RE.finditer(spec): + if entry.group(1) != model: + continue + os_list = entry.group(2) + if os_list is None: + return True + if CURRENT_OS in [o.strip() for o in os_list.split(',')]: + return True + return False should_fail = False fail_code = lit.Test.FAIL xfail = self.regex_xfail.search(text) if xfail: - xfail = re.split(r'\s*,\s*', xfail.group(1)) - should_fail = model in xfail + should_fail = matches_model(xfail, model) fail_code = lit.Test.XFAIL should_panic = matches_model(self.regex_panic.search(text), model) diff --git a/tests/unit/out/refcount/union_cross_arm_cast.rs b/tests/unit/out/refcount/union_cross_arm_cast.rs deleted file mode 100644 index 20e0d2eb..00000000 --- a/tests/unit/out/refcount/union_cross_arm_cast.rs +++ /dev/null @@ -1,80 +0,0 @@ -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}; -#[derive()] -pub struct shape_a { - pub code: Value, - pub pad: Value>, -} -impl ByteRepr for shape_a {} -#[derive()] -pub struct shape_b { - pub code: Value, - pub lo: Value, - pub mid: Value, - pub fill: Value>, - pub tail: Value, -} -impl ByteRepr for shape_b {} -#[derive()] -pub struct Container_anon_0 { - pub a: Value, - pub b: Value, - pub raw_: Value>, -} -impl ByteRepr for Container_anon_0 {} -#[derive(Default)] -pub struct Container { - pub len: Value, - pub u: Value, -} -impl ByteRepr for Container {} -pub fn main() { - std::process::exit(main_0()); -} -fn main_0() -> i32 { - let c: Value = >::default(); - { - ((c.as_pointer()) as Ptr).to_any().memset( - (0) as u8, - ::std::mem::size_of::() as u64 as usize, - ); - ((c.as_pointer()) as Ptr).to_any().clone() - }; - (*(*(*(*c.borrow()).u.borrow()).a.borrow()).code.borrow_mut()) = 10_u16; - (*(*c.borrow()).len.borrow_mut()) = (::std::mem::size_of::() as u64 as u32); - (*(*((((*(*c.borrow()).u.borrow()).a.as_pointer()) - .to_strong() - .as_pointer() as AnyPtr) - .cast::() - .expect("ub:wrong type")) - .upgrade() - .deref()) - .tail - .borrow_mut()) = 3735928559_u32; - assert!(((*(*(*(*c.borrow()).u.borrow()).b.borrow()).tail.borrow()) == 3735928559_u32)); - assert!((((*(*(*(*c.borrow()).u.borrow()).b.borrow()).code.borrow()) as i32) == 10)); - (*(*(*(*c.borrow()).u.borrow()).b.borrow()).lo.borrow_mut()) = 8080_u16; - assert!( - ((((((*(*c.borrow()).u.borrow()).raw_.as_pointer()) - .to_strong() - .as_pointer() as Ptr::) - .offset((2) as isize) - .read()) as i32) - == 144) - ); - assert!( - ((((((*(*c.borrow()).u.borrow()).raw_.as_pointer()) - .to_strong() - .as_pointer() as Ptr::) - .offset((3) as isize) - .read()) as i32) - == 31) - ); - return 0; -} diff --git a/tests/unit/out/refcount/union_field_alignment.rs b/tests/unit/out/refcount/union_field_alignment.rs deleted file mode 100644 index 3601f78e..00000000 --- a/tests/unit/out/refcount/union_field_alignment.rs +++ /dev/null @@ -1,30 +0,0 @@ -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}; -#[derive()] -pub struct node_anon_0 { - pub bytes: Value>, - pub aligner: Value, -} -impl ByteRepr for node_anon_0 {} -#[derive(Default)] -pub struct node { - pub next: Value>, - pub x: Value, -} -impl ByteRepr for node {} -pub fn main() { - std::process::exit(main_0()); -} -fn main_0() -> i32 { - let n: Value = >::default(); - (*(*n.borrow()).next.borrow_mut()) = Default::default(); - (*(*(*n.borrow()).x.borrow()).bytes.borrow_mut())[(0) as usize] = 171_u8; - assert!((((*(*(*n.borrow()).x.borrow()).bytes.borrow())[(0) as usize] as i32) == 171)); - return 0; -} diff --git a/tests/unit/out/refcount/union_flex_array_member.rs b/tests/unit/out/refcount/union_flex_array_member.rs deleted file mode 100644 index 56d7ef0e..00000000 --- a/tests/unit/out/refcount/union_flex_array_member.rs +++ /dev/null @@ -1,73 +0,0 @@ -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}; -#[derive()] -pub struct node_anon_0 { - pub bytes: Value>, - pub aligner: Value, -} -impl ByteRepr for node_anon_0 {} -#[derive(Default)] -pub struct node { - pub len: Value, - pub x: Value, -} -impl ByteRepr for node {} -pub fn main() { - std::process::exit(main_0()); -} -fn main_0() -> i32 { - let tail_size: Value = Rc::new(RefCell::new(32_u64)); - let n: Value> = Rc::new(RefCell::new( - ({ - let ___size: u64 = - (::std::mem::size_of::() as u64 as u64).wrapping_add((*tail_size.borrow())); - malloc_0(___size) - }) - .cast::() - .expect("ub:wrong type"), - )); - (*(*(*n.borrow()).upgrade().deref()).len.borrow_mut()) = (*tail_size.borrow()); - let i: Value = Rc::new(RefCell::new(0_u64)); - 'loop_: while ((*i.borrow()) < (*tail_size.borrow())) { - let __rhs = ((((*i.borrow()) & 255_u64) as u64) as u8); - (*(*(*(*n.borrow()).upgrade().deref()).x.borrow()) - .bytes - .borrow_mut())[(*i.borrow()) as usize] = __rhs; - (*i.borrow_mut()).postfix_inc(); - } - let i: Value = Rc::new(RefCell::new(0_u64)); - 'loop_: while ((*i.borrow()) < (*tail_size.borrow())) { - assert!({ - let _lhs = ((*(*(*(*n.borrow()).upgrade().deref()).x.borrow()) - .bytes - .borrow())[(*i.borrow()) as usize] as i32); - _lhs == (((((*i.borrow()) & 255_u64) as u64) as u8) as i32) - }); - (*i.borrow_mut()).postfix_inc(); - } - let p: Value> = Rc::new(RefCell::new( - (((*(*(*n.borrow()).upgrade().deref()).x.borrow()) - .bytes - .as_pointer() as Ptr) - .offset(10 as isize)), - )); - assert!(((((*p.borrow()).read()) as i32) == 10)); - (*p.borrow()).write(170_u8); - assert!( - (((*(*(*(*n.borrow()).upgrade().deref()).x.borrow()) - .bytes - .borrow())[(10) as usize] as i32) - == 170) - ); - ({ - let ___ptr: AnyPtr = ((*n.borrow()).clone() as Ptr).to_any(); - free_1(___ptr) - }); - return 0; -} diff --git a/tests/unit/out/refcount/union_memset_memcpy.rs b/tests/unit/out/refcount/union_memset_memcpy.rs deleted file mode 100644 index fbb55430..00000000 --- a/tests/unit/out/refcount/union_memset_memcpy.rs +++ /dev/null @@ -1,107 +0,0 @@ -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}; -#[derive()] -pub struct shape_a { - pub code: Value, - pub pad: Value>, -} -impl ByteRepr for shape_a {} -#[derive()] -pub struct shape_b { - pub code: Value, - pub lo: Value, - pub hi: Value, - pub fill: Value>, -} -impl ByteRepr for shape_b {} -#[derive()] -pub struct Container_anon_0 { - pub a: Value, - pub b: Value, - pub raw_: Value>, -} -impl ByteRepr for Container_anon_0 {} -#[derive(Default)] -pub struct Container { - pub view: Value, -} -impl ByteRepr for Container {} -pub fn main() { - std::process::exit(main_0()); -} -fn main_0() -> i32 { - let c: Value = >::default(); - { - ((c.as_pointer()) as Ptr).to_any().memset( - (0) as u8, - ::std::mem::size_of::() as u64 as usize, - ); - ((c.as_pointer()) as Ptr).to_any().clone() - }; - assert!((((*(*(*(*c.borrow()).view.borrow()).a.borrow()).code.borrow()) as i32) == 0)); - assert!((((*(*(*(*c.borrow()).view.borrow()).b.borrow()).lo.borrow()) as i32) == 0)); - assert!((((*(*(*c.borrow()).view.borrow()).raw_.borrow())[(0) as usize] as i32) == 0)); - assert!((((*(*(*c.borrow()).view.borrow()).raw_.borrow())[(255) as usize] as i32) == 0)); - let src: Value> = Rc::new(RefCell::new(Box::new([ - 0_u8, - ::default(), - ::default(), - ::default(), - ::default(), - ::default(), - ::default(), - ::default(), - ::default(), - ::default(), - ::default(), - ::default(), - ::default(), - ::default(), - ::default(), - ::default(), - ]))); - (*src.borrow_mut())[(0) as usize] = 2_u8; - (*src.borrow_mut())[(2) as usize] = 80_u8; - (*src.borrow_mut())[(3) as usize] = 0_u8; - (*src.borrow_mut())[(4) as usize] = 127_u8; - (*src.borrow_mut())[(5) as usize] = 0_u8; - (*src.borrow_mut())[(6) as usize] = 0_u8; - (*src.borrow_mut())[(7) as usize] = 1_u8; - let len: Value = Rc::new(RefCell::new(16_u64)); - assert!(((*len.borrow()) <= ::std::mem::size_of::<[u8; 256]>() as u64)); - { - (((*(*c.borrow()).view.borrow()).raw_.as_pointer()) as Ptr) - .to_any() - .memcpy( - &((src.as_pointer() as Ptr) as Ptr).to_any(), - (*len.borrow()) as usize, - ); - (((*(*c.borrow()).view.borrow()).raw_.as_pointer()) as Ptr) - .to_any() - .clone() - }; - assert!((((*(*(*(*c.borrow()).view.borrow()).b.borrow()).code.borrow()) as i32) == 2)); - assert!( - ((((((*(*(*c.borrow()).view.borrow()).b.borrow()).lo.as_pointer()) - .to_strong() - .as_pointer() as Ptr::) - .offset((0) as isize) - .read()) as i32) - == 80) - ); - { - ((c.as_pointer()) as Ptr).to_any().memset( - (0) as u8, - ::std::mem::size_of::() as u64 as usize, - ); - ((c.as_pointer()) as Ptr).to_any().clone() - }; - assert!((((*(*(*(*c.borrow()).view.borrow()).b.borrow()).code.borrow()) as i32) == 0)); - return 0; -} diff --git a/tests/unit/out/refcount/union_nested.rs b/tests/unit/out/refcount/union_nested.rs deleted file mode 100644 index d8322734..00000000 --- a/tests/unit/out/refcount/union_nested.rs +++ /dev/null @@ -1,78 +0,0 @@ -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}; -#[derive()] -pub struct record { - pub code: Value, - pub pad: Value>, -} -impl ByteRepr for record {} -#[derive()] -pub struct inner_anon_0 { - pub h: Value, - pub raw_: Value>, -} -impl ByteRepr for inner_anon_0 {} -#[derive(Default)] -pub struct inner { - pub view: Value, -} -impl ByteRepr for inner {} -#[derive(Default)] -pub struct Outer_anon_0 { - pub h: Value, - pub nested: Value, -} -impl ByteRepr for Outer_anon_0 {} -#[derive(Default)] -pub struct Outer { - pub kind: Value, - pub level: Value, - pub variant: Value, - pub len: Value, - pub body: Value, -} -impl ByteRepr for Outer {} -pub fn main() { - std::process::exit(main_0()); -} -fn main_0() -> i32 { - let ex: Value = >::default(); - { - ((ex.as_pointer()) as Ptr) - .to_any() - .memset((0) as u8, ::std::mem::size_of::() as u64 as usize); - ((ex.as_pointer()) as Ptr).to_any().clone() - }; - (*(*ex.borrow()).kind.borrow_mut()) = 2; - (*(*ex.borrow()).level.borrow_mut()) = 1; - (*(*ex.borrow()).variant.borrow_mut()) = 6; - (*(*ex.borrow()).len.borrow_mut()) = (::std::mem::size_of::() as u64 as u32); - (*(*(*(*ex.borrow()).body.borrow()).h.borrow()) - .code - .borrow_mut()) = 2_u16; - (*(*(*(*ex.borrow()).body.borrow()).h.borrow()) - .pad - .borrow_mut())[(0) as usize] = (('X' as i32) as u8); - assert!((((*(*(*(*ex.borrow()).body.borrow()).h.borrow()).code.borrow()) as i32) == 2)); - assert!( - (((*(*(*(*ex.borrow()).body.borrow()).h.borrow()).pad.borrow())[(0) as usize] as i32) - == ('X' as i32)) - ); - assert!( - (((*(*(*(*(*(*ex.borrow()).body.borrow()).nested.borrow()) - .view - .borrow()) - .h - .borrow()) - .code - .borrow()) as i32) - == 2) - ); - return 0; -} diff --git a/tests/unit/out/refcount/union_pointer_pun_address.rs b/tests/unit/out/refcount/union_pointer_pun_address.rs deleted file mode 100644 index bbe33b8a..00000000 --- a/tests/unit/out/refcount/union_pointer_pun_address.rs +++ /dev/null @@ -1,41 +0,0 @@ -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}; -#[derive(Default)] -pub struct node_a { - pub n: Value, -} -impl ByteRepr for node_a {} -#[derive(Default)] -pub struct node_b { - pub data: Value, - pub next: Value>, -} -impl ByteRepr for node_b {} -pub fn main() { - std::process::exit(main_0()); -} -fn main_0() -> i32 { - let a: Value = Rc::new(RefCell::new(node_a { - n: Rc::new(RefCell::new(123)), - })); - #[derive(Default)] - pub struct anon_0 { - pub to_a: Value>, - pub to_b: Value>, - } - impl ByteRepr for anon_0 {}; - let ptr: Value = >::default(); - (*(*ptr.borrow()).to_a.borrow_mut()) = (a.as_pointer()); - let out: Value> = Rc::new(RefCell::new((*(*ptr.borrow()).to_b.borrow()).clone())); - assert!({ - let _lhs = ((*out.borrow()).to_strong().as_pointer() as AnyPtr).clone(); - _lhs == ((a.as_pointer()).to_strong().as_pointer() as AnyPtr) - }); - return 0; -} diff --git a/tests/unit/out/refcount/union_struct_dual_use.rs b/tests/unit/out/refcount/union_struct_dual_use.rs deleted file mode 100644 index 2e1989c3..00000000 --- a/tests/unit/out/refcount/union_struct_dual_use.rs +++ /dev/null @@ -1,68 +0,0 @@ -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}; -#[derive(Default)] -pub struct Inner { - pub a: Value, - pub b: Value, -} -impl ByteRepr for Inner {} -pub fn sum_inner_0(i: Ptr) -> i32 { - let i: Value> = Rc::new(RefCell::new(i)); - return { - let _lhs = (*(*(*i.borrow()).upgrade().deref()).a.borrow()); - _lhs + (*(*(*i.borrow()).upgrade().deref()).b.borrow()) - }; -} -#[derive()] -pub struct Outer_anon_0 { - pub inner: Value, - pub raw_: Value>, -} -impl ByteRepr for Outer_anon_0 {} -#[derive(Default)] -pub struct Outer { - pub u: Value, -} -impl ByteRepr for Outer {} -pub fn main() { - std::process::exit(main_0()); -} -fn main_0() -> i32 { - let standalone: Value = >::default(); - (*(*standalone.borrow()).a.borrow_mut()) = 3; - (*(*standalone.borrow()).b.borrow_mut()) = 4; - assert!( - (({ - let _i: Ptr = (standalone.as_pointer()); - sum_inner_0(_i) - }) == 7) - ); - let outer: Value = >::default(); - { - ((outer.as_pointer()) as Ptr) - .to_any() - .memset((0) as u8, ::std::mem::size_of::() as u64 as usize); - ((outer.as_pointer()) as Ptr).to_any().clone() - }; - (*(*(*(*outer.borrow()).u.borrow()).inner.borrow()) - .a - .borrow_mut()) = 3; - (*(*(*(*outer.borrow()).u.borrow()).inner.borrow()) - .b - .borrow_mut()) = 4; - assert!( - (({ - let _i: Ptr = ((*(*outer.borrow()).u.borrow()).inner.as_pointer()); - sum_inner_0(_i) - }) == 7) - ); - assert!(((((*(*(*outer.borrow()).u.borrow()).raw_.borrow())[(0) as usize] as u8) as i32) == 3)); - assert!(((((*(*(*outer.borrow()).u.borrow()).raw_.borrow())[(4) as usize] as u8) as i32) == 4)); - return 0; -} diff --git a/tests/unit/out/unsafe/union_addrof_external.rs b/tests/unit/out/unsafe/union_addrof_external.rs deleted file mode 100644 index 9181620f..00000000 --- a/tests/unit/out/unsafe/union_addrof_external.rs +++ /dev/null @@ -1,81 +0,0 @@ -extern crate libc; -use libc::*; -extern crate libcc2rs; -use libcc2rs::*; -use std::collections::BTreeMap; -use std::io::{Read, Seek, Write}; -use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; -use std::rc::Rc; -#[derive(Copy, Clone)] -pub struct record { - pub code: u16, - pub lo: u16, - pub hi: u32, - pub pad: [u8; 8], -} -#[derive(Copy, Clone)] -pub struct Container_anon_0 { - pub h: record, - pub raw_: [u8; 128], -} -#[derive(Copy, Clone, Default)] -pub struct Container { - pub view: Container_anon_0, -} -pub unsafe fn fill_0(mut out: *mut ::libc::c_void, mut cap: u64) { - let mut src: [u8; 16] = [ - 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, - 0_u8, - ]; - src[(0) as usize] = 2_u8; - src[(1) as usize] = 0_u8; - src[(2) as usize] = 0_u8; - src[(3) as usize] = 80_u8; - src[(4) as usize] = 127_u8; - src[(5) as usize] = 0_u8; - src[(6) as usize] = 0_u8; - src[(7) as usize] = 1_u8; - let mut n: u64 = if ((::std::mem::size_of::<[u8; 16]>() as u64) < (cap)) { - ::std::mem::size_of::<[u8; 16]>() as u64 - } else { - cap - }; - { - if n != 0 { - ::std::ptr::copy_nonoverlapping( - (src.as_mut_ptr() as *const u8 as *const ::libc::c_void), - out, - n as usize, - ) - } - out - }; -} -pub fn main() { - unsafe { - std::process::exit(main_0() as i32); - } -} -unsafe fn main_0() -> i32 { - let mut c: Container = ::default(); - { - let byte_0 = - ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) as *mut u8; - for offset in 0..::std::mem::size_of::() as u64 { - *byte_0.offset(offset as isize) = 0 as u8; - } - ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) - }; - (unsafe { - let _out: *mut ::libc::c_void = - ((&mut c.view as *mut Container_anon_0) as *mut ::libc::c_void); - let _cap: u64 = ::std::mem::size_of::() as u64; - fill_0(_out, _cap) - }); - assert!(((c.view.h.code as i32) == (2))); - assert!((((*((&mut c.view.h.lo as *mut u16) as *mut u8).offset((0) as isize)) as i32) == (0))); - assert!((((*((&mut c.view.h.lo as *mut u16) as *mut u8).offset((1) as isize)) as i32) == (80))); - assert!(((c.view.raw_[(0) as usize] as i32) == (2))); - assert!((((c.view.raw_[(3) as usize] as u8) as i32) == (80))); - return 0; -} diff --git a/tests/unit/out/unsafe/union_cross_arm_cast.rs b/tests/unit/out/unsafe/union_cross_arm_cast.rs deleted file mode 100644 index d93385ce..00000000 --- a/tests/unit/out/unsafe/union_cross_arm_cast.rs +++ /dev/null @@ -1,62 +0,0 @@ -extern crate libc; -use libc::*; -extern crate libcc2rs; -use libcc2rs::*; -use std::collections::BTreeMap; -use std::io::{Read, Seek, Write}; -use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; -use std::rc::Rc; -#[derive(Copy, Clone)] -pub struct shape_a { - pub code: u16, - pub pad: [u8; 14], -} -#[derive(Copy, Clone)] -pub struct shape_b { - pub code: u16, - pub lo: u16, - pub mid: u32, - pub fill: [u8; 16], - pub tail: u32, -} -#[derive(Copy, Clone)] -pub struct Container_anon_0 { - pub a: shape_a, - pub b: shape_b, - pub raw_: [u8; 64], -} -#[derive(Copy, Clone, Default)] -pub struct Container { - pub len: u32, - pub u: Container_anon_0, -} -pub fn main() { - unsafe { - std::process::exit(main_0() as i32); - } -} -unsafe fn main_0() -> i32 { - let mut c: Container = ::default(); - { - let byte_0 = - ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) as *mut u8; - for offset in 0..::std::mem::size_of::() as u64 { - *byte_0.offset(offset as isize) = 0 as u8; - } - ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) - }; - c.u.a.code = 10_u16; - c.len = (::std::mem::size_of::() as u64 as u32); - (*(((&mut c.u.a as *mut shape_a) as *mut ::libc::c_void) as *mut shape_b)).tail = - 3735928559_u32; - assert!(((c.u.b.tail) == (3735928559_u32))); - assert!(((c.u.b.code as i32) == (10))); - c.u.b.lo = 8080_u16; - assert!( - (((*((&mut c.u.raw_ as *mut [u8; 64]) as *mut u8).offset((2) as isize)) as i32) == (144)) - ); - assert!( - (((*((&mut c.u.raw_ as *mut [u8; 64]) as *mut u8).offset((3) as isize)) as i32) == (31)) - ); - return 0; -} diff --git a/tests/unit/out/unsafe/union_field_alignment.rs b/tests/unit/out/unsafe/union_field_alignment.rs deleted file mode 100644 index 8441c7d4..00000000 --- a/tests/unit/out/unsafe/union_field_alignment.rs +++ /dev/null @@ -1,30 +0,0 @@ -extern crate libc; -use libc::*; -extern crate libcc2rs; -use libcc2rs::*; -use std::collections::BTreeMap; -use std::io::{Read, Seek, Write}; -use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; -use std::rc::Rc; -#[derive(Copy, Clone)] -pub struct node_anon_0 { - pub bytes: [u8; 1], - pub aligner: *mut ::libc::c_void, -} -#[derive(Copy, Clone, Default)] -pub struct node { - pub next: *mut node, - pub x: node_anon_0, -} -pub fn main() { - unsafe { - std::process::exit(main_0() as i32); - } -} -unsafe fn main_0() -> i32 { - let mut n: node = ::default(); - n.next = Default::default(); - n.x.bytes[(0) as usize] = 171_u8; - assert!(((n.x.bytes[(0) as usize] as i32) == (171))); - return 0; -} diff --git a/tests/unit/out/unsafe/union_flex_array_member.rs b/tests/unit/out/unsafe/union_flex_array_member.rs deleted file mode 100644 index fcf94b81..00000000 --- a/tests/unit/out/unsafe/union_flex_array_member.rs +++ /dev/null @@ -1,52 +0,0 @@ -extern crate libc; -use libc::*; -extern crate libcc2rs; -use libcc2rs::*; -use std::collections::BTreeMap; -use std::io::{Read, Seek, Write}; -use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; -use std::rc::Rc; -#[derive(Copy, Clone)] -pub struct node_anon_0 { - pub bytes: [u8; 1], - pub aligner: *mut ::libc::c_void, -} -#[derive(Copy, Clone, Default)] -pub struct node { - pub len: u64, - pub x: node_anon_0, -} -pub fn main() { - unsafe { - std::process::exit(main_0() as i32); - } -} -unsafe fn main_0() -> i32 { - let mut tail_size: u64 = 32_u64; - let mut n: *mut node = ((unsafe { - let ___size: u64 = (::std::mem::size_of::() as u64 as u64).wrapping_add(tail_size); - malloc_0(___size) - }) as *mut node); - (*n).len = tail_size; - let mut i: u64 = 0_u64; - 'loop_: while ((i) < (tail_size)) { - (*n).x.bytes[(i) as usize] = ((((i) & (255_u64)) as u64) as u8); - i.postfix_inc(); - } - let mut i: u64 = 0_u64; - 'loop_: while ((i) < (tail_size)) { - assert!( - (((*n).x.bytes[(i) as usize] as i32) == (((((i) & (255_u64)) as u64) as u8) as i32)) - ); - i.postfix_inc(); - } - let mut p: *mut u8 = (&mut (*n).x.bytes[(10) as usize] as *mut u8); - assert!((((*p) as i32) == (10))); - (*p) = 170_u8; - assert!((((*n).x.bytes[(10) as usize] as i32) == (170))); - (unsafe { - let ___ptr: *mut ::libc::c_void = (n as *mut node as *mut ::libc::c_void); - free_1(___ptr) - }); - return 0; -} diff --git a/tests/unit/out/unsafe/union_memset_memcpy.rs b/tests/unit/out/unsafe/union_memset_memcpy.rs deleted file mode 100644 index 47354e9d..00000000 --- a/tests/unit/out/unsafe/union_memset_memcpy.rs +++ /dev/null @@ -1,85 +0,0 @@ -extern crate libc; -use libc::*; -extern crate libcc2rs; -use libcc2rs::*; -use std::collections::BTreeMap; -use std::io::{Read, Seek, Write}; -use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; -use std::rc::Rc; -#[derive(Copy, Clone)] -pub struct shape_a { - pub code: u16, - pub pad: [u8; 14], -} -#[derive(Copy, Clone)] -pub struct shape_b { - pub code: u16, - pub lo: u16, - pub hi: u32, - pub fill: [u8; 8], -} -#[derive(Copy, Clone)] -pub struct Container_anon_0 { - pub a: shape_a, - pub b: shape_b, - pub raw_: [u8; 256], -} -#[derive(Copy, Clone, Default)] -pub struct Container { - pub view: Container_anon_0, -} -pub fn main() { - unsafe { - std::process::exit(main_0() as i32); - } -} -unsafe fn main_0() -> i32 { - let mut c: Container = ::default(); - { - let byte_0 = - ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) as *mut u8; - for offset in 0..::std::mem::size_of::() as u64 { - *byte_0.offset(offset as isize) = 0 as u8; - } - ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) - }; - assert!(((c.view.a.code as i32) == (0))); - assert!(((c.view.b.lo as i32) == (0))); - assert!(((c.view.raw_[(0) as usize] as i32) == (0))); - assert!(((c.view.raw_[(255) as usize] as i32) == (0))); - let mut src: [u8; 16] = [ - 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, - 0_u8, - ]; - src[(0) as usize] = 2_u8; - src[(2) as usize] = 80_u8; - src[(3) as usize] = 0_u8; - src[(4) as usize] = 127_u8; - src[(5) as usize] = 0_u8; - src[(6) as usize] = 0_u8; - src[(7) as usize] = 1_u8; - let mut len: u64 = 16_u64; - assert!(((len) <= (::std::mem::size_of::<[u8; 256]>() as u64))); - { - if len != 0 { - ::std::ptr::copy_nonoverlapping( - (src.as_mut_ptr() as *const u8 as *const ::libc::c_void), - ((&mut c.view.raw_ as *mut [u8; 256]) as *mut [u8; 256] as *mut ::libc::c_void), - len as usize, - ) - } - ((&mut c.view.raw_ as *mut [u8; 256]) as *mut [u8; 256] as *mut ::libc::c_void) - }; - assert!(((c.view.b.code as i32) == (2))); - assert!((((*((&mut c.view.b.lo as *mut u16) as *mut u8).offset((0) as isize)) as i32) == (80))); - { - let byte_0 = - ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) as *mut u8; - for offset in 0..::std::mem::size_of::() as u64 { - *byte_0.offset(offset as isize) = 0 as u8; - } - ((&mut c as *mut Container) as *mut Container as *mut ::libc::c_void) - }; - assert!(((c.view.b.code as i32) == (0))); - return 0; -} diff --git a/tests/unit/out/unsafe/union_nested.rs b/tests/unit/out/unsafe/union_nested.rs deleted file mode 100644 index ba0822fb..00000000 --- a/tests/unit/out/unsafe/union_nested.rs +++ /dev/null @@ -1,60 +0,0 @@ -extern crate libc; -use libc::*; -extern crate libcc2rs; -use libcc2rs::*; -use std::collections::BTreeMap; -use std::io::{Read, Seek, Write}; -use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; -use std::rc::Rc; -#[derive(Copy, Clone)] -pub struct record { - pub code: u16, - pub pad: [u8; 14], -} -#[derive(Copy, Clone)] -pub struct inner_anon_0 { - pub h: record, - pub raw_: [u8; 128], -} -#[derive(Copy, Clone, Default)] -pub struct inner { - pub view: inner_anon_0, -} -#[derive(Copy, Clone, Default)] -pub struct Outer_anon_0 { - pub h: record, - pub nested: inner, -} -#[derive(Copy, Clone, Default)] -pub struct Outer { - pub kind: i32, - pub level: i32, - pub variant: i32, - pub len: u32, - pub body: Outer_anon_0, -} -pub fn main() { - unsafe { - std::process::exit(main_0() as i32); - } -} -unsafe fn main_0() -> i32 { - let mut ex: Outer = ::default(); - { - let byte_0 = ((&mut ex as *mut Outer) as *mut Outer as *mut ::libc::c_void) as *mut u8; - for offset in 0..::std::mem::size_of::() as u64 { - *byte_0.offset(offset as isize) = 0 as u8; - } - ((&mut ex as *mut Outer) as *mut Outer as *mut ::libc::c_void) - }; - ex.kind = 2; - ex.level = 1; - ex.variant = 6; - ex.len = (::std::mem::size_of::() as u64 as u32); - ex.body.h.code = 2_u16; - ex.body.h.pad[(0) as usize] = (('X' as i32) as u8); - assert!(((ex.body.h.code as i32) == (2))); - assert!(((ex.body.h.pad[(0) as usize] as i32) == ('X' as i32))); - assert!(((ex.body.nested.view.h.code as i32) == (2))); - return 0; -} diff --git a/tests/unit/out/unsafe/union_struct_dual_use.rs b/tests/unit/out/unsafe/union_struct_dual_use.rs deleted file mode 100644 index 76beecf2..00000000 --- a/tests/unit/out/unsafe/union_struct_dual_use.rs +++ /dev/null @@ -1,60 +0,0 @@ -extern crate libc; -use libc::*; -extern crate libcc2rs; -use libcc2rs::*; -use std::collections::BTreeMap; -use std::io::{Read, Seek, Write}; -use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; -use std::rc::Rc; -#[derive(Copy, Clone, Default)] -pub struct Inner { - pub a: i32, - pub b: i32, -} -pub unsafe fn sum_inner_0(mut i: *mut Inner) -> i32 { - return (((*i).a) + ((*i).b)); -} -#[derive(Copy, Clone)] -pub struct Outer_anon_0 { - pub inner: Inner, - pub raw_: [u8; 16], -} -#[derive(Copy, Clone, Default)] -pub struct Outer { - pub u: Outer_anon_0, -} -pub fn main() { - unsafe { - std::process::exit(main_0() as i32); - } -} -unsafe fn main_0() -> i32 { - let mut standalone: Inner = ::default(); - standalone.a = 3; - standalone.b = 4; - assert!( - ((unsafe { - let _i: *mut Inner = (&mut standalone as *mut Inner); - sum_inner_0(_i) - }) == (7)) - ); - let mut outer: Outer = ::default(); - { - let byte_0 = ((&mut outer as *mut Outer) as *mut Outer as *mut ::libc::c_void) as *mut u8; - for offset in 0..::std::mem::size_of::() as u64 { - *byte_0.offset(offset as isize) = 0 as u8; - } - ((&mut outer as *mut Outer) as *mut Outer as *mut ::libc::c_void) - }; - outer.u.inner.a = 3; - outer.u.inner.b = 4; - assert!( - ((unsafe { - let _i: *mut Inner = (&mut outer.u.inner as *mut Inner); - sum_inner_0(_i) - }) == (7)) - ); - assert!((((outer.u.raw_[(0) as usize] as u8) as i32) == (3))); - assert!((((outer.u.raw_[(4) as usize] as u8) as i32) == (4))); - return 0; -} diff --git a/tests/unit/out/unsafe/union_tagged_struct_arms.rs b/tests/unit/out/unsafe/union_tagged_struct_arms.rs deleted file mode 100644 index 541a1395..00000000 --- a/tests/unit/out/unsafe/union_tagged_struct_arms.rs +++ /dev/null @@ -1,86 +0,0 @@ -extern crate libc; -use libc::*; -extern crate libcc2rs; -use libcc2rs::*; -use std::collections::BTreeMap; -use std::io::{Read, Seek, Write}; -use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; -use std::rc::Rc; -#[derive(Clone, Copy, PartialEq, Debug, Default)] -enum Choice { - #[default] - C_LIST = 1, - C_LETTERS = 2, - C_INTEGERS = 3, -} -#[derive(Copy, Clone, Default)] -pub struct Branch_anon_0_anon_0 { - pub items: *mut *mut u8, - pub count: i64, - pub cursor: i64, -} -#[derive(Copy, Clone, Default)] -pub struct Branch_anon_0_anon_1 { - pub lo: i32, - pub hi: i32, - pub curr: i32, - pub step: u8, -} -#[derive(Copy, Clone, Default)] -pub struct Branch_anon_0_anon_2 { - pub lo: i64, - pub hi: i64, - pub curr: i64, - pub step: i64, - pub width: i32, -} -#[derive(Copy, Clone, Default)] -pub struct Branch_anon_0 { - pub list: Branch_anon_0_anon_0, - pub letters: Branch_anon_0_anon_1, - pub integers: Branch_anon_0_anon_2, -} -#[derive(Copy, Clone, Default)] -pub struct Branch { - pub choice: Choice, - pub index: i32, - pub v: Branch_anon_0, -} -pub fn main() { - unsafe { - std::process::exit(main_0() as i32); - } -} -unsafe fn main_0() -> i32 { - static mut items: [*mut u8; 3] = [b"a\0".as_ptr(), b"b\0".as_ptr(), b"c\0".as_ptr()];; - let mut p_list: Branch = ::default(); - p_list.choice = (Choice::C_LIST as Choice); - p_list.index = 0; - p_list.v.list.items = items.as_mut_ptr(); - p_list.v.list.count = 3_i64; - p_list.v.list.cursor = 1_i64; - assert!(((p_list.v.list.count) == (3_i64))); - assert!( - (((*(*p_list.v.list.items.offset((1) as isize)).offset((0) as isize)) as i32) - == ('b' as i32)) - ); - let mut p_letters: Branch = ::default(); - p_letters.choice = (Choice::C_LETTERS as Choice); - p_letters.index = 1; - p_letters.v.letters.lo = ('a' as i32); - p_letters.v.letters.hi = ('z' as i32); - p_letters.v.letters.curr = ('m' as i32); - p_letters.v.letters.step = 1_u8; - assert!((((p_letters.v.letters.hi) - (p_letters.v.letters.lo)) == (25))); - let mut p_integers: Branch = ::default(); - p_integers.choice = (Choice::C_INTEGERS as Choice); - p_integers.index = 2; - p_integers.v.integers.lo = 1_i64; - p_integers.v.integers.hi = 100_i64; - p_integers.v.integers.curr = 1_i64; - p_integers.v.integers.step = 1_i64; - p_integers.v.integers.width = 3; - assert!(((p_integers.v.integers.hi) == (100_i64))); - assert!(((p_integers.v.integers.width) == (3))); - return 0; -} From 5d35089d01211fea682784467637a25234249c92 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 28 Apr 2026 11:17:40 +0100 Subject: [PATCH 13/14] Revert unintented changes --- tests/lit/lit/formats/Cpp2RustTest.py | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/tests/lit/lit/formats/Cpp2RustTest.py b/tests/lit/lit/formats/Cpp2RustTest.py index de276e97..9ba658f3 100644 --- a/tests/lit/lit/formats/Cpp2RustTest.py +++ b/tests/lit/lit/formats/Cpp2RustTest.py @@ -4,12 +4,9 @@ import lit.Test import lit.util from .base import TestFormat -import difflib, os, re, shutil, random, sys +import difflib, os, re, shutil, random import tomli -CURRENT_OS = 'macos' if sys.platform == 'darwin' else 'linux' -ENTRY_RE = re.compile(r'(\w+)(?:\s*\(([^)]*)\))?') - def read_rust_version(): toolchain_path = os.path.join(os.path.dirname(__file__), '../../../../libcc2rs/rust-toolchain.toml') @@ -72,24 +69,17 @@ def execute(self, test, litConfig): def matches_model(match, model): if match is None: return False - spec = match.group(1) - if spec is None or spec.strip() == '': + models = match.group(1) + if models is None or models.strip() == '': return True - for entry in ENTRY_RE.finditer(spec): - if entry.group(1) != model: - continue - os_list = entry.group(2) - if os_list is None: - return True - if CURRENT_OS in [o.strip() for o in os_list.split(',')]: - return True - return False + return model in re.split(r'\s*,\s*', models.strip()) should_fail = False fail_code = lit.Test.FAIL xfail = self.regex_xfail.search(text) if xfail: - should_fail = matches_model(xfail, model) + xfail = re.split(r'\s*,\s*', xfail.group(1)) + should_fail = model in xfail fail_code = lit.Test.XFAIL should_panic = matches_model(self.regex_panic.search(text), model) From bf6437438a5e3c1f1ae3a67ba6066ea676ea44d4 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 28 Apr 2026 12:59:28 +0100 Subject: [PATCH 14/14] Don't check generated != expected in no-compile mode --- tests/lit/lit/formats/Cpp2RustTest.py | 33 ++++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/tests/lit/lit/formats/Cpp2RustTest.py b/tests/lit/lit/formats/Cpp2RustTest.py index 9ba658f3..d414f572 100644 --- a/tests/lit/lit/formats/Cpp2RustTest.py +++ b/tests/lit/lit/formats/Cpp2RustTest.py @@ -118,22 +118,23 @@ def fail(str, code = fail_code): if should_not_translate: return fail('expected translation-fail but cpp2rust succeeded') - expected_file = self.getExpectedFile(filepath, model, fname) - if not os.path.exists(expected_file) and not replace_expected: - return fail('no expected file') - - if replace_expected: - self.updateExpected(generated, expected_file) - - with open(expected_file, 'r') as f: - expected = f.read() - - if generated != expected: - diff = ''.join(difflib.unified_diff( - expected.splitlines(keepends=True), - generated.splitlines(keepends=True), - fromfile='expected', tofile='generated')) - return fail('different output\n' + diff) + if not should_not_compile: + expected_file = self.getExpectedFile(filepath, model, fname) + if not os.path.exists(expected_file) and not replace_expected: + return fail('no expected file') + + if replace_expected: + self.updateExpected(generated, expected_file) + + with open(expected_file, 'r') as f: + expected = f.read() + + if generated != expected: + diff = ''.join(difflib.unified_diff( + expected.splitlines(keepends=True), + generated.splitlines(keepends=True), + fromfile='expected', tofile='generated')) + return fail('different output\n' + diff) pkg_name = "test_" + re.sub(r'[^a-zA-Z0-9_]', '_', os.path.basename(tmp_dir))