1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/// Observe the referenced data and prevent the compiler from removing previous writes to it.
///
/// This function acts like [`core::hint::black_box`] but takes a reference and
/// does not return the passed value.
///
/// It's implemented using the [`core::arch::asm!`] macro on target arches where `asm!` is stable,
/// i.e. `aarch64`, `arm`, `arm64ec`, `loongarch64`, `riscv32`, `riscv64`, `s390x`, `x86`, and
/// `x86_64`.
///
/// On all other targets it's implemented using [`core::hint::black_box`] and custom `black_box`
/// implemented using `#[inline(never)]` and `read_volatile`.
///
/// # Examples
/// ```
/// use core::num::NonZeroU32;
/// use zeroize::{ZeroizeOnDrop, zeroize_flat_type};
///
/// # type ThirdPartyType = u32;
///
/// struct DataToZeroize {
/// buf: [u8; 32],
/// // `ThirdPartyType` can be a type with private fields
/// // defined in a third-party crate and which does not implement
/// // `Zeroize` or zeroization on drop.
/// data: ThirdPartyType,
/// pos: NonZeroU32,
/// }
///
/// struct SomeMoreFlatData(u64);
///
/// impl Drop for DataToZeroize {
/// fn drop(&mut self) {
/// self.buf = [0u8; 32];
/// self.data = ThirdPartyType::default();
/// self.pos = NonZeroU32::new(32).unwrap();
/// zeroize::optimization_barrier(self);
/// }
/// }
///
/// impl zeroize::ZeroizeOnDrop for DataToZeroize {}
///
/// let mut data = DataToZeroize {
/// buf: [3u8; 32],
/// data: ThirdPartyType::default(),
/// pos: NonZeroU32::new(32).unwrap(),
/// };
///
/// // data gets zeroized when dropped
/// ```
///
/// Note that erasure of `ThirdPartyType` demonstrated above can be fragile if it contains
/// `MaybeUninit` or `union` data. It also does not perform erasure of types like `Box` or `Vec`.
Sized>