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..a4bddaa --- /dev/null +++ b/tests/unit/out/unsafe/socket_transparent_union.rs @@ -0,0 +1,37 @@ +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) + ); + let mut sin: sockaddr_in = std::mem::zeroed::(); + let mut inlen: u32 = (::std::mem::size_of::() as u64 as u32); + assert!( + ((((libc::getsockname( + fd, + ((&mut sin as *mut sockaddr_in) as *mut sockaddr), + (&mut inlen as *mut u32) + )) == (-1_i32)) 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..7ee4b86 --- /dev/null +++ b/tests/unit/socket_transparent_union.c @@ -0,0 +1,20 @@ +// 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); + + struct sockaddr_in sin; + socklen_t inlen = sizeof(sin); + assert(getsockname(fd, (struct sockaddr *)&sin, &inlen) == -1); + + return 0; +}