From 1725429cc0da611461574470dccc0b7e236d19fe Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 30 Apr 2026 11:14:03 +0100 Subject: [PATCH] Handle typedef'ed anonymous structs --- cpp2rust/converter/mapper.cpp | 3 + .../unit/out/refcount/typedef-anon-struct.rs | 69 +++++++++++++++++++ tests/unit/out/unsafe/typedef-anon-struct.rs | 38 ++++++++++ tests/unit/typedef-anon-struct.cpp | 26 +++++++ 4 files changed, 136 insertions(+) create mode 100644 tests/unit/out/refcount/typedef-anon-struct.rs create mode 100644 tests/unit/out/unsafe/typedef-anon-struct.rs create mode 100644 tests/unit/typedef-anon-struct.cpp diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index 45d88bae..1887fa10 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -733,6 +733,9 @@ std::string ToString(clang::QualType qual_type) { std::string ToString(const clang::NamedDecl *decl) { if (auto *record = clang::dyn_cast(decl); record && !record->getIdentifier()) { + if (auto *typedef_decl = record->getTypedefNameForAnonDecl()) { + return ToString(clang::cast(typedef_decl)); + } return synthesizeAnonRecordName(record); } diff --git a/tests/unit/out/refcount/typedef-anon-struct.rs b/tests/unit/out/refcount/typedef-anon-struct.rs new file mode 100644 index 00000000..c8faa988 --- /dev/null +++ b/tests/unit/out/refcount/typedef-anon-struct.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(Default)] +pub struct Outer_RunInfo { + pub block_idx: Value, + pub num_extra_zero_runs: Value, +} +impl Clone for Outer_RunInfo { + fn clone(&self) -> Self { + let mut this = Self { + block_idx: Rc::new(RefCell::new((*self.block_idx.borrow()))), + num_extra_zero_runs: Rc::new(RefCell::new((*self.num_extra_zero_runs.borrow()))), + }; + this + } +} +impl ByteRepr for Outer_RunInfo {} +#[derive(Default)] +pub struct Outer { + pub runs: Value>, +} +impl Clone for Outer { + fn clone(&self) -> Self { + let mut this = Self { + runs: Rc::new(RefCell::new((*self.runs.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(::default())); + let info: Value = Rc::new(RefCell::new(::default())); + (*(*info.borrow()).block_idx.borrow_mut()) = 1; + (*(*info.borrow()).num_extra_zero_runs.borrow_mut()) = 2; + { + let a0_clone = (*info.borrow()).clone(); + (*(*o.borrow()).runs.borrow_mut()).push(a0_clone) + }; + assert!(((*(*o.borrow()).runs.borrow()).len() as u64 == 1_u64)); + assert!( + ((*(*((*o.borrow()).runs.as_pointer() as Ptr) + .offset(0_u64 as isize) + .upgrade() + .deref()) + .block_idx + .borrow()) + == 1) + ); + assert!( + ((*(*((*o.borrow()).runs.as_pointer() as Ptr) + .offset(0_u64 as isize) + .upgrade() + .deref()) + .num_extra_zero_runs + .borrow()) + == 2) + ); + return 0; +} diff --git a/tests/unit/out/unsafe/typedef-anon-struct.rs b/tests/unit/out/unsafe/typedef-anon-struct.rs new file mode 100644 index 00000000..ef989073 --- /dev/null +++ b/tests/unit/out/unsafe/typedef-anon-struct.rs @@ -0,0 +1,38 @@ +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; +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct Outer_RunInfo { + pub block_idx: i32, + pub num_extra_zero_runs: i32, +} +#[repr(C)] +#[derive(Clone, Default)] +pub struct Outer { + pub runs: Vec, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut o: Outer = ::default(); + let mut info: Outer_RunInfo = ::default(); + info.block_idx = 1; + info.num_extra_zero_runs = 2; + { + let a0_clone = info.clone(); + o.runs.push(a0_clone) + }; + assert!(((o.runs.len() as u64) == (1_u64))); + assert!(((o.runs[(0_u64) as usize].block_idx) == (1))); + assert!(((o.runs[(0_u64) as usize].num_extra_zero_runs) == (2))); + return 0; +} diff --git a/tests/unit/typedef-anon-struct.cpp b/tests/unit/typedef-anon-struct.cpp new file mode 100644 index 00000000..3bec9fe4 --- /dev/null +++ b/tests/unit/typedef-anon-struct.cpp @@ -0,0 +1,26 @@ +#include +#include + +struct Outer { + typedef struct { + int block_idx; + int num_extra_zero_runs; + } RunInfo; + + std::vector runs; +}; + +int main() { + Outer o; + + Outer::RunInfo info; + info.block_idx = 1; + info.num_extra_zero_runs = 2; + o.runs.push_back(info); + + assert(o.runs.size() == 1); + assert(o.runs[0].block_idx == 1); + assert(o.runs[0].num_extra_zero_runs == 2); + + return 0; +}