Skip to content

Commit 63df8b2

Browse files
authored
[unsafe] Records that struct libc types do not derive Default (#151)
1 parent cb54669 commit 63df8b2

5 files changed

Lines changed: 40 additions & 9 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,14 @@ bool Converter::RecordDerivesDefault(const clang::RecordDecl *decl) {
579579
if (f->getType()->isArrayType()) {
580580
return false;
581581
}
582+
583+
// Records that contain libc types do not derive Default
584+
if (auto record = f->getType()->getAsRecordDecl()) {
585+
if (ctx_.getSourceManager().isInSystemHeader(record->getLocation()) &&
586+
f->getType().isPODType(ctx_)) {
587+
return false;
588+
}
589+
}
582590
}
583591

584592
return true;
@@ -3163,7 +3171,8 @@ std::string Converter::GetDefaultAsStringFallback(clang::QualType qual_type) {
31633171
if (auto record = qual_type->getAsRecordDecl()) {
31643172
if (ctx_.getSourceManager().isInSystemHeader(record->getLocation()) &&
31653173
qual_type.isPODType(ctx_)) {
3166-
return std::format("std::mem::zeroed::<{}>()", ToString(qual_type));
3174+
return std::format("unsafe {{ std::mem::zeroed::<{}>() }}",
3175+
ToString(qual_type));
31673176
}
31683177
}
31693178

tests/unit/libc_struct_without_default.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <assert.h>
44
#include <netinet/in.h>
55
#include <poll.h>
6+
#include <sys/socket.h>
67
#include <sys/stat.h>
78
#include <time.h>
89
#include <vector>
@@ -12,6 +13,10 @@ struct UserDefined {
1213
std::vector<int> v;
1314
};
1415

16+
struct FieldIsLibcType {
17+
struct sockaddr addr;
18+
};
19+
1520
int main() {
1621
struct pollfd p;
1722
p.fd = -1;
@@ -40,5 +45,8 @@ int main() {
4045
UserDefined ud;
4146
assert(ud.a[0] == 0);
4247
assert(ud.v.size() == 0);
48+
49+
FieldIsLibcType filt;
50+
assert(filt.addr.sa_family == 0);
4351
return 0;
4452
}

tests/unit/out/unsafe/libc_struct_without_default.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,48 @@ impl Default for UserDefined {
2020
}
2121
}
2222
}
23+
#[repr(C)]
24+
#[derive(Copy, Clone)]
25+
pub struct FieldIsLibcType {
26+
pub addr: sockaddr,
27+
}
28+
impl Default for FieldIsLibcType {
29+
fn default() -> Self {
30+
FieldIsLibcType {
31+
addr: unsafe { std::mem::zeroed::<sockaddr>() },
32+
}
33+
}
34+
}
2335
pub fn main() {
2436
unsafe {
2537
std::process::exit(main_0() as i32);
2638
}
2739
}
2840
unsafe fn main_0() -> i32 {
29-
let mut p: pollfd = std::mem::zeroed::<pollfd>();
41+
let mut p: pollfd = unsafe { std::mem::zeroed::<pollfd>() };
3042
p.fd = -1_i32;
3143
p.events = 0_i16;
3244
p.revents = 2_i16;
3345
assert!(((p.fd) == (-1_i32)));
3446
assert!(((p.events as i32) == (0)));
3547
assert!(((p.revents as i32) == (2)));
36-
let mut ia: in_addr = std::mem::zeroed::<in_addr>();
48+
let mut ia: in_addr = unsafe { std::mem::zeroed::<in_addr>() };
3749
ia.s_addr = 1_u32;
3850
assert!(((ia.s_addr) == (1_u32)));
39-
let mut t: tm = std::mem::zeroed::<tm>();
51+
let mut t: tm = unsafe { std::mem::zeroed::<tm>() };
4052
t.tm_year = 124;
4153
t.tm_mon = 5;
4254
t.tm_mday = 15;
4355
assert!(((t.tm_year) == (124)));
4456
assert!(((t.tm_mon) == (5)));
4557
assert!(((t.tm_mday) == (15)));
46-
let mut st: stat = std::mem::zeroed::<stat>();
58+
let mut st: stat = unsafe { std::mem::zeroed::<stat>() };
4759
st.st_size = 1024_i64;
4860
assert!(((st.st_size) == (1024_i64)));
4961
let mut ud: UserDefined = <UserDefined>::default();
5062
assert!(((ud.a[(0_u64) as usize]) == (0)));
5163
assert!(((ud.v.len() as u64) == (0_u64)));
64+
let mut filt: FieldIsLibcType = <FieldIsLibcType>::default();
65+
assert!(((filt.addr.sa_family as i32) == (0)));
5266
return 0;
5367
}

tests/unit/out/unsafe/socket_transparent_union.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub fn main() {
1313
}
1414
unsafe fn main_0() -> i32 {
1515
let mut fd: i32 = 0;
16-
let mut ssloc: sockaddr_storage = std::mem::zeroed::<sockaddr_storage>();
16+
let mut ssloc: sockaddr_storage = unsafe { std::mem::zeroed::<sockaddr_storage>() };
1717
let mut slen: u32 = (::std::mem::size_of::<sockaddr_storage>() as u64 as u32);
1818
assert!(
1919
((((libc::getsockname(
@@ -23,7 +23,7 @@ unsafe fn main_0() -> i32 {
2323
)) == (-1_i32)) as i32)
2424
!= 0)
2525
);
26-
let mut sin: sockaddr_in = std::mem::zeroed::<sockaddr_in>();
26+
let mut sin: sockaddr_in = unsafe { std::mem::zeroed::<sockaddr_in>() };
2727
let mut inlen: u32 = (::std::mem::size_of::<sockaddr_in>() as u64 as u32);
2828
assert!(
2929
((((libc::getsockname(

tests/unit/out/unsafe/sys_stat.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub unsafe fn test_stat_0() {
1818
fp,
1919
);
2020
assert!(((((libc::fclose(fp)) == (0)) as i32) != 0));
21-
let mut st: stat = std::mem::zeroed::<stat>();
21+
let mut st: stat = unsafe { std::mem::zeroed::<stat>() };
2222
assert!(((((libc::stat(path as *const i8, (&mut st as *mut stat))) == (0)) as i32) != 0));
2323
assert!(((((st.st_size) == (5_i64)) as i32) != 0));
2424
libc::unlink(path as *const i8);
@@ -36,7 +36,7 @@ pub unsafe fn test_fstat_1() {
3636
);
3737
libc::fflush(fp);
3838
let mut fd: i32 = libc::fileno(fp);
39-
let mut st: stat = std::mem::zeroed::<stat>();
39+
let mut st: stat = unsafe { std::mem::zeroed::<stat>() };
4040
assert!(((((libc::fstat(fd, (&mut st as *mut stat))) == (0)) as i32) != 0));
4141
assert!(((((st.st_size) == (11_i64)) as i32) != 0));
4242
assert!(((((libc::fclose(fp)) == (0)) as i32) != 0));

0 commit comments

Comments
 (0)