diff options
author | Daniel Xu <accounts@dxuuu.xyz> | 2021-05-11 10:46:27 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-11 17:46:27 +0200 |
commit | e6684dc5c56d0283b9c14b34f68d445e9d5a580f (patch) | |
tree | 024daaec5497f25d60fdc39f3efe1fd76ed0c397 /src/codegen/mod.rs | |
parent | 4116b701f5c86f4197824703d935283ca644c21b (diff) |
Zero out padding in custom Default trait implementations (#2051)
* Zero out padding in custom Default trait implementations
Previously, we were using `std::mem::zeroed()` which unfortunately does
not necessarily zero out padding. It'd be better if the padding is
zeroed out because some libraries are sensitive to non-zero'd out bytes,
especially when forward/backward compatability is involved.
This commit ensures all bytes are zeroed out in custom Default trait
implementations.
Diffstat (limited to 'src/codegen/mod.rs')
-rw-r--r-- | src/codegen/mod.rs | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 1a702b00..6f8a451a 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -2196,9 +2196,32 @@ impl CodeGenerator for CompInfo { if needs_default_impl { let prefix = ctx.trait_prefix(); + let body = if ctx.options().rust_features().maybe_uninit { + quote! { + let mut s = ::#prefix::mem::MaybeUninit::<Self>::uninit(); + unsafe { + ::#prefix::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } + } else { + quote! { + unsafe { + let mut s: Self = ::#prefix::mem::uninitialized(); + ::#prefix::ptr::write_bytes(&mut s, 0, 1); + s + } + } + }; + // Note we use `ptr::write_bytes()` instead of `mem::zeroed()` because the latter does + // not necessarily ensure padding bytes are zeroed. Some C libraries are sensitive to + // non-zero padding bytes, especially when forwards/backwards compatability is + // involved. result.push(quote! { impl #generics Default for #ty_for_impl { - fn default() -> Self { unsafe { ::#prefix::mem::zeroed() } } + fn default() -> Self { + #body + } } }); } |