1
Fork 0

Auto merge of #106294 - Nilstrieb:noundef-everything, r=nikic

Put `noundef` on all scalars that don't allow uninit

Previously, it was only put on scalars with range validity invariants like bool, was uninit was obviously invalid for those.

Since then, we have normatively declared all uninit primitives to be undefined behavior and can therefore put `noundef` on them.

The remaining concern was the `mem::uninitialized` function, which cause quite a lot of UB in the older parts of the ecosystem. After #99182, this function now doesn't return uninit values anymore, making users of it safe from this change.

The only real sources of UB where people could encounter uninit primitives are `MaybeUninit::uninit().assume_init()`, which has always be clear in the docs about being UB and from heap allocations (like reading from the spare capacity of a vec). This is hopefully rare enough to not break anything.

cc `@nagisa` `@scottmcm` `@nikic`
This commit is contained in:
bors 2023-01-17 17:39:48 +00:00
commit 3984bc5833
39 changed files with 130 additions and 109 deletions

View file

@ -219,8 +219,7 @@ fn adjust_for_rust_scalar<'tcx>(
return;
}
// Scalars which have invalid values cannot be undef.
if !scalar.is_always_valid(&cx) {
if !scalar.is_uninit_valid() {
attrs.set(ArgAttribute::NoUndef);
}
@ -246,11 +245,6 @@ fn adjust_for_rust_scalar<'tcx>(
PointerKind::SharedMutable | PointerKind::UniqueOwned => Size::ZERO,
};
// `Box`, `&T`, and `&mut T` cannot be undef.
// Note that this only applies to the value of the pointer itself;
// this attribute doesn't make it UB for the pointed-to data to be undef.
attrs.set(ArgAttribute::NoUndef);
// The aliasing rules for `Box<T>` are still not decided, but currently we emit
// `noalias` for it. This can be turned off using an unstable flag.
// See https://github.com/rust-lang/unsafe-code-guidelines/issues/326