diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index a7f12c8d..9a11f897 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,17 @@ 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()) { + 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)) { 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..425cf805 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -562,6 +562,18 @@ 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); + parent_name += '_'; + } + return std::format("{}anon_{}", parent_name, GetAnonIndex(record)); +} + } // namespace PushASTContext::PushASTContext(clang::ASTContext &ctx) : prev_(ctx_) { @@ -724,6 +736,11 @@ std::string ToString(clang::QualType qual_type) { } 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); 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)) { diff --git a/tests/lit/lit/formats/Cpp2RustTest.py b/tests/lit/lit/formats/Cpp2RustTest.py index 2daf1491..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 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) + if replace_expected: + self.updateExpected(generated, expected_file) - with open(expected_file, 'r') as f: - expected = f.read() + 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 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)) @@ -163,7 +164,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) diff --git a/tests/unit/anonymous-struct.cpp b/tests/unit/anonymous-struct.cpp new file mode 100644 index 00000000..7b04a5a6 --- /dev/null +++ b/tests/unit/anonymous-struct.cpp @@ -0,0 +1,74 @@ +#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); + + 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 new file mode 100644 index 00000000..50ab1959 --- /dev/null +++ b/tests/unit/anonymous-struct_c.c @@ -0,0 +1,74 @@ +#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); + + 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 new file mode 100644 index 00000000..980aff17 --- /dev/null +++ b/tests/unit/out/refcount/anonymous-struct.rs @@ -0,0 +1,231 @@ +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) + ); + #[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 new file mode 100644 index 00000000..ab870b0a --- /dev/null +++ b/tests/unit/out/refcount/anonymous-struct_c.rs @@ -0,0 +1,131 @@ +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) + ); + #[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/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_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/anonymous-struct.rs b/tests/unit/out/unsafe/anonymous-struct.rs new file mode 100644 index 00000000..6b95a9f3 --- /dev/null +++ b/tests/unit/out/unsafe/anonymous-struct.rs @@ -0,0 +1,111 @@ +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))); + #[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 new file mode 100644 index 00000000..578d1f81 --- /dev/null +++ b/tests/unit/out/unsafe/anonymous-struct_c.rs @@ -0,0 +1,107 @@ +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))); + #[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/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_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_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; +} 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