From 270f97f89ce148631329f68a473d92d28e185e99 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 22 May 2026 13:34:50 +0100 Subject: [PATCH 1/3] Translate socket functions in C mode --- cpp2rust/converter/converter.cpp | 12 ++++++++ cpp2rust/converter/converter.h | 2 ++ rules/socket/{src.cpp => src.c} | 1 + .../out/unsafe/socket_transparent_union.rs | 28 +++++++++++++++++++ tests/unit/socket_transparent_union.c | 15 ++++++++++ 5 files changed, 58 insertions(+) rename rules/socket/{src.cpp => src.c} (98%) create mode 100644 tests/unit/out/unsafe/socket_transparent_union.rs create mode 100644 tests/unit/socket_transparent_union.c diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 976255a..258d0a2 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -2621,6 +2621,18 @@ bool Converter::VisitInitListExpr(clang::InitListExpr *expr) { return false; } +bool Converter::VisitCompoundLiteralExpr(clang::CompoundLiteralExpr *expr) { + auto record = expr->getType()->getAsRecordDecl(); + if (!record || !record->hasAttr()) { + return true; + } + auto init = clang::cast(expr->getInitializer()); + assert(init->getNumInits() == 1); + PushExprKind push(*this, ExprKind::RValue); + Convert(init->getInit(0)); + return false; +} + bool Converter::VisitArraySubscriptExpr(clang::ArraySubscriptExpr *expr) { auto *base = expr->getBase(); if (base->IgnoreCasts()->getType()->isPointerType()) { diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index 0710538..9baa504 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -283,6 +283,8 @@ class Converter : public clang::RecursiveASTVisitor { virtual bool VisitInitListExpr(clang::InitListExpr *expr); + virtual bool VisitCompoundLiteralExpr(clang::CompoundLiteralExpr *expr); + virtual bool VisitArraySubscriptExpr(clang::ArraySubscriptExpr *expr); virtual bool VisitCXXNullPtrLiteralExpr(clang::CXXNullPtrLiteralExpr *expr); diff --git a/rules/socket/src.cpp b/rules/socket/src.c similarity index 98% rename from rules/socket/src.cpp rename to rules/socket/src.c index f965435..9be2c1c 100644 --- a/rules/socket/src.cpp +++ b/rules/socket/src.c @@ -1,3 +1,4 @@ +#define _GNU_SOURCE #include #include diff --git a/tests/unit/out/unsafe/socket_transparent_union.rs b/tests/unit/out/unsafe/socket_transparent_union.rs new file mode 100644 index 0000000..aa49a44 --- /dev/null +++ b/tests/unit/out/unsafe/socket_transparent_union.rs @@ -0,0 +1,28 @@ +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 fd: i32 = 0; + let mut ssloc: sockaddr_storage = std::mem::zeroed::(); + let mut slen: u32 = (::std::mem::size_of::() as u64 as u32); + assert!( + ((((libc::getsockname( + fd, + ((&mut ssloc as *mut sockaddr_storage) as *mut sockaddr), + (&mut slen as *mut u32) + )) == (-1_i32)) as i32) + != 0) + ); + assert!(((((*libcc2rs::cpp2rust_errno()) == (88)) as i32) != 0)); + return 0; +} diff --git a/tests/unit/socket_transparent_union.c b/tests/unit/socket_transparent_union.c new file mode 100644 index 0000000..f3721f9 --- /dev/null +++ b/tests/unit/socket_transparent_union.c @@ -0,0 +1,15 @@ +// no-compile: refcount +#define _GNU_SOURCE +#include +#include +#include +#include + +int main(void) { + int fd = 0; + struct sockaddr_storage ssloc; + socklen_t slen = sizeof(ssloc); + assert(getsockname(fd, (struct sockaddr *)&ssloc, &slen) == -1); + assert(errno == ENOTSOCK); + return 0; +} From 5a596af94044668c519f4dbc81e6742c484bdf76 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 22 May 2026 13:53:24 +0100 Subject: [PATCH 2/3] Add sockaddr_in -> sockaddr cast --- tests/unit/out/unsafe/socket_transparent_union.rs | 12 ++++++++++++ tests/unit/socket_transparent_union.c | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/tests/unit/out/unsafe/socket_transparent_union.rs b/tests/unit/out/unsafe/socket_transparent_union.rs index aa49a44..41eb4a3 100644 --- a/tests/unit/out/unsafe/socket_transparent_union.rs +++ b/tests/unit/out/unsafe/socket_transparent_union.rs @@ -24,5 +24,17 @@ unsafe fn main_0() -> i32 { != 0) ); assert!(((((*libcc2rs::cpp2rust_errno()) == (88)) as i32) != 0)); + let mut sin: sockaddr_in = std::mem::zeroed::(); + let mut inlen: u32 = (::std::mem::size_of::() as u64 as u32); + (*libcc2rs::cpp2rust_errno()) = 0; + assert!( + ((((libc::getsockname( + fd, + ((&mut sin as *mut sockaddr_in) as *mut sockaddr), + (&mut inlen as *mut u32) + )) == (-1_i32)) as i32) + != 0) + ); + assert!(((((*libcc2rs::cpp2rust_errno()) == (88)) as i32) != 0)); return 0; } diff --git a/tests/unit/socket_transparent_union.c b/tests/unit/socket_transparent_union.c index f3721f9..0bd1843 100644 --- a/tests/unit/socket_transparent_union.c +++ b/tests/unit/socket_transparent_union.c @@ -2,14 +2,23 @@ #define _GNU_SOURCE #include #include +#include #include #include int main(void) { int fd = 0; + struct sockaddr_storage ssloc; socklen_t slen = sizeof(ssloc); assert(getsockname(fd, (struct sockaddr *)&ssloc, &slen) == -1); assert(errno == ENOTSOCK); + + struct sockaddr_in sin; + socklen_t inlen = sizeof(sin); + errno = 0; + assert(getsockname(fd, (struct sockaddr *)&sin, &inlen) == -1); + assert(errno == ENOTSOCK); + return 0; } From 3f8780b42b351dcd8be69c00e6149eed9fe651ef Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 22 May 2026 14:28:30 +0100 Subject: [PATCH 3/3] Delete unportable errno check --- tests/unit/out/unsafe/socket_transparent_union.rs | 3 --- tests/unit/socket_transparent_union.c | 4 ---- 2 files changed, 7 deletions(-) diff --git a/tests/unit/out/unsafe/socket_transparent_union.rs b/tests/unit/out/unsafe/socket_transparent_union.rs index 41eb4a3..a4bddaa 100644 --- a/tests/unit/out/unsafe/socket_transparent_union.rs +++ b/tests/unit/out/unsafe/socket_transparent_union.rs @@ -23,10 +23,8 @@ unsafe fn main_0() -> i32 { )) == (-1_i32)) as i32) != 0) ); - assert!(((((*libcc2rs::cpp2rust_errno()) == (88)) as i32) != 0)); let mut sin: sockaddr_in = std::mem::zeroed::(); let mut inlen: u32 = (::std::mem::size_of::() as u64 as u32); - (*libcc2rs::cpp2rust_errno()) = 0; assert!( ((((libc::getsockname( fd, @@ -35,6 +33,5 @@ unsafe fn main_0() -> i32 { )) == (-1_i32)) as i32) != 0) ); - assert!(((((*libcc2rs::cpp2rust_errno()) == (88)) as i32) != 0)); return 0; } diff --git a/tests/unit/socket_transparent_union.c b/tests/unit/socket_transparent_union.c index 0bd1843..7ee4b86 100644 --- a/tests/unit/socket_transparent_union.c +++ b/tests/unit/socket_transparent_union.c @@ -1,7 +1,6 @@ // no-compile: refcount #define _GNU_SOURCE #include -#include #include #include #include @@ -12,13 +11,10 @@ int main(void) { struct sockaddr_storage ssloc; socklen_t slen = sizeof(ssloc); assert(getsockname(fd, (struct sockaddr *)&ssloc, &slen) == -1); - assert(errno == ENOTSOCK); struct sockaddr_in sin; socklen_t inlen = sizeof(sin); - errno = 0; assert(getsockname(fd, (struct sockaddr *)&sin, &inlen) == -1); - assert(errno == ENOTSOCK); return 0; }