Skip to content

Commit f120aeb

Browse files
authored
Only emit mem::zeroed() on POD types (#105)
The previous check, i.e. `ctx_.getSourceManager().isInSystemHeader(record->getLocation())`, was too permissive and also matched against types such as `std::vector` which are not POD and cannot be initialized using `std::mem::zeroed()`
1 parent fcd50c6 commit f120aeb

3 files changed

Lines changed: 38 additions & 9 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3092,7 +3092,8 @@ std::string Converter::GetDefaultAsStringFallback(clang::QualType qual_type) {
30923092
}
30933093

30943094
if (auto record = qual_type->getAsRecordDecl()) {
3095-
if (ctx_.getSourceManager().isInSystemHeader(record->getLocation())) {
3095+
if (ctx_.getSourceManager().isInSystemHeader(record->getLocation()) &&
3096+
qual_type.isPODType(ctx_)) {
30963097
return std::format("std::mem::zeroed::<{}>()", ToString(qual_type));
30973098
}
30983099
}

tests/unit/libc_struct_without_default.c renamed to tests/unit/libc_struct_without_default.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
// no-compile: refcount
2+
#include <array>
23
#include <assert.h>
34
#include <netinet/in.h>
45
#include <poll.h>
56
#include <sys/stat.h>
67
#include <time.h>
8+
#include <vector>
9+
10+
struct UserDefined {
11+
std::array<int, 1> a;
12+
std::vector<int> v;
13+
};
714

815
int main() {
916
struct pollfd p;
@@ -29,5 +36,9 @@ int main() {
2936
struct stat st;
3037
st.st_size = 1024;
3138
assert(st.st_size == 1024);
39+
40+
UserDefined ud;
41+
assert(ud.a[0] == 0);
42+
assert(ud.v.size() == 0);
3243
return 0;
3344
}

tests/unit/out/unsafe/libc_struct_without_default.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,20 @@ use std::collections::BTreeMap;
66
use std::io::{Read, Seek, Write};
77
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
88
use std::rc::Rc;
9+
#[repr(C)]
10+
#[derive(Clone)]
11+
pub struct UserDefined {
12+
pub a: Vec<i32>,
13+
pub v: Vec<i32>,
14+
}
15+
impl Default for UserDefined {
16+
fn default() -> Self {
17+
UserDefined {
18+
a: std::array::from_fn::<_, 1, _>(|_| Default::default()).to_vec(),
19+
v: <Vec<i32>>::default(),
20+
}
21+
}
22+
}
923
pub fn main() {
1024
unsafe {
1125
std::process::exit(main_0() as i32);
@@ -16,21 +30,24 @@ unsafe fn main_0() -> i32 {
1630
p.fd = -1_i32;
1731
p.events = 0_i16;
1832
p.revents = 2_i16;
19-
assert!(((((p.fd) == (-1_i32)) as i32) != 0));
20-
assert!(((((p.events as i32) == (0)) as i32) != 0));
21-
assert!(((((p.revents as i32) == (2)) as i32) != 0));
33+
assert!(((p.fd) == (-1_i32)));
34+
assert!(((p.events as i32) == (0)));
35+
assert!(((p.revents as i32) == (2)));
2236
let mut ia: in_addr = std::mem::zeroed::<in_addr>();
2337
ia.s_addr = 1_u32;
24-
assert!(((((ia.s_addr) == (1_u32)) as i32) != 0));
38+
assert!(((ia.s_addr) == (1_u32)));
2539
let mut t: tm = std::mem::zeroed::<tm>();
2640
t.tm_year = 124;
2741
t.tm_mon = 5;
2842
t.tm_mday = 15;
29-
assert!(((((t.tm_year) == (124)) as i32) != 0));
30-
assert!(((((t.tm_mon) == (5)) as i32) != 0));
31-
assert!(((((t.tm_mday) == (15)) as i32) != 0));
43+
assert!(((t.tm_year) == (124)));
44+
assert!(((t.tm_mon) == (5)));
45+
assert!(((t.tm_mday) == (15)));
3246
let mut st: stat = std::mem::zeroed::<stat>();
3347
st.st_size = 1024_i64;
34-
assert!(((((st.st_size) == (1024_i64)) as i32) != 0));
48+
assert!(((st.st_size) == (1024_i64)));
49+
let mut ud: UserDefined = <UserDefined>::default();
50+
assert!(((ud.a[(0_u64) as usize]) == (0)));
51+
assert!(((ud.v.len() as u64) == (0_u64)));
3552
return 0;
3653
}

0 commit comments

Comments
 (0)