Skip to content

New lint: lint against any MaybeUninit::uninit() #16342

@tgross35

Description

@tgross35

What it does

Warn for any calls to MaybeUninit::uninit(). Alternatively, expand uninit_assumed_init to any uses of MaybeUninit::uninit() followed after some code by .assume_init().

Advantage

MaybeUninit::uninit() isn't unsound on its own, but it can be a bit of a footgun with libc types and other FFI. The issue is that a number of libc structs have padding that the system libc/kernel doesn't write, and occasionally there are new fields added. This means that fairly innocent looking code like this:

let mut s = MaybeUninit::<foo>::uninit();
libc::do_foo(s.as_mut_ptr());
return s.assume_init();

Can turn into UB if libc adds a field that hasn't yet made it to the local glibc version. Using zeroed instead is safe against this, and should be negligible to no cost.

Drawbacks

No response

Example

let mut s = MaybeUninit::<foo>::uninit();
libc::do_foo(s.as_mut_ptr());
return s.assume_init();

Could be written as:

let mut s = MaybeUninit::<foo>::zeroed();
libc::do_foo(s.as_mut_ptr());
return s.assume_init();

Comparison with existing lints

This is similar to clippy::uninit_assumed_init, though that specifically looks for MaybeUninit::uninit().assume_init().

Additional Context

Technically this doesn't need to warn if assume_init is never called, but that adds more difficulty to the lint.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintArea: New lints

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions