From 345bef46a1b6765185bfe1450cc147f5feb5d0e7 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 4 Mar 2025 20:48:05 +0100 Subject: rust: qom: change instance_init to take a ParentInit<> This removes undefined behavior associated to writing to uninitialized fields, and makes it possible to remove "unsafe" from the instance_init implementation. However, the init function itself is still unsafe, because it must promise (as a sort as MaybeUninit::assume_init) that all fields have been initialized. Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/qom.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'rust/qemu-api/src/qom.rs') diff --git a/rust/qemu-api/src/qom.rs b/rust/qemu-api/src/qom.rs index 04d102591d..e20ee014cb 100644 --- a/rust/qemu-api/src/qom.rs +++ b/rust/qemu-api/src/qom.rs @@ -382,12 +382,15 @@ impl DerefMut for ParentInit<'_, T> { } unsafe extern "C" fn rust_instance_init(obj: *mut bindings::Object) { - let mut state = NonNull::new(obj).unwrap().cast::(); + let mut state = NonNull::new(obj).unwrap().cast::>(); + // SAFETY: obj is an instance of T, since rust_instance_init // is called from QOM core as the instance_init function // for class T unsafe { - T::INSTANCE_INIT.unwrap()(state.as_mut()); + ParentInit::with(state.as_mut(), |parent_init| { + T::INSTANCE_INIT.unwrap()(parent_init); + }); } } @@ -654,7 +657,7 @@ pub trait ObjectImpl: ObjectType + IsA { /// /// FIXME: The argument is not really a valid reference. `&mut /// MaybeUninit` would be a better description. - const INSTANCE_INIT: Option = None; + const INSTANCE_INIT: Option)> = None; /// Function that is called to finish initialization of an object, once /// `INSTANCE_INIT` functions have been called. -- cgit 1.4.1