Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion cpp2rust/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,14 @@ bool Converter::RecordDerivesDefault(const clang::RecordDecl *decl) {
if (f->getType()->isArrayType()) {
return false;
}

// Records that contain libc types do not derive Default
if (auto record = f->getType()->getAsRecordDecl()) {
if (ctx_.getSourceManager().isInSystemHeader(record->getLocation()) &&
f->getType().isPODType(ctx_)) {
return false;
}
}
}

return true;
Expand Down Expand Up @@ -3162,7 +3170,8 @@ std::string Converter::GetDefaultAsStringFallback(clang::QualType qual_type) {
if (auto record = qual_type->getAsRecordDecl()) {
if (ctx_.getSourceManager().isInSystemHeader(record->getLocation()) &&
qual_type.isPODType(ctx_)) {
return std::format("std::mem::zeroed::<{}>()", ToString(qual_type));
return std::format("unsafe {{ std::mem::zeroed::<{}>() }}",
ToString(qual_type));
}
}

Expand Down
8 changes: 8 additions & 0 deletions tests/unit/libc_struct_without_default.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <assert.h>
#include <netinet/in.h>
#include <poll.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <time.h>
#include <vector>
Expand All @@ -12,6 +13,10 @@ struct UserDefined {
std::vector<int> v;
};

struct FieldIsLibcType {
struct sockaddr addr;
};

int main() {
struct pollfd p;
p.fd = -1;
Expand Down Expand Up @@ -40,5 +45,8 @@ int main() {
UserDefined ud;
assert(ud.a[0] == 0);
assert(ud.v.size() == 0);

FieldIsLibcType filt;
assert(filt.addr.sa_family == 0);
return 0;
}
22 changes: 18 additions & 4 deletions tests/unit/out/unsafe/libc_struct_without_default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,48 @@ impl Default for UserDefined {
}
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct FieldIsLibcType {
pub addr: sockaddr,
}
impl Default for FieldIsLibcType {
fn default() -> Self {
FieldIsLibcType {
addr: unsafe { std::mem::zeroed::<sockaddr>() },
}
}
}
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
}
}
unsafe fn main_0() -> i32 {
let mut p: pollfd = std::mem::zeroed::<pollfd>();
let mut p: pollfd = unsafe { std::mem::zeroed::<pollfd>() };
p.fd = -1_i32;
p.events = 0_i16;
p.revents = 2_i16;
assert!(((p.fd) == (-1_i32)));
assert!(((p.events as i32) == (0)));
assert!(((p.revents as i32) == (2)));
let mut ia: in_addr = std::mem::zeroed::<in_addr>();
let mut ia: in_addr = unsafe { std::mem::zeroed::<in_addr>() };
ia.s_addr = 1_u32;
assert!(((ia.s_addr) == (1_u32)));
let mut t: tm = std::mem::zeroed::<tm>();
let mut t: tm = unsafe { std::mem::zeroed::<tm>() };
t.tm_year = 124;
t.tm_mon = 5;
t.tm_mday = 15;
assert!(((t.tm_year) == (124)));
assert!(((t.tm_mon) == (5)));
assert!(((t.tm_mday) == (15)));
let mut st: stat = std::mem::zeroed::<stat>();
let mut st: stat = unsafe { std::mem::zeroed::<stat>() };
st.st_size = 1024_i64;
assert!(((st.st_size) == (1024_i64)));
let mut ud: UserDefined = <UserDefined>::default();
assert!(((ud.a[(0_u64) as usize]) == (0)));
assert!(((ud.v.len() as u64) == (0_u64)));
let mut filt: FieldIsLibcType = <FieldIsLibcType>::default();
assert!(((filt.addr.sa_family as i32) == (0)));
return 0;
}
4 changes: 2 additions & 2 deletions tests/unit/out/unsafe/socket_transparent_union.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub fn main() {
}
unsafe fn main_0() -> i32 {
let mut fd: i32 = 0;
let mut ssloc: sockaddr_storage = std::mem::zeroed::<sockaddr_storage>();
let mut ssloc: sockaddr_storage = unsafe { std::mem::zeroed::<sockaddr_storage>() };
let mut slen: u32 = (::std::mem::size_of::<sockaddr_storage>() as u64 as u32);
assert!(
((((libc::getsockname(
Expand All @@ -23,7 +23,7 @@ unsafe fn main_0() -> i32 {
)) == (-1_i32)) as i32)
!= 0)
);
let mut sin: sockaddr_in = std::mem::zeroed::<sockaddr_in>();
let mut sin: sockaddr_in = unsafe { std::mem::zeroed::<sockaddr_in>() };
let mut inlen: u32 = (::std::mem::size_of::<sockaddr_in>() as u64 as u32);
assert!(
((((libc::getsockname(
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/out/unsafe/sys_stat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub unsafe fn test_stat_0() {
fp,
);
assert!(((((libc::fclose(fp)) == (0)) as i32) != 0));
let mut st: stat = std::mem::zeroed::<stat>();
let mut st: stat = unsafe { std::mem::zeroed::<stat>() };
assert!(((((libc::stat(path as *const i8, (&mut st as *mut stat))) == (0)) as i32) != 0));
assert!(((((st.st_size) == (5_i64)) as i32) != 0));
libc::unlink(path as *const i8);
Expand All @@ -36,7 +36,7 @@ pub unsafe fn test_fstat_1() {
);
libc::fflush(fp);
let mut fd: i32 = libc::fileno(fp);
let mut st: stat = std::mem::zeroed::<stat>();
let mut st: stat = unsafe { std::mem::zeroed::<stat>() };
assert!(((((libc::fstat(fd, (&mut st as *mut stat))) == (0)) as i32) != 0));
assert!(((((st.st_size) == (11_i64)) as i32) != 0));
assert!(((((libc::fclose(fp)) == (0)) as i32) != 0));
Expand Down
Loading