From 0857fb51030360280822b51aedcd2251a68beb92 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 27 May 2026 10:29:50 +0100 Subject: [PATCH 1/2] Fix collision of anonymous structs from different functions --- cpp2rust/converter/converter_lib.cpp | 39 +++------- cpp2rust/converter/converter_lib.h | 2 - cpp2rust/converter/mapper.cpp | 14 +--- tests/unit/local_anon_struct_collision.c | 27 +++++++ tests/unit/out/refcount/anonymous-struct.rs | 74 +++++++++---------- tests/unit/out/refcount/anonymous-struct_c.rs | 54 +++++++------- .../refcount/local_anon_struct_collision.rs | 62 ++++++++++++++++ tests/unit/out/unsafe/anonymous-struct.rs | 44 +++++------ tests/unit/out/unsafe/anonymous-struct_c.rs | 40 +++++----- .../out/unsafe/local_anon_struct_collision.rs | 42 +++++++++++ .../unit/out/unsafe/union_addrof_external.rs | 15 ++-- tests/unit/out/unsafe/union_cross_arm_cast.rs | 6 +- .../unit/out/unsafe/union_field_alignment.rs | 6 +- tests/unit/out/unsafe/union_memset_memcpy.rs | 6 +- tests/unit/out/unsafe/union_nested.rs | 12 +-- .../unit/out/unsafe/union_struct_dual_use.rs | 6 +- .../unit/out/unsafe/union_tagged_many_arms.rs | 6 +- tests/unit/out/unsafe/union_tagged_simple.rs | 6 +- .../out/unsafe/union_tagged_struct_arms.rs | 22 +++--- .../out/unsafe/union_void_ptr_sized_deref.rs | 14 ++-- 20 files changed, 299 insertions(+), 198 deletions(-) create mode 100644 tests/unit/local_anon_struct_collision.c create mode 100644 tests/unit/out/refcount/local_anon_struct_collision.rs create mode 100644 tests/unit/out/unsafe/local_anon_struct_collision.rs diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 051aed2d..a8bf076c 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -328,25 +328,6 @@ 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; -} - static std::string GetLocationID(const clang::Decl *decl) { return GetFileName(decl) + std::to_string(GetLineNumber(decl)) + std::to_string(GetColumnNumber(decl)); @@ -373,15 +354,19 @@ 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; + // Anonymous record + if (name.empty() && (clang::isa(decl) || + clang::isa(decl))) { + const clang::NamedDecl *target = decl; + if (auto *field = clang::dyn_cast(decl)) { + if (auto *record = field->getType()->getAsRecordDecl(); + record && !record->getIdentifier()) { + target = record; + } } - return std::format("anon_{}", GetAnonIndex(target)); + return std::format( + "anon_{}", type_mapping.try_emplace(GetID(target), type_mapping.size()) + .first->second); } if (auto *fn = clang::dyn_cast(decl)) { diff --git a/cpp2rust/converter/converter_lib.h b/cpp2rust/converter/converter_lib.h index c208ea1c..cae8afbf 100644 --- a/cpp2rust/converter/converter_lib.h +++ b/cpp2rust/converter/converter_lib.h @@ -87,8 +87,6 @@ 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 8a7109a4..fc8779fa 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -571,18 +571,6 @@ 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_) { @@ -760,7 +748,7 @@ std::string ToString(const clang::NamedDecl *decl) { if (auto *typedef_decl = record->getTypedefNameForAnonDecl()) { return ToString(clang::cast(typedef_decl)); } - return synthesizeAnonRecordName(record); + return GetNamedDeclAsString(record); } if (auto *enum_decl = clang::dyn_cast(decl); diff --git a/tests/unit/local_anon_struct_collision.c b/tests/unit/local_anon_struct_collision.c new file mode 100644 index 00000000..ee4f8b92 --- /dev/null +++ b/tests/unit/local_anon_struct_collision.c @@ -0,0 +1,27 @@ +#include + +int first(void) { + struct { + int x; + int y; + } p; + p.x = 1; + p.y = 2; + return p.x + p.y; +} + +int second(void) { + struct { + long a; + long b; + } q; + q.a = 10; + q.b = 20; + return (int)(q.a + q.b); +} + +int main(void) { + assert(first() == 3); + assert(second() == 30); + return 0; +} diff --git a/tests/unit/out/refcount/anonymous-struct.rs b/tests/unit/out/refcount/anonymous-struct.rs index 60f64c58..fcd7db80 100644 --- a/tests/unit/out/refcount/anonymous-struct.rs +++ b/tests/unit/out/refcount/anonymous-struct.rs @@ -33,11 +33,11 @@ impl ByteRepr for Outer_Named { } } #[derive(Default)] -pub struct Outer_anon_0 { +pub struct anon_0 { pub c: Value, pub d: Value, } -impl Clone for Outer_anon_0 { +impl Clone for anon_0 { fn clone(&self) -> Self { let mut this = Self { c: Rc::new(RefCell::new((*self.c.borrow()))), @@ -46,7 +46,7 @@ impl Clone for Outer_anon_0 { this } } -impl ByteRepr for Outer_anon_0 { +impl ByteRepr for anon_0 { fn to_bytes(&self, buf: &mut [u8]) { (*self.c.borrow()).to_bytes(&mut buf[0..4]); (*self.d.borrow()).to_bytes(&mut buf[4..8]); @@ -59,11 +59,11 @@ impl ByteRepr for Outer_anon_0 { } } #[derive(Default)] -pub struct Outer_anon_1 { +pub struct anon_1 { pub g: Value, pub h: Value, } -impl Clone for Outer_anon_1 { +impl Clone for anon_1 { fn clone(&self) -> Self { let mut this = Self { g: Rc::new(RefCell::new((*self.g.borrow()))), @@ -72,7 +72,7 @@ impl Clone for Outer_anon_1 { this } } -impl ByteRepr for Outer_anon_1 { +impl ByteRepr for anon_1 { fn to_bytes(&self, buf: &mut [u8]) { (*self.g.borrow()).to_bytes(&mut buf[0..4]); (*self.h.borrow()).to_bytes(&mut buf[4..8]); @@ -85,11 +85,11 @@ impl ByteRepr for Outer_anon_1 { } } #[derive(Default)] -pub struct Outer_anon_2 { +pub struct anon_2 { pub e: Value, pub f: Value, } -impl Clone for Outer_anon_2 { +impl Clone for anon_2 { fn clone(&self) -> Self { let mut this = Self { e: Rc::new(RefCell::new((*self.e.borrow()))), @@ -98,7 +98,7 @@ impl Clone for Outer_anon_2 { this } } -impl ByteRepr for Outer_anon_2 { +impl ByteRepr for anon_2 { fn to_bytes(&self, buf: &mut [u8]) { (*self.e.borrow()).to_bytes(&mut buf[0..4]); (*self.f.borrow()).to_bytes(&mut buf[4..8]); @@ -111,10 +111,10 @@ impl ByteRepr for Outer_anon_2 { } } #[derive(Default)] -pub struct Outer_anon_3_anon_0 { +pub struct anon_4 { pub j: Value, } -impl Clone for Outer_anon_3_anon_0 { +impl Clone for anon_4 { fn clone(&self) -> Self { let mut this = Self { j: Rc::new(RefCell::new((*self.j.borrow()))), @@ -122,7 +122,7 @@ impl Clone for Outer_anon_3_anon_0 { this } } -impl ByteRepr for Outer_anon_3_anon_0 { +impl ByteRepr for anon_4 { fn to_bytes(&self, buf: &mut [u8]) { (*self.j.borrow()).to_bytes(&mut buf[0..4]); } @@ -133,10 +133,10 @@ impl ByteRepr for Outer_anon_3_anon_0 { } } #[derive(Default)] -pub struct Outer_anon_3_anon_1 { +pub struct anon_5 { pub k: Value, } -impl Clone for Outer_anon_3_anon_1 { +impl Clone for anon_5 { fn clone(&self) -> Self { let mut this = Self { k: Rc::new(RefCell::new((*self.k.borrow()))), @@ -144,7 +144,7 @@ impl Clone for Outer_anon_3_anon_1 { this } } -impl ByteRepr for Outer_anon_3_anon_1 { +impl ByteRepr for anon_5 { fn to_bytes(&self, buf: &mut [u8]) { (*self.k.borrow()).to_bytes(&mut buf[0..4]); } @@ -155,29 +155,29 @@ impl ByteRepr for Outer_anon_3_anon_1 { } } #[derive(Default)] -pub struct Outer_anon_3 { +pub struct anon_3 { pub i: Value, - pub inner_named: Value, - pub anon_1: Value, + pub inner_named: Value, + pub anon_5: Value, } -impl Clone for Outer_anon_3 { +impl Clone for 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())), + anon_5: Rc::new(RefCell::new((*self.anon_5.borrow()).clone())), }; this } } -impl ByteRepr for Outer_anon_3 {} +impl ByteRepr for 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, + 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 { @@ -201,24 +201,24 @@ fn main_0() -> i32 { a: Rc::new(RefCell::new(::default())), b: Rc::new(RefCell::new(::default())), })), - anonymous_named_0: Rc::new(RefCell::new(Outer_anon_0 { + anonymous_named_0: Rc::new(RefCell::new(anon_0 { c: Rc::new(RefCell::new(::default())), d: Rc::new(RefCell::new(::default())), })), - anonymous_named_1: Rc::new(RefCell::new(Outer_anon_1 { + anonymous_named_1: Rc::new(RefCell::new(anon_1 { g: Rc::new(RefCell::new(::default())), h: Rc::new(RefCell::new(::default())), })), - anon_2: Rc::new(RefCell::new(Outer_anon_2 { + anon_2: Rc::new(RefCell::new(anon_2 { e: Rc::new(RefCell::new(::default())), f: Rc::new(RefCell::new(::default())), })), - anon_3: Rc::new(RefCell::new(Outer_anon_3 { + anon_3: Rc::new(RefCell::new(anon_3 { i: Rc::new(RefCell::new(::default())), - inner_named: Rc::new(RefCell::new(Outer_anon_3_anon_0 { + inner_named: Rc::new(RefCell::new(anon_4 { j: Rc::new(RefCell::new(::default())), })), - anon_1: Rc::new(RefCell::new(Outer_anon_3_anon_1 { + anon_5: Rc::new(RefCell::new(anon_5 { k: Rc::new(RefCell::new(::default())), })), })), @@ -235,7 +235,7 @@ fn main_0() -> i32 { (*(*(*(*o.borrow()).anon_3.borrow()).inner_named.borrow()) .j .borrow_mut()) = 10; - (*(*(*(*o.borrow()).anon_3.borrow()).anon_1.borrow()) + (*(*(*(*o.borrow()).anon_3.borrow()).anon_5.borrow()) .k .borrow_mut()) = 11; assert!(((*(*(*o.borrow()).named.borrow()).a.borrow()) == 1)); @@ -254,17 +254,17 @@ fn main_0() -> i32 { == 10) ); assert!( - ((*(*(*(*o.borrow()).anon_3.borrow()).anon_1.borrow()) + ((*(*(*(*o.borrow()).anon_3.borrow()).anon_5.borrow()) .k .borrow()) == 11) ); #[derive(Default)] - pub struct anon_0 { + pub struct anon_6 { pub x: Value, pub z: Value, } - impl Clone for anon_0 { + impl Clone for anon_6 { fn clone(&self) -> Self { let mut this = Self { x: Rc::new(RefCell::new((*self.x.borrow()))), @@ -273,7 +273,7 @@ fn main_0() -> i32 { this } } - impl ByteRepr for anon_0 { + impl ByteRepr for anon_6 { fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.z.borrow()).to_bytes(&mut buf[4..8]); @@ -285,7 +285,7 @@ fn main_0() -> i32 { } } }; - let s: Value = Rc::new(RefCell::new(::default())); + let s: Value = Rc::new(RefCell::new(::default())); (*(*s.borrow()).x.borrow_mut()) = 1; (*(*s.borrow()).z.borrow_mut()) = 2; assert!( diff --git a/tests/unit/out/refcount/anonymous-struct_c.rs b/tests/unit/out/refcount/anonymous-struct_c.rs index d682a2d6..23ce8df8 100644 --- a/tests/unit/out/refcount/anonymous-struct_c.rs +++ b/tests/unit/out/refcount/anonymous-struct_c.rs @@ -24,11 +24,11 @@ impl ByteRepr for Named { } } #[derive(Default)] -pub struct Outer_anon_0 { +pub struct anon_0 { pub c: Value, pub d: Value, } -impl ByteRepr for Outer_anon_0 { +impl ByteRepr for anon_0 { fn to_bytes(&self, buf: &mut [u8]) { (*self.c.borrow()).to_bytes(&mut buf[0..4]); (*self.d.borrow()).to_bytes(&mut buf[4..8]); @@ -41,11 +41,11 @@ impl ByteRepr for Outer_anon_0 { } } #[derive(Default)] -pub struct Outer_anon_1 { +pub struct anon_1 { pub g: Value, pub h: Value, } -impl ByteRepr for Outer_anon_1 { +impl ByteRepr for anon_1 { fn to_bytes(&self, buf: &mut [u8]) { (*self.g.borrow()).to_bytes(&mut buf[0..4]); (*self.h.borrow()).to_bytes(&mut buf[4..8]); @@ -58,11 +58,11 @@ impl ByteRepr for Outer_anon_1 { } } #[derive(Default)] -pub struct Outer_anon_2 { +pub struct anon_2 { pub e: Value, pub f: Value, } -impl ByteRepr for Outer_anon_2 { +impl ByteRepr for anon_2 { fn to_bytes(&self, buf: &mut [u8]) { (*self.e.borrow()).to_bytes(&mut buf[0..4]); (*self.f.borrow()).to_bytes(&mut buf[4..8]); @@ -75,10 +75,10 @@ impl ByteRepr for Outer_anon_2 { } } #[derive(Default)] -pub struct Outer_anon_3_anon_0 { +pub struct anon_4 { pub j: Value, } -impl ByteRepr for Outer_anon_3_anon_0 { +impl ByteRepr for anon_4 { fn to_bytes(&self, buf: &mut [u8]) { (*self.j.borrow()).to_bytes(&mut buf[0..4]); } @@ -89,10 +89,10 @@ impl ByteRepr for Outer_anon_3_anon_0 { } } #[derive(Default)] -pub struct Outer_anon_3_anon_1 { +pub struct anon_5 { pub k: Value, } -impl ByteRepr for Outer_anon_3_anon_1 { +impl ByteRepr for anon_5 { fn to_bytes(&self, buf: &mut [u8]) { (*self.k.borrow()).to_bytes(&mut buf[0..4]); } @@ -103,19 +103,19 @@ impl ByteRepr for Outer_anon_3_anon_1 { } } #[derive(Default)] -pub struct Outer_anon_3 { +pub struct anon_3 { pub i: Value, - pub inner_named: Value, - pub anon_1: Value, + pub inner_named: Value, + pub anon_5: Value, } -impl ByteRepr for Outer_anon_3 {} +impl ByteRepr for anon_3 {} #[derive(Default)] pub struct Outer { pub named: Value, - pub anon0: Value, - pub anon1: Value, - pub anon_2: Value, - pub anon_3: Value, + pub anon0: Value, + pub anon1: Value, + pub anon_2: Value, + pub anon_3: Value, } impl ByteRepr for Outer {} pub fn main() { @@ -127,10 +127,10 @@ fn main_0() -> i32 { 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())), + 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; @@ -144,7 +144,7 @@ fn main_0() -> i32 { (*(*(*(*o.borrow()).anon_3.borrow()).inner_named.borrow()) .j .borrow_mut()) = 10; - (*(*(*(*o.borrow()).anon_3.borrow()).anon_1.borrow()) + (*(*(*(*o.borrow()).anon_3.borrow()).anon_5.borrow()) .k .borrow_mut()) = 11; assert!(((((*(*(*o.borrow()).named.borrow()).a.borrow()) == 1) as i32) != 0)); @@ -164,18 +164,18 @@ fn main_0() -> i32 { != 0) ); assert!( - ((((*(*(*(*o.borrow()).anon_3.borrow()).anon_1.borrow()) + ((((*(*(*(*o.borrow()).anon_3.borrow()).anon_5.borrow()) .k .borrow()) == 11) as i32) != 0) ); #[derive(Default)] - pub struct anon_0 { + pub struct anon_6 { pub x: Value, pub z: Value, } - impl ByteRepr for anon_0 { + impl ByteRepr for anon_6 { fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.z.borrow()).to_bytes(&mut buf[4..8]); @@ -187,7 +187,7 @@ fn main_0() -> i32 { } } }; - let s: Value = >::default(); + let s: Value = >::default(); (*(*s.borrow()).x.borrow_mut()) = 1; (*(*s.borrow()).z.borrow_mut()) = 2; assert!( diff --git a/tests/unit/out/refcount/local_anon_struct_collision.rs b/tests/unit/out/refcount/local_anon_struct_collision.rs new file mode 100644 index 00000000..c4b23e73 --- /dev/null +++ b/tests/unit/out/refcount/local_anon_struct_collision.rs @@ -0,0 +1,62 @@ +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 first_0() -> i32 { + #[derive(Default)] + pub struct anon_1 { + pub x: Value, + pub y: Value, + } + impl ByteRepr for anon_1 { + fn to_bytes(&self, buf: &mut [u8]) { + (*self.x.borrow()).to_bytes(&mut buf[0..4]); + (*self.y.borrow()).to_bytes(&mut buf[4..8]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + x: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + y: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + } + } + }; + let p: Value = >::default(); + (*(*p.borrow()).x.borrow_mut()) = 1; + (*(*p.borrow()).y.borrow_mut()) = 2; + return ((*(*p.borrow()).x.borrow()) + (*(*p.borrow()).y.borrow())); +} +pub fn second_2() -> i32 { + #[derive(Default)] + pub struct anon_3 { + pub a: Value, + pub b: Value, + } + impl ByteRepr for anon_3 { + fn to_bytes(&self, buf: &mut [u8]) { + (*self.a.borrow()).to_bytes(&mut buf[0..8]); + (*self.b.borrow()).to_bytes(&mut buf[8..16]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + a: Rc::new(RefCell::new(::from_bytes(&buf[0..8]))), + b: Rc::new(RefCell::new(::from_bytes(&buf[8..16]))), + } + } + }; + let q: Value = >::default(); + (*(*q.borrow()).a.borrow_mut()) = 10_i64; + (*(*q.borrow()).b.borrow_mut()) = 20_i64; + return (((*(*q.borrow()).a.borrow()) + (*(*q.borrow()).b.borrow())) as i32); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + assert!((((({ first_0() }) == 3) as i32) != 0)); + assert!((((({ second_2() }) == 30) as i32) != 0)); + return 0; +} diff --git a/tests/unit/out/unsafe/anonymous-struct.rs b/tests/unit/out/unsafe/anonymous-struct.rs index 8940f0ac..59c69a7f 100644 --- a/tests/unit/out/unsafe/anonymous-struct.rs +++ b/tests/unit/out/unsafe/anonymous-struct.rs @@ -14,47 +14,47 @@ pub struct Outer_Named { } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Outer_anon_0 { +pub struct anon_0 { pub c: i32, pub d: i32, } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Outer_anon_1 { +pub struct anon_1 { pub g: i32, pub h: i32, } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Outer_anon_2 { +pub struct anon_2 { pub e: i32, pub f: i32, } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Outer_anon_3_anon_0 { +pub struct anon_4 { pub j: i32, } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Outer_anon_3_anon_1 { +pub struct anon_5 { pub k: i32, } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Outer_anon_3 { +pub struct anon_3 { pub i: i32, - pub inner_named: Outer_anon_3_anon_0, - pub anon_1: Outer_anon_3_anon_1, + pub inner_named: anon_4, + pub anon_5: anon_5, } #[repr(C)] #[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 anonymous_named_0: anon_0, + pub anonymous_named_1: anon_1, + pub anon_2: anon_2, + pub anon_3: anon_3, } pub fn main() { unsafe { @@ -64,13 +64,13 @@ pub fn main() { 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 { + anonymous_named_0: anon_0 { c: 0_i32, d: 0_i32 }, + anonymous_named_1: anon_1 { g: 0_i32, h: 0_i32 }, + anon_2: anon_2 { e: 0_i32, f: 0_i32 }, + anon_3: 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 }, + inner_named: anon_4 { j: 0_i32 }, + anon_5: anon_5 { k: 0_i32 }, }, }; o.named.a = 1; @@ -83,7 +83,7 @@ unsafe fn main_0() -> i32 { o.anon_2.f = 8; o.anon_3.i = 9; o.anon_3.inner_named.j = 10; - o.anon_3.anon_1.k = 11; + o.anon_3.anon_5.k = 11; assert!(((o.named.a) == (1))); assert!(((o.named.b) == (2))); assert!(((o.anonymous_named_0.c) == (3))); @@ -94,14 +94,14 @@ unsafe fn main_0() -> i32 { 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))); + assert!(((o.anon_3.anon_5.k) == (11))); #[repr(C)] #[derive(Copy, Clone, Default)] - pub struct anon_0 { + pub struct anon_6 { pub x: i32, pub z: i32, }; - let mut s: anon_0 = ::default(); + let mut s: anon_6 = ::default(); s.x = 1; s.z = 2; assert!( diff --git a/tests/unit/out/unsafe/anonymous-struct_c.rs b/tests/unit/out/unsafe/anonymous-struct_c.rs index bbf8be7b..1c9915d9 100644 --- a/tests/unit/out/unsafe/anonymous-struct_c.rs +++ b/tests/unit/out/unsafe/anonymous-struct_c.rs @@ -14,47 +14,47 @@ pub struct Named { } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Outer_anon_0 { +pub struct anon_0 { pub c: i32, pub d: i32, } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Outer_anon_1 { +pub struct anon_1 { pub g: i32, pub h: i32, } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Outer_anon_2 { +pub struct anon_2 { pub e: i32, pub f: i32, } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Outer_anon_3_anon_0 { +pub struct anon_4 { pub j: i32, } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Outer_anon_3_anon_1 { +pub struct anon_5 { pub k: i32, } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Outer_anon_3 { +pub struct anon_3 { pub i: i32, - pub inner_named: Outer_anon_3_anon_0, - pub anon_1: Outer_anon_3_anon_1, + pub inner_named: anon_4, + pub anon_5: anon_5, } #[repr(C)] #[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 anon0: anon_0, + pub anon1: anon_1, + pub anon_2: anon_2, + pub anon_3: anon_3, } pub fn main() { unsafe { @@ -64,10 +64,10 @@ pub fn main() { 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(), + anon0: ::default(), + anon1: ::default(), + anon_2: ::default(), + anon_3: ::default(), }; o.named.a = 1; o.named.b = 2; @@ -79,7 +79,7 @@ unsafe fn main_0() -> i32 { o.anon_2.f = 8; o.anon_3.i = 9; o.anon_3.inner_named.j = 10; - o.anon_3.anon_1.k = 11; + o.anon_3.anon_5.k = 11; assert!(((((o.named.a) == (1)) as i32) != 0)); assert!(((((o.named.b) == (2)) as i32) != 0)); assert!(((((o.anon0.c) == (3)) as i32) != 0)); @@ -90,14 +90,14 @@ unsafe fn main_0() -> i32 { assert!(((((o.anon_2.f) == (8)) as i32) != 0)); assert!(((((o.anon_3.i) == (9)) as i32) != 0)); assert!(((((o.anon_3.inner_named.j) == (10)) as i32) != 0)); - assert!(((((o.anon_3.anon_1.k) == (11)) as i32) != 0)); + assert!(((((o.anon_3.anon_5.k) == (11)) as i32) != 0)); #[repr(C)] #[derive(Copy, Clone, Default)] - pub struct anon_0 { + pub struct anon_6 { pub x: i32, pub z: i32, }; - let mut s: anon_0 = ::default(); + let mut s: anon_6 = ::default(); s.x = 1; s.z = 2; assert!( diff --git a/tests/unit/out/unsafe/local_anon_struct_collision.rs b/tests/unit/out/unsafe/local_anon_struct_collision.rs new file mode 100644 index 00000000..4e0a72bd --- /dev/null +++ b/tests/unit/out/unsafe/local_anon_struct_collision.rs @@ -0,0 +1,42 @@ +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 unsafe fn first_0() -> i32 { + #[repr(C)] + #[derive(Copy, Clone, Default)] + pub struct anon_1 { + pub x: i32, + pub y: i32, + }; + let mut p: anon_1 = ::default(); + p.x = 1; + p.y = 2; + return ((p.x) + (p.y)); +} +pub unsafe fn second_2() -> i32 { + #[repr(C)] + #[derive(Copy, Clone, Default)] + pub struct anon_3 { + pub a: i64, + pub b: i64, + }; + let mut q: anon_3 = ::default(); + q.a = 10_i64; + q.b = 20_i64; + return (((q.a) + (q.b)) as i32); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + assert!(((((unsafe { first_0() }) == (3)) as i32) != 0)); + assert!(((((unsafe { second_2() }) == (30)) as i32) != 0)); + return 0; +} diff --git a/tests/unit/out/unsafe/union_addrof_external.rs b/tests/unit/out/unsafe/union_addrof_external.rs index 0084e009..266ced3e 100644 --- a/tests/unit/out/unsafe/union_addrof_external.rs +++ b/tests/unit/out/unsafe/union_addrof_external.rs @@ -26,11 +26,11 @@ impl Default for record { } #[repr(C)] #[derive(Copy, Clone)] -pub union Container_anon_0 { +pub union anon_0 { pub h: record, pub raw_: [u8; 128], } -impl Default for Container_anon_0 { +impl Default for anon_0 { fn default() -> Self { unsafe { std::mem::zeroed() } } @@ -38,9 +38,9 @@ impl Default for Container_anon_0 { #[repr(C)] #[derive(Copy, Clone, Default)] pub struct Container { - pub view: Container_anon_0, + pub view: anon_0, } -pub unsafe fn fill_0(mut out: *mut ::libc::c_void, mut cap: u64) { +pub unsafe fn fill_1(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, @@ -85,10 +85,9 @@ unsafe fn main_0() -> i32 { ((&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) + let _out: *mut ::libc::c_void = ((&mut c.view as *mut anon_0) as *mut ::libc::c_void); + let _cap: u64 = ::std::mem::size_of::() as u64; + fill_1(_out, _cap) }); assert!(((((c.view.h.code as i32) == (2)) as i32) != 0)); assert!( diff --git a/tests/unit/out/unsafe/union_cross_arm_cast.rs b/tests/unit/out/unsafe/union_cross_arm_cast.rs index ecc6ac93..4cefe6d5 100644 --- a/tests/unit/out/unsafe/union_cross_arm_cast.rs +++ b/tests/unit/out/unsafe/union_cross_arm_cast.rs @@ -42,12 +42,12 @@ impl Default for shape_b { } #[repr(C)] #[derive(Copy, Clone)] -pub union Container_anon_0 { +pub union anon_0 { pub a: shape_a, pub b: shape_b, pub raw_: [u8; 64], } -impl Default for Container_anon_0 { +impl Default for anon_0 { fn default() -> Self { unsafe { std::mem::zeroed() } } @@ -56,7 +56,7 @@ impl Default for Container_anon_0 { #[derive(Copy, Clone, Default)] pub struct Container { pub len: u32, - pub u: Container_anon_0, + pub u: anon_0, } pub fn main() { unsafe { diff --git a/tests/unit/out/unsafe/union_field_alignment.rs b/tests/unit/out/unsafe/union_field_alignment.rs index 9eaf35cf..f30c73da 100644 --- a/tests/unit/out/unsafe/union_field_alignment.rs +++ b/tests/unit/out/unsafe/union_field_alignment.rs @@ -8,11 +8,11 @@ use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; #[repr(C)] #[derive(Copy, Clone)] -pub union node_anon_0 { +pub union anon_0 { pub bytes: [u8; 1], pub aligner: *mut ::libc::c_void, } -impl Default for node_anon_0 { +impl Default for anon_0 { fn default() -> Self { unsafe { std::mem::zeroed() } } @@ -21,7 +21,7 @@ impl Default for node_anon_0 { #[derive(Copy, Clone, Default)] pub struct node { pub next: *mut node, - pub x: node_anon_0, + pub x: anon_0, } pub fn main() { unsafe { diff --git a/tests/unit/out/unsafe/union_memset_memcpy.rs b/tests/unit/out/unsafe/union_memset_memcpy.rs index 0d90cf0b..a65d549e 100644 --- a/tests/unit/out/unsafe/union_memset_memcpy.rs +++ b/tests/unit/out/unsafe/union_memset_memcpy.rs @@ -40,12 +40,12 @@ impl Default for shape_b { } #[repr(C)] #[derive(Copy, Clone)] -pub union Container_anon_0 { +pub union anon_0 { pub a: shape_a, pub b: shape_b, pub raw_: [u8; 256], } -impl Default for Container_anon_0 { +impl Default for anon_0 { fn default() -> Self { unsafe { std::mem::zeroed() } } @@ -53,7 +53,7 @@ impl Default for Container_anon_0 { #[repr(C)] #[derive(Copy, Clone, Default)] pub struct Container { - pub view: Container_anon_0, + pub view: anon_0, } pub fn main() { unsafe { diff --git a/tests/unit/out/unsafe/union_nested.rs b/tests/unit/out/unsafe/union_nested.rs index ccc9f939..280df299 100644 --- a/tests/unit/out/unsafe/union_nested.rs +++ b/tests/unit/out/unsafe/union_nested.rs @@ -22,11 +22,11 @@ impl Default for record { } #[repr(C)] #[derive(Copy, Clone)] -pub union inner_anon_0 { +pub union anon_0 { pub h: record, pub raw_: [u8; 128], } -impl Default for inner_anon_0 { +impl Default for anon_0 { fn default() -> Self { unsafe { std::mem::zeroed() } } @@ -34,15 +34,15 @@ impl Default for inner_anon_0 { #[repr(C)] #[derive(Copy, Clone, Default)] pub struct inner { - pub view: inner_anon_0, + pub view: anon_0, } #[repr(C)] #[derive(Copy, Clone)] -pub union Outer_anon_0 { +pub union anon_1 { pub h: record, pub nested: inner, } -impl Default for Outer_anon_0 { +impl Default for anon_1 { fn default() -> Self { unsafe { std::mem::zeroed() } } @@ -54,7 +54,7 @@ pub struct Outer { pub level: i32, pub variant: i32, pub len: u32, - pub body: Outer_anon_0, + pub body: anon_1, } pub fn main() { unsafe { diff --git a/tests/unit/out/unsafe/union_struct_dual_use.rs b/tests/unit/out/unsafe/union_struct_dual_use.rs index 7bbe483c..2e2beb04 100644 --- a/tests/unit/out/unsafe/union_struct_dual_use.rs +++ b/tests/unit/out/unsafe/union_struct_dual_use.rs @@ -17,11 +17,11 @@ pub unsafe fn sum_inner_0(mut i: *mut Inner) -> i32 { } #[repr(C)] #[derive(Copy, Clone)] -pub union Outer_anon_0 { +pub union anon_1 { pub inner: Inner, pub raw_: [u8; 16], } -impl Default for Outer_anon_0 { +impl Default for anon_1 { fn default() -> Self { unsafe { std::mem::zeroed() } } @@ -29,7 +29,7 @@ impl Default for Outer_anon_0 { #[repr(C)] #[derive(Copy, Clone, Default)] pub struct Outer { - pub u: Outer_anon_0, + pub u: anon_1, } pub fn main() { unsafe { diff --git a/tests/unit/out/unsafe/union_tagged_many_arms.rs b/tests/unit/out/unsafe/union_tagged_many_arms.rs index b1ac0bda..68fa5187 100644 --- a/tests/unit/out/unsafe/union_tagged_many_arms.rs +++ b/tests/unit/out/unsafe/union_tagged_many_arms.rs @@ -30,14 +30,14 @@ impl From for Tag { libcc2rs::impl_enum_inc_dec!(Tag); #[repr(C)] #[derive(Copy, Clone)] -pub union Slot_anon_0 { +pub union anon_0 { pub text: *const u8, pub handle: *mut ::libc::c_void, pub signed_n: i64, pub unsigned_n: u64, pub f: f64, } -impl Default for Slot_anon_0 { +impl Default for anon_0 { fn default() -> Self { unsafe { std::mem::zeroed() } } @@ -46,7 +46,7 @@ impl Default for Slot_anon_0 { #[derive(Copy, Clone, Default)] pub struct Slot { pub tag: Tag, - pub payload: Slot_anon_0, + pub payload: anon_0, } pub fn main() { unsafe { diff --git a/tests/unit/out/unsafe/union_tagged_simple.rs b/tests/unit/out/unsafe/union_tagged_simple.rs index 834c22fe..b6ce9160 100644 --- a/tests/unit/out/unsafe/union_tagged_simple.rs +++ b/tests/unit/out/unsafe/union_tagged_simple.rs @@ -24,11 +24,11 @@ impl From for Kind { libcc2rs::impl_enum_inc_dec!(Kind); #[repr(C)] #[derive(Copy, Clone)] -pub union Event_anon_0 { +pub union anon_0 { pub obj: *mut ::libc::c_void, pub code: i32, } -impl Default for Event_anon_0 { +impl Default for anon_0 { fn default() -> Self { unsafe { std::mem::zeroed() } } @@ -38,7 +38,7 @@ impl Default for Event_anon_0 { pub struct Event { pub kind: Kind, pub handle: *mut ::libc::c_void, - pub payload: Event_anon_0, + pub payload: anon_0, } pub fn main() { unsafe { diff --git a/tests/unit/out/unsafe/union_tagged_struct_arms.rs b/tests/unit/out/unsafe/union_tagged_struct_arms.rs index 52ec1c70..6bf0689a 100644 --- a/tests/unit/out/unsafe/union_tagged_struct_arms.rs +++ b/tests/unit/out/unsafe/union_tagged_struct_arms.rs @@ -26,14 +26,14 @@ impl From for Choice { libcc2rs::impl_enum_inc_dec!(Choice); #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Branch_anon_0_anon_0 { +pub struct anon_1 { pub items: *mut *mut u8, pub count: i64, pub cursor: i64, } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Branch_anon_0_anon_1 { +pub struct anon_2 { pub lo: i32, pub hi: i32, pub curr: i32, @@ -41,7 +41,7 @@ pub struct Branch_anon_0_anon_1 { } #[repr(C)] #[derive(Copy, Clone, Default)] -pub struct Branch_anon_0_anon_2 { +pub struct anon_3 { pub lo: i64, pub hi: i64, pub curr: i64, @@ -50,12 +50,12 @@ pub struct Branch_anon_0_anon_2 { } #[repr(C)] #[derive(Copy, Clone)] -pub union Branch_anon_0 { - pub list: Branch_anon_0_anon_0, - pub letters: Branch_anon_0_anon_1, - pub integers: Branch_anon_0_anon_2, +pub union anon_0 { + pub list: anon_1, + pub letters: anon_2, + pub integers: anon_3, } -impl Default for Branch_anon_0 { +impl Default for anon_0 { fn default() -> Self { unsafe { std::mem::zeroed() } } @@ -65,7 +65,7 @@ impl Default for Branch_anon_0 { pub struct Branch { pub choice: Choice, pub index: i32, - pub v: Branch_anon_0, + pub v: anon_0, } pub fn main() { unsafe { @@ -73,7 +73,7 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - static mut items: [*mut u8; 3] = unsafe { + static mut items_4: [*mut u8; 3] = unsafe { [ b"a\0".as_ptr().cast_mut(), b"b\0".as_ptr().cast_mut(), @@ -83,7 +83,7 @@ unsafe fn main_0() -> i32 { let mut p_list: Branch = ::default(); p_list.choice = Choice::C_LIST; p_list.index = 0; - p_list.v.list.items = items.as_mut_ptr(); + p_list.v.list.items = items_4.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)) as i32) != 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 index 3391a818..b4ee56c8 100644 --- a/tests/unit/out/unsafe/union_void_ptr_sized_deref.rs +++ b/tests/unit/out/unsafe/union_void_ptr_sized_deref.rs @@ -26,13 +26,13 @@ impl From for Width { libcc2rs::impl_enum_inc_dec!(Width); #[repr(C)] #[derive(Copy, Clone)] -pub union Sink_anon_0 { +pub union anon_0 { pub text: *const u8, pub handle: *mut ::libc::c_void, pub signed_n: i64, pub f: f64, } -impl Default for Sink_anon_0 { +impl Default for anon_0 { fn default() -> Self { unsafe { std::mem::zeroed() } } @@ -41,9 +41,9 @@ impl Default for Sink_anon_0 { #[derive(Copy, Clone, Default)] pub struct Sink { pub width: Width, - pub out: Sink_anon_0, + pub out: anon_0, } -pub unsafe fn write_count_0(mut s: *mut Sink, mut count: i64) { +pub unsafe fn write_count_1(mut s: *mut Sink, mut count: i64) { 'switch: { let __match_cond = ((*s).width as u32); match __match_cond { @@ -78,7 +78,7 @@ unsafe fn main_0() -> i32 { (unsafe { let _s: *mut Sink = (&mut s as *mut Sink); let _count: i64 = 1234605616436508552_i64; - write_count_0(_s, _count) + write_count_1(_s, _count) }); assert!(((((buf64) == (1234605616436508552_i64)) as i32) != 0)); s.width = Width::W_32; @@ -86,7 +86,7 @@ unsafe fn main_0() -> i32 { (unsafe { let _s: *mut Sink = (&mut s as *mut Sink); let _count: i64 = 305419896_i64; - write_count_0(_s, _count) + write_count_1(_s, _count) }); assert!(((((buf32) == (305419896)) as i32) != 0)); s.width = Width::W_16; @@ -94,7 +94,7 @@ unsafe fn main_0() -> i32 { (unsafe { let _s: *mut Sink = (&mut s as *mut Sink); let _count: i64 = 4660_i64; - write_count_0(_s, _count) + write_count_1(_s, _count) }); assert!(((((buf16 as i32) == (4660)) as i32) != 0)); return 0; From ab3e31cb1adc303f00a646b3501326763f217c9c Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 27 May 2026 11:13:42 +0100 Subject: [PATCH 2/2] Update tests --- tests/unit/out/unsafe/union_tagged_struct_arms.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/out/unsafe/union_tagged_struct_arms.rs b/tests/unit/out/unsafe/union_tagged_struct_arms.rs index 6bf0689a..24089174 100644 --- a/tests/unit/out/unsafe/union_tagged_struct_arms.rs +++ b/tests/unit/out/unsafe/union_tagged_struct_arms.rs @@ -73,7 +73,7 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - static mut items_4: [*mut u8; 3] = unsafe { + static mut items: [*mut u8; 3] = unsafe { [ b"a\0".as_ptr().cast_mut(), b"b\0".as_ptr().cast_mut(), @@ -83,7 +83,7 @@ unsafe fn main_0() -> i32 { let mut p_list: Branch = ::default(); p_list.choice = Choice::C_LIST; p_list.index = 0; - p_list.v.list.items = items_4.as_mut_ptr(); + 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)) as i32) != 0));