Skip to content

Undefined behaviour in slice::fill specialization. #87891

@m-ou-se

Description

This was reported by @the8472 on Zulip: https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/potential.20UB.20in.20slice.3A.3Afill/near/248871405

I'm wondering if the optimization here is correct:

if size_of::<T>() == 1 {
// SAFETY: The size_of check above ensures that values are 1 byte wide, as required
// for the transmute and write_bytes
unsafe {
let value: u8 = transmute_copy(&value);
write_bytes(self.as_mut_ptr(), value, self.len());
}

Specifically if T is MaybeUninit<u8>. It momentarily transmutes that to an u8 before passing it to write_bytes.

Demo:

use std::mem::MaybeUninit;

fn main() {
    let mut a = [MaybeUninit::<u8>::uninit(); 10];
    a.fill(MaybeUninit::uninit());
}
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
    --> /home/mara/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/intrinsics.rs:2191:14
     |
2191 |     unsafe { write_bytes(dst, val, count) }
     |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
     |
     = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
     = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-raw-pointersArea: raw pointers, MaybeUninit, NonNullA-sliceArea: `[T]`E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.T-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions