xref: /openbmc/qemu/rust/qemu-api/src/zeroable.rs (revision 7d87775f)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 use std::ptr;
4 
5 /// Encapsulates the requirement that
6 /// `MaybeUninit::<Self>::zeroed().assume_init()` does not cause undefined
7 /// behavior.  This trait in principle could be implemented as just:
8 ///
9 /// ```
10 ///     const ZERO: Self = unsafe {
11 ///         ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init()
12 ///     },
13 /// ```
14 ///
15 /// The need for a manual implementation is only because `zeroed()` cannot
16 /// be used as a `const fn` prior to Rust 1.75.0. Once we can assume a new
17 /// enough version of the compiler, we could provide a `#[derive(Zeroable)]`
18 /// macro to check at compile-time that all struct fields are Zeroable, and
19 /// use the above blanket implementation of the `ZERO` constant.
20 ///
21 /// # Safety
22 ///
23 /// Because the implementation of `ZERO` is manual, it does not make
24 /// any assumption on the safety of `zeroed()`.  However, other users of the
25 /// trait could use it that way.  Do not add this trait to a type unless
26 /// all-zeroes is a valid value for the type.  In particular, remember that
27 /// raw pointers can be zero, but references and `NonNull<T>` cannot
28 pub unsafe trait Zeroable: Default {
29     const ZERO: Self;
30 }
31 
32 unsafe impl Zeroable for crate::bindings::Property__bindgen_ty_1 {
33     const ZERO: Self = Self { i: 0 };
34 }
35 
36 unsafe impl Zeroable for crate::bindings::Property {
37     const ZERO: Self = Self {
38         name: ptr::null(),
39         info: ptr::null(),
40         offset: 0,
41         bitnr: 0,
42         bitmask: 0,
43         set_default: false,
44         defval: Zeroable::ZERO,
45         arrayoffset: 0,
46         arrayinfo: ptr::null(),
47         arrayfieldsize: 0,
48         link_type: ptr::null(),
49     };
50 }
51 
52 unsafe impl Zeroable for crate::bindings::VMStateDescription {
53     const ZERO: Self = Self {
54         name: ptr::null(),
55         unmigratable: false,
56         early_setup: false,
57         version_id: 0,
58         minimum_version_id: 0,
59         priority: crate::bindings::MigrationPriority::MIG_PRI_DEFAULT,
60         pre_load: None,
61         post_load: None,
62         pre_save: None,
63         post_save: None,
64         needed: None,
65         dev_unplug_pending: None,
66         fields: ptr::null(),
67         subsections: ptr::null(),
68     };
69 }
70 
71 unsafe impl Zeroable for crate::bindings::MemoryRegionOps__bindgen_ty_1 {
72     const ZERO: Self = Self {
73         min_access_size: 0,
74         max_access_size: 0,
75         unaligned: false,
76         accepts: None,
77     };
78 }
79 
80 unsafe impl Zeroable for crate::bindings::MemoryRegionOps__bindgen_ty_2 {
81     const ZERO: Self = Self {
82         min_access_size: 0,
83         max_access_size: 0,
84         unaligned: false,
85     };
86 }
87