From 54326e773070fe4495c57649d6714cea4795a80d Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 3 Jun 2026 13:28:03 +0100 Subject: [PATCH 1/4] Fix collision of anonymous enum names --- cpp2rust/converter/converter_lib.cpp | 5 +++-- cpp2rust/converter/mapper.cpp | 2 +- .../cross_tu_anon_enum_collision/CMakeLists.txt | 3 +++ .../multi-file/cross_tu_anon_enum_collision/a.c | 17 +++++++++++++++++ .../multi-file/cross_tu_anon_enum_collision/b.c | 9 +++++++++ 5 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 tests/multi-file/cross_tu_anon_enum_collision/CMakeLists.txt create mode 100644 tests/multi-file/cross_tu_anon_enum_collision/a.c create mode 100644 tests/multi-file/cross_tu_anon_enum_collision/b.c diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 1999c8df..f3fd27e4 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -408,9 +408,10 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) { auto name = decl->getDeclName().isIdentifier() ? decl->getName().str() : decl->getNameAsString(); - // Anonymous record + // Anonymous record or enum if (name.empty() && (clang::isa(decl) || - clang::isa(decl))) { + clang::isa(decl) || + clang::isa(decl))) { const clang::NamedDecl *target = decl; if (auto *field = clang::dyn_cast(decl)) { if (auto *record = field->getType()->getAsRecordDecl(); diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index d332b180..3b1f7bc9 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -765,7 +765,7 @@ std::string ToString(const clang::NamedDecl *decl) { } if (!enum_decl->getIdentifier() && !enum_decl->getTypedefNameForAnonDecl()) { - return std::format("anon_enum_{}", GetLineNumber(enum_decl)); + return GetNamedDeclAsString(enum_decl); } } diff --git a/tests/multi-file/cross_tu_anon_enum_collision/CMakeLists.txt b/tests/multi-file/cross_tu_anon_enum_collision/CMakeLists.txt new file mode 100644 index 00000000..979b6244 --- /dev/null +++ b/tests/multi-file/cross_tu_anon_enum_collision/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.16) +project(cross_tu_anon_enum_collision LANGUAGES C) +add_executable(app a.c b.c) diff --git a/tests/multi-file/cross_tu_anon_enum_collision/a.c b/tests/multi-file/cross_tu_anon_enum_collision/a.c new file mode 100644 index 00000000..604acb8a --- /dev/null +++ b/tests/multi-file/cross_tu_anon_enum_collision/a.c @@ -0,0 +1,17 @@ +#include +// anon enum below shares the same declaration line as b.c:enum { BETA = 9 } +enum { ALPHA = 7 }; + +int b_value(void); + +int a_value(void) { + int x = 0; + x |= ALPHA; + return x; +} + +int main(void) { + assert(a_value() == 7); + assert(b_value() == 9); + return 0; +} diff --git a/tests/multi-file/cross_tu_anon_enum_collision/b.c b/tests/multi-file/cross_tu_anon_enum_collision/b.c new file mode 100644 index 00000000..60a4150f --- /dev/null +++ b/tests/multi-file/cross_tu_anon_enum_collision/b.c @@ -0,0 +1,9 @@ +// anon enum below shares the same declaration line as b.c:enum { ALPHA = 7 } + +enum { BETA = 9 }; + +int b_value(void) { + int x = 0; + x |= BETA; + return x; +} From 7a5571af9bc075c580bdc5c320dfe1a9258f8aa2 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 3 Jun 2026 15:19:37 +0100 Subject: [PATCH 2/4] Update tests --- tests/unit/out/refcount/anonymous_enum.rs | 72 ++++++++-------- tests/unit/out/refcount/anonymous_enum_c.rs | 96 ++++++++++----------- tests/unit/out/unsafe/anonymous_enum.rs | 72 ++++++++-------- tests/unit/out/unsafe/anonymous_enum_c.rs | 94 ++++++++++---------- 4 files changed, 166 insertions(+), 168 deletions(-) diff --git a/tests/unit/out/refcount/anonymous_enum.rs b/tests/unit/out/refcount/anonymous_enum.rs index fb540cf7..25de7201 100644 --- a/tests/unit/out/refcount/anonymous_enum.rs +++ b/tests/unit/out/refcount/anonymous_enum.rs @@ -7,37 +7,37 @@ use std::io::{Read, Seek, Write}; use std::os::fd::AsFd; use std::rc::{Rc, Weak}; #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_3 { +enum anon_0 { #[default] FIRST_A = 0, FIRST_B = 1, } -impl From for anon_enum_3 { - fn from(n: i32) -> anon_enum_3 { +impl From for anon_0 { + fn from(n: i32) -> anon_0 { match n { - 0 => anon_enum_3::FIRST_A, - 1 => anon_enum_3::FIRST_B, - _ => panic!("invalid anon_enum_3 value: {}", n), + 0 => anon_0::FIRST_A, + 1 => anon_0::FIRST_B, + _ => panic!("invalid anon_0 value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(anon_enum_3); +libcc2rs::impl_enum_inc_dec!(anon_0); #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_11 { +enum anon_1 { #[default] SECOND_A = 0, SECOND_B = 1, } -impl From for anon_enum_11 { - fn from(n: i32) -> anon_enum_11 { +impl From for anon_1 { + fn from(n: i32) -> anon_1 { match n { - 0 => anon_enum_11::SECOND_A, - 1 => anon_enum_11::SECOND_B, - _ => panic!("invalid anon_enum_11 value: {}", n), + 0 => anon_1::SECOND_A, + 1 => anon_1::SECOND_B, + _ => panic!("invalid anon_1 value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(anon_enum_11); +libcc2rs::impl_enum_inc_dec!(anon_1); #[derive(Default)] pub struct S { pub a: Value, @@ -77,25 +77,25 @@ impl From for TdEnum { } libcc2rs::impl_enum_inc_dec!(TdEnum); #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_24 { +enum anon_2 { #[default] FIELD_A = 0, FIELD_B = 1, } -impl From for anon_enum_24 { - fn from(n: i32) -> anon_enum_24 { +impl From for anon_2 { + fn from(n: i32) -> anon_2 { match n { - 0 => anon_enum_24::FIELD_A, - 1 => anon_enum_24::FIELD_B, - _ => panic!("invalid anon_enum_24 value: {}", n), + 0 => anon_2::FIELD_A, + 1 => anon_2::FIELD_B, + _ => panic!("invalid anon_2 value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(anon_enum_24); +libcc2rs::impl_enum_inc_dec!(anon_2); #[derive(Default)] pub struct WithAnonField { pub a: Value, - pub field: Value, + pub field: Value, } impl Clone for WithAnonField { fn clone(&self) -> Self { @@ -112,32 +112,32 @@ pub fn main() { } fn main_0() -> i32 { #[derive(Clone, Copy, PartialEq, Debug, Default)] - enum anon_enum_31 { + enum anon_3 { #[default] THIRD_A = 0, THIRD_B = 1, } - impl From for anon_enum_31 { - fn from(n: i32) -> anon_enum_31 { + impl From for anon_3 { + fn from(n: i32) -> anon_3 { match n { - 0 => anon_enum_31::THIRD_A, - 1 => anon_enum_31::THIRD_B, - _ => panic!("invalid anon_enum_31 value: {}", n), + 0 => anon_3::THIRD_A, + 1 => anon_3::THIRD_B, + _ => panic!("invalid anon_3 value: {}", n), } } } - libcc2rs::impl_enum_inc_dec!(anon_enum_31); - assert!(((anon_enum_3::FIRST_A as i32) != (anon_enum_3::FIRST_B as i32))); - assert!(((anon_enum_11::SECOND_A as i32) != (anon_enum_11::SECOND_B as i32))); - assert!(((anon_enum_31::THIRD_A as i32) != (anon_enum_31::THIRD_B as i32))); + libcc2rs::impl_enum_inc_dec!(anon_3); + assert!(((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32))); + assert!(((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32))); + assert!(((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32))); let td: Value = Rc::new(RefCell::new(TdEnum::TD_A)); assert!((((*td.borrow()) as i32) == (TdEnum::TD_A as i32))); (*td.borrow_mut()) = TdEnum::TD_B; assert!((((*td.borrow()) as i32) == (TdEnum::TD_B as i32))); let w: Value = Rc::new(RefCell::new(::default())); - (*(*w.borrow()).field.borrow_mut()) = anon_enum_24::FIELD_A; - assert!((((*(*w.borrow()).field.borrow()) as i32) == (anon_enum_24::FIELD_A as i32))); - (*(*w.borrow()).field.borrow_mut()) = anon_enum_24::FIELD_B; - assert!((((*(*w.borrow()).field.borrow()) as i32) == (anon_enum_24::FIELD_B as i32))); + (*(*w.borrow()).field.borrow_mut()) = anon_2::FIELD_A; + assert!((((*(*w.borrow()).field.borrow()) as i32) == (anon_2::FIELD_A as i32))); + (*(*w.borrow()).field.borrow_mut()) = anon_2::FIELD_B; + assert!((((*(*w.borrow()).field.borrow()) as i32) == (anon_2::FIELD_B as i32))); return 0; } diff --git a/tests/unit/out/refcount/anonymous_enum_c.rs b/tests/unit/out/refcount/anonymous_enum_c.rs index d4d31b73..c1032796 100644 --- a/tests/unit/out/refcount/anonymous_enum_c.rs +++ b/tests/unit/out/refcount/anonymous_enum_c.rs @@ -7,37 +7,37 @@ use std::io::{Read, Seek, Write}; use std::os::fd::AsFd; use std::rc::{Rc, Weak}; #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_3 { +enum anon_0 { #[default] FIRST_A = 0, FIRST_B = 1, } -impl From for anon_enum_3 { - fn from(n: i32) -> anon_enum_3 { +impl From for anon_0 { + fn from(n: i32) -> anon_0 { match n { - 0 => anon_enum_3::FIRST_A, - 1 => anon_enum_3::FIRST_B, - _ => panic!("invalid anon_enum_3 value: {}", n), + 0 => anon_0::FIRST_A, + 1 => anon_0::FIRST_B, + _ => panic!("invalid anon_0 value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(anon_enum_3); +libcc2rs::impl_enum_inc_dec!(anon_0); #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_11 { +enum anon_1 { #[default] SECOND_A = 0, SECOND_B = 1, } -impl From for anon_enum_11 { - fn from(n: i32) -> anon_enum_11 { +impl From for anon_1 { + fn from(n: i32) -> anon_1 { match n { - 0 => anon_enum_11::SECOND_A, - 1 => anon_enum_11::SECOND_B, - _ => panic!("invalid anon_enum_11 value: {}", n), + 0 => anon_1::SECOND_A, + 1 => anon_1::SECOND_B, + _ => panic!("invalid anon_1 value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(anon_enum_11); +libcc2rs::impl_enum_inc_dec!(anon_1); #[derive(Default)] pub struct S { pub a: Value, @@ -53,41 +53,41 @@ impl ByteRepr for S { } } #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum TdEnum_enum { +enum TdEnum { #[default] TD_A = 0, TD_B = 1, } -impl From for TdEnum_enum { - fn from(n: i32) -> TdEnum_enum { +impl From for TdEnum { + fn from(n: i32) -> TdEnum { match n { - 0 => TdEnum_enum::TD_A, - 1 => TdEnum_enum::TD_B, - _ => panic!("invalid TdEnum_enum value: {}", n), + 0 => TdEnum::TD_A, + 1 => TdEnum::TD_B, + _ => panic!("invalid TdEnum value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(TdEnum_enum); +libcc2rs::impl_enum_inc_dec!(TdEnum); #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_24 { +enum anon_2 { #[default] FIELD_A = 0, FIELD_B = 1, } -impl From for anon_enum_24 { - fn from(n: i32) -> anon_enum_24 { +impl From for anon_2 { + fn from(n: i32) -> anon_2 { match n { - 0 => anon_enum_24::FIELD_A, - 1 => anon_enum_24::FIELD_B, - _ => panic!("invalid anon_enum_24 value: {}", n), + 0 => anon_2::FIELD_A, + 1 => anon_2::FIELD_B, + _ => panic!("invalid anon_2 value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(anon_enum_24); +libcc2rs::impl_enum_inc_dec!(anon_2); #[derive(Default)] pub struct WithAnonField { pub a: Value, - pub field: Value, + pub field: Value, } impl ByteRepr for WithAnonField {} pub fn main() { @@ -95,39 +95,37 @@ pub fn main() { } fn main_0() -> i32 { #[derive(Clone, Copy, PartialEq, Debug, Default)] - enum anon_enum_31 { + enum anon_3 { #[default] THIRD_A = 0, THIRD_B = 1, } - impl From for anon_enum_31 { - fn from(n: i32) -> anon_enum_31 { + impl From for anon_3 { + fn from(n: i32) -> anon_3 { match n { - 0 => anon_enum_31::THIRD_A, - 1 => anon_enum_31::THIRD_B, - _ => panic!("invalid anon_enum_31 value: {}", n), + 0 => anon_3::THIRD_A, + 1 => anon_3::THIRD_B, + _ => panic!("invalid anon_3 value: {}", n), } } } - libcc2rs::impl_enum_inc_dec!(anon_enum_31); - assert!(((((anon_enum_3::FIRST_A as i32) != (anon_enum_3::FIRST_B as i32)) as i32) != 0)); - assert!(((((anon_enum_11::SECOND_A as i32) != (anon_enum_11::SECOND_B as i32)) as i32) != 0)); - assert!(((((anon_enum_31::THIRD_A as i32) != (anon_enum_31::THIRD_B as i32)) as i32) != 0)); - let td: Value = Rc::new(RefCell::new(TdEnum_enum::TD_A)); - assert!((((((*td.borrow()) as u32) == ((TdEnum_enum::TD_A as i32) as u32)) as i32) != 0)); - (*td.borrow_mut()) = TdEnum_enum::TD_B; - assert!((((((*td.borrow()) as u32) == ((TdEnum_enum::TD_B as i32) as u32)) as i32) != 0)); + libcc2rs::impl_enum_inc_dec!(anon_3); + assert!(((((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32)) as i32) != 0)); + assert!(((((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32)) as i32) != 0)); + assert!(((((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32)) as i32) != 0)); + let td: Value = Rc::new(RefCell::new(TdEnum::TD_A)); + assert!((((((*td.borrow()) as u32) == ((TdEnum::TD_A as i32) as u32)) as i32) != 0)); + (*td.borrow_mut()) = TdEnum::TD_B; + assert!((((((*td.borrow()) as u32) == ((TdEnum::TD_B as i32) as u32)) as i32) != 0)); let w: Value = >::default(); - (*(*w.borrow()).field.borrow_mut()) = anon_enum_24::FIELD_A; + (*(*w.borrow()).field.borrow_mut()) = anon_2::FIELD_A; assert!( - (((((*(*w.borrow()).field.borrow()) as u32) == ((anon_enum_24::FIELD_A as i32) as u32)) - as i32) + (((((*(*w.borrow()).field.borrow()) as u32) == ((anon_2::FIELD_A as i32) as u32)) as i32) != 0) ); - (*(*w.borrow()).field.borrow_mut()) = anon_enum_24::FIELD_B; + (*(*w.borrow()).field.borrow_mut()) = anon_2::FIELD_B; assert!( - (((((*(*w.borrow()).field.borrow()) as u32) == ((anon_enum_24::FIELD_B as i32) as u32)) - as i32) + (((((*(*w.borrow()).field.borrow()) as u32) == ((anon_2::FIELD_B as i32) as u32)) as i32) != 0) ); return 0; diff --git a/tests/unit/out/unsafe/anonymous_enum.rs b/tests/unit/out/unsafe/anonymous_enum.rs index 55f89d26..ce23505f 100644 --- a/tests/unit/out/unsafe/anonymous_enum.rs +++ b/tests/unit/out/unsafe/anonymous_enum.rs @@ -7,37 +7,37 @@ use std::io::{Read, Seek, Write}; use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_3 { +enum anon_0 { #[default] FIRST_A = 0, FIRST_B = 1, } -impl From for anon_enum_3 { - fn from(n: i32) -> anon_enum_3 { +impl From for anon_0 { + fn from(n: i32) -> anon_0 { match n { - 0 => anon_enum_3::FIRST_A, - 1 => anon_enum_3::FIRST_B, - _ => panic!("invalid anon_enum_3 value: {}", n), + 0 => anon_0::FIRST_A, + 1 => anon_0::FIRST_B, + _ => panic!("invalid anon_0 value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(anon_enum_3); +libcc2rs::impl_enum_inc_dec!(anon_0); #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_11 { +enum anon_1 { #[default] SECOND_A = 0, SECOND_B = 1, } -impl From for anon_enum_11 { - fn from(n: i32) -> anon_enum_11 { +impl From for anon_1 { + fn from(n: i32) -> anon_1 { match n { - 0 => anon_enum_11::SECOND_A, - 1 => anon_enum_11::SECOND_B, - _ => panic!("invalid anon_enum_11 value: {}", n), + 0 => anon_1::SECOND_A, + 1 => anon_1::SECOND_B, + _ => panic!("invalid anon_1 value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(anon_enum_11); +libcc2rs::impl_enum_inc_dec!(anon_1); #[repr(C)] #[derive(Copy, Clone, Default)] pub struct S { @@ -60,26 +60,26 @@ impl From for TdEnum { } libcc2rs::impl_enum_inc_dec!(TdEnum); #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_24 { +enum anon_2 { #[default] FIELD_A = 0, FIELD_B = 1, } -impl From for anon_enum_24 { - fn from(n: i32) -> anon_enum_24 { +impl From for anon_2 { + fn from(n: i32) -> anon_2 { match n { - 0 => anon_enum_24::FIELD_A, - 1 => anon_enum_24::FIELD_B, - _ => panic!("invalid anon_enum_24 value: {}", n), + 0 => anon_2::FIELD_A, + 1 => anon_2::FIELD_B, + _ => panic!("invalid anon_2 value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(anon_enum_24); +libcc2rs::impl_enum_inc_dec!(anon_2); #[repr(C)] #[derive(Copy, Clone, Default)] pub struct WithAnonField { pub a: i32, - pub field: anon_enum_24, + pub field: anon_2, } pub fn main() { unsafe { @@ -88,32 +88,32 @@ pub fn main() { } unsafe fn main_0() -> i32 { #[derive(Clone, Copy, PartialEq, Debug, Default)] - enum anon_enum_31 { + enum anon_3 { #[default] THIRD_A = 0, THIRD_B = 1, } - impl From for anon_enum_31 { - fn from(n: i32) -> anon_enum_31 { + impl From for anon_3 { + fn from(n: i32) -> anon_3 { match n { - 0 => anon_enum_31::THIRD_A, - 1 => anon_enum_31::THIRD_B, - _ => panic!("invalid anon_enum_31 value: {}", n), + 0 => anon_3::THIRD_A, + 1 => anon_3::THIRD_B, + _ => panic!("invalid anon_3 value: {}", n), } } } - libcc2rs::impl_enum_inc_dec!(anon_enum_31); - assert!(((anon_enum_3::FIRST_A as i32) != (anon_enum_3::FIRST_B as i32))); - assert!(((anon_enum_11::SECOND_A as i32) != (anon_enum_11::SECOND_B as i32))); - assert!(((anon_enum_31::THIRD_A as i32) != (anon_enum_31::THIRD_B as i32))); + libcc2rs::impl_enum_inc_dec!(anon_3); + assert!(((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32))); + assert!(((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32))); + assert!(((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32))); let mut td: TdEnum = TdEnum::TD_A; assert!(((td as i32) == (TdEnum::TD_A as i32))); td = (TdEnum::TD_B).clone(); assert!(((td as i32) == (TdEnum::TD_B as i32))); let mut w: WithAnonField = ::default(); - w.field = anon_enum_24::FIELD_A; - assert!(((w.field as i32) == (anon_enum_24::FIELD_A as i32))); - w.field = (anon_enum_24::FIELD_B).clone(); - assert!(((w.field as i32) == (anon_enum_24::FIELD_B as i32))); + w.field = anon_2::FIELD_A; + assert!(((w.field as i32) == (anon_2::FIELD_A as i32))); + w.field = (anon_2::FIELD_B).clone(); + assert!(((w.field as i32) == (anon_2::FIELD_B as i32))); return 0; } diff --git a/tests/unit/out/unsafe/anonymous_enum_c.rs b/tests/unit/out/unsafe/anonymous_enum_c.rs index 260b7a26..c0d9f4e8 100644 --- a/tests/unit/out/unsafe/anonymous_enum_c.rs +++ b/tests/unit/out/unsafe/anonymous_enum_c.rs @@ -7,79 +7,79 @@ use std::io::{Read, Seek, Write}; use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_3 { +enum anon_0 { #[default] FIRST_A = 0, FIRST_B = 1, } -impl From for anon_enum_3 { - fn from(n: i32) -> anon_enum_3 { +impl From for anon_0 { + fn from(n: i32) -> anon_0 { match n { - 0 => anon_enum_3::FIRST_A, - 1 => anon_enum_3::FIRST_B, - _ => panic!("invalid anon_enum_3 value: {}", n), + 0 => anon_0::FIRST_A, + 1 => anon_0::FIRST_B, + _ => panic!("invalid anon_0 value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(anon_enum_3); +libcc2rs::impl_enum_inc_dec!(anon_0); #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_11 { +enum anon_1 { #[default] SECOND_A = 0, SECOND_B = 1, } -impl From for anon_enum_11 { - fn from(n: i32) -> anon_enum_11 { +impl From for anon_1 { + fn from(n: i32) -> anon_1 { match n { - 0 => anon_enum_11::SECOND_A, - 1 => anon_enum_11::SECOND_B, - _ => panic!("invalid anon_enum_11 value: {}", n), + 0 => anon_1::SECOND_A, + 1 => anon_1::SECOND_B, + _ => panic!("invalid anon_1 value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(anon_enum_11); +libcc2rs::impl_enum_inc_dec!(anon_1); #[repr(C)] #[derive(Copy, Clone, Default)] pub struct S { pub a: i32, } #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum TdEnum_enum { +enum TdEnum { #[default] TD_A = 0, TD_B = 1, } -impl From for TdEnum_enum { - fn from(n: i32) -> TdEnum_enum { +impl From for TdEnum { + fn from(n: i32) -> TdEnum { match n { - 0 => TdEnum_enum::TD_A, - 1 => TdEnum_enum::TD_B, - _ => panic!("invalid TdEnum_enum value: {}", n), + 0 => TdEnum::TD_A, + 1 => TdEnum::TD_B, + _ => panic!("invalid TdEnum value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(TdEnum_enum); +libcc2rs::impl_enum_inc_dec!(TdEnum); #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_24 { +enum anon_2 { #[default] FIELD_A = 0, FIELD_B = 1, } -impl From for anon_enum_24 { - fn from(n: i32) -> anon_enum_24 { +impl From for anon_2 { + fn from(n: i32) -> anon_2 { match n { - 0 => anon_enum_24::FIELD_A, - 1 => anon_enum_24::FIELD_B, - _ => panic!("invalid anon_enum_24 value: {}", n), + 0 => anon_2::FIELD_A, + 1 => anon_2::FIELD_B, + _ => panic!("invalid anon_2 value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(anon_enum_24); +libcc2rs::impl_enum_inc_dec!(anon_2); #[repr(C)] #[derive(Copy, Clone, Default)] pub struct WithAnonField { pub a: i32, - pub field: anon_enum_24, + pub field: anon_2, } pub fn main() { unsafe { @@ -88,32 +88,32 @@ pub fn main() { } unsafe fn main_0() -> i32 { #[derive(Clone, Copy, PartialEq, Debug, Default)] - enum anon_enum_31 { + enum anon_3 { #[default] THIRD_A = 0, THIRD_B = 1, } - impl From for anon_enum_31 { - fn from(n: i32) -> anon_enum_31 { + impl From for anon_3 { + fn from(n: i32) -> anon_3 { match n { - 0 => anon_enum_31::THIRD_A, - 1 => anon_enum_31::THIRD_B, - _ => panic!("invalid anon_enum_31 value: {}", n), + 0 => anon_3::THIRD_A, + 1 => anon_3::THIRD_B, + _ => panic!("invalid anon_3 value: {}", n), } } } - libcc2rs::impl_enum_inc_dec!(anon_enum_31); - assert!(((((anon_enum_3::FIRST_A as i32) != (anon_enum_3::FIRST_B as i32)) as i32) != 0)); - assert!(((((anon_enum_11::SECOND_A as i32) != (anon_enum_11::SECOND_B as i32)) as i32) != 0)); - assert!(((((anon_enum_31::THIRD_A as i32) != (anon_enum_31::THIRD_B as i32)) as i32) != 0)); - let mut td: TdEnum_enum = TdEnum_enum::TD_A; - assert!(((((td as u32) == ((TdEnum_enum::TD_A as i32) as u32)) as i32) != 0)); - td = (TdEnum_enum::TD_B).clone(); - assert!(((((td as u32) == ((TdEnum_enum::TD_B as i32) as u32)) as i32) != 0)); + libcc2rs::impl_enum_inc_dec!(anon_3); + assert!(((((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32)) as i32) != 0)); + assert!(((((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32)) as i32) != 0)); + assert!(((((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32)) as i32) != 0)); + let mut td: TdEnum = TdEnum::TD_A; + assert!(((((td as u32) == ((TdEnum::TD_A as i32) as u32)) as i32) != 0)); + td = (TdEnum::TD_B).clone(); + assert!(((((td as u32) == ((TdEnum::TD_B as i32) as u32)) as i32) != 0)); let mut w: WithAnonField = ::default(); - w.field = anon_enum_24::FIELD_A; - assert!(((((w.field as u32) == ((anon_enum_24::FIELD_A as i32) as u32)) as i32) != 0)); - w.field = (anon_enum_24::FIELD_B).clone(); - assert!(((((w.field as u32) == ((anon_enum_24::FIELD_B as i32) as u32)) as i32) != 0)); + w.field = anon_2::FIELD_A; + assert!(((((w.field as u32) == ((anon_2::FIELD_A as i32) as u32)) as i32) != 0)); + w.field = (anon_2::FIELD_B).clone(); + assert!(((((w.field as u32) == ((anon_2::FIELD_B as i32) as u32)) as i32) != 0)); return 0; } From 2a100c1b5b0ddb988c9fb89793a74998a3ff1800 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 3 Jun 2026 15:21:49 +0100 Subject: [PATCH 3/4] Update tests --- tests/unit/out/refcount/anonymous_enum_c.rs | 22 ++++++++++----------- tests/unit/out/unsafe/anonymous_enum_c.rs | 22 ++++++++++----------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/unit/out/refcount/anonymous_enum_c.rs b/tests/unit/out/refcount/anonymous_enum_c.rs index c1032796..772ea6e5 100644 --- a/tests/unit/out/refcount/anonymous_enum_c.rs +++ b/tests/unit/out/refcount/anonymous_enum_c.rs @@ -53,21 +53,21 @@ impl ByteRepr for S { } } #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum TdEnum { +enum TdEnum_enum { #[default] TD_A = 0, TD_B = 1, } -impl From for TdEnum { - fn from(n: i32) -> TdEnum { +impl From for TdEnum_enum { + fn from(n: i32) -> TdEnum_enum { match n { - 0 => TdEnum::TD_A, - 1 => TdEnum::TD_B, - _ => panic!("invalid TdEnum value: {}", n), + 0 => TdEnum_enum::TD_A, + 1 => TdEnum_enum::TD_B, + _ => panic!("invalid TdEnum_enum value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(TdEnum); +libcc2rs::impl_enum_inc_dec!(TdEnum_enum); #[derive(Clone, Copy, PartialEq, Debug, Default)] enum anon_2 { #[default] @@ -113,10 +113,10 @@ fn main_0() -> i32 { assert!(((((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32)) as i32) != 0)); assert!(((((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32)) as i32) != 0)); assert!(((((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32)) as i32) != 0)); - let td: Value = Rc::new(RefCell::new(TdEnum::TD_A)); - assert!((((((*td.borrow()) as u32) == ((TdEnum::TD_A as i32) as u32)) as i32) != 0)); - (*td.borrow_mut()) = TdEnum::TD_B; - assert!((((((*td.borrow()) as u32) == ((TdEnum::TD_B as i32) as u32)) as i32) != 0)); + let td: Value = Rc::new(RefCell::new(TdEnum_enum::TD_A)); + assert!((((((*td.borrow()) as u32) == ((TdEnum_enum::TD_A as i32) as u32)) as i32) != 0)); + (*td.borrow_mut()) = TdEnum_enum::TD_B; + assert!((((((*td.borrow()) as u32) == ((TdEnum_enum::TD_B as i32) as u32)) as i32) != 0)); let w: Value = >::default(); (*(*w.borrow()).field.borrow_mut()) = anon_2::FIELD_A; assert!( diff --git a/tests/unit/out/unsafe/anonymous_enum_c.rs b/tests/unit/out/unsafe/anonymous_enum_c.rs index c0d9f4e8..8bdf3f73 100644 --- a/tests/unit/out/unsafe/anonymous_enum_c.rs +++ b/tests/unit/out/unsafe/anonymous_enum_c.rs @@ -44,21 +44,21 @@ pub struct S { pub a: i32, } #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum TdEnum { +enum TdEnum_enum { #[default] TD_A = 0, TD_B = 1, } -impl From for TdEnum { - fn from(n: i32) -> TdEnum { +impl From for TdEnum_enum { + fn from(n: i32) -> TdEnum_enum { match n { - 0 => TdEnum::TD_A, - 1 => TdEnum::TD_B, - _ => panic!("invalid TdEnum value: {}", n), + 0 => TdEnum_enum::TD_A, + 1 => TdEnum_enum::TD_B, + _ => panic!("invalid TdEnum_enum value: {}", n), } } } -libcc2rs::impl_enum_inc_dec!(TdEnum); +libcc2rs::impl_enum_inc_dec!(TdEnum_enum); #[derive(Clone, Copy, PartialEq, Debug, Default)] enum anon_2 { #[default] @@ -106,10 +106,10 @@ unsafe fn main_0() -> i32 { assert!(((((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32)) as i32) != 0)); assert!(((((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32)) as i32) != 0)); assert!(((((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32)) as i32) != 0)); - let mut td: TdEnum = TdEnum::TD_A; - assert!(((((td as u32) == ((TdEnum::TD_A as i32) as u32)) as i32) != 0)); - td = (TdEnum::TD_B).clone(); - assert!(((((td as u32) == ((TdEnum::TD_B as i32) as u32)) as i32) != 0)); + let mut td: TdEnum_enum = TdEnum_enum::TD_A; + assert!(((((td as u32) == ((TdEnum_enum::TD_A as i32) as u32)) as i32) != 0)); + td = (TdEnum_enum::TD_B).clone(); + assert!(((((td as u32) == ((TdEnum_enum::TD_B as i32) as u32)) as i32) != 0)); let mut w: WithAnonField = ::default(); w.field = anon_2::FIELD_A; assert!(((((w.field as u32) == ((anon_2::FIELD_A as i32) as u32)) as i32) != 0)); From 031b4ffbd8105ec7d97a21966436606289300c98 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 3 Jun 2026 15:23:48 +0100 Subject: [PATCH 4/4] Update tests --- .../refcount/cross_tu_anon_enum_collision.rs | 54 ++++++++++++++++++ .../unsafe/cross_tu_anon_enum_collision.rs | 56 +++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 tests/multi-file/cross_tu_anon_enum_collision/out/refcount/cross_tu_anon_enum_collision.rs create mode 100644 tests/multi-file/cross_tu_anon_enum_collision/out/unsafe/cross_tu_anon_enum_collision.rs diff --git a/tests/multi-file/cross_tu_anon_enum_collision/out/refcount/cross_tu_anon_enum_collision.rs b/tests/multi-file/cross_tu_anon_enum_collision/out/refcount/cross_tu_anon_enum_collision.rs new file mode 100644 index 00000000..c7edae33 --- /dev/null +++ b/tests/multi-file/cross_tu_anon_enum_collision/out/refcount/cross_tu_anon_enum_collision.rs @@ -0,0 +1,54 @@ +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 anon_0 { + #[default] + ALPHA = 7, +} +impl From for anon_0 { + fn from(n: i32) -> anon_0 { + match n { + 7 => anon_0::ALPHA, + _ => panic!("invalid anon_0 value: {}", n), + } + } +} +libcc2rs::impl_enum_inc_dec!(anon_0); +pub fn a_value_1() -> i32 { + let x: Value = Rc::new(RefCell::new(0)); + (*x.borrow_mut()) |= (anon_0::ALPHA as i32); + return (*x.borrow()); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + assert!((((({ a_value_1() }) == 7) as i32) != 0)); + assert!((((({ b_value_2() }) == 9) as i32) != 0)); + return 0; +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_3 { + #[default] + BETA = 9, +} +impl From for anon_3 { + fn from(n: i32) -> anon_3 { + match n { + 9 => anon_3::BETA, + _ => panic!("invalid anon_3 value: {}", n), + } + } +} +libcc2rs::impl_enum_inc_dec!(anon_3); +pub fn b_value_2() -> i32 { + let x: Value = Rc::new(RefCell::new(0)); + (*x.borrow_mut()) |= (anon_3::BETA as i32); + return (*x.borrow()); +} diff --git a/tests/multi-file/cross_tu_anon_enum_collision/out/unsafe/cross_tu_anon_enum_collision.rs b/tests/multi-file/cross_tu_anon_enum_collision/out/unsafe/cross_tu_anon_enum_collision.rs new file mode 100644 index 00000000..3bcc3f17 --- /dev/null +++ b/tests/multi-file/cross_tu_anon_enum_collision/out/unsafe/cross_tu_anon_enum_collision.rs @@ -0,0 +1,56 @@ +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 anon_0 { + #[default] + ALPHA = 7, +} +impl From for anon_0 { + fn from(n: i32) -> anon_0 { + match n { + 7 => anon_0::ALPHA, + _ => panic!("invalid anon_0 value: {}", n), + } + } +} +libcc2rs::impl_enum_inc_dec!(anon_0); +pub unsafe fn a_value_1() -> i32 { + let mut x: i32 = 0; + x |= (anon_0::ALPHA as i32); + return x; +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + assert!(((((unsafe { a_value_1() }) == (7)) as i32) != 0)); + assert!(((((unsafe { b_value_2() }) == (9)) as i32) != 0)); + return 0; +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_3 { + #[default] + BETA = 9, +} +impl From for anon_3 { + fn from(n: i32) -> anon_3 { + match n { + 9 => anon_3::BETA, + _ => panic!("invalid anon_3 value: {}", n), + } + } +} +libcc2rs::impl_enum_inc_dec!(anon_3); +pub unsafe fn b_value_2() -> i32 { + let mut x: i32 = 0; + x |= (anon_3::BETA as i32); + return x; +}