Skip to content

Commit 3984bc5

Browse files
committed
Auto merge of rust-lang#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 rust-lang#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`
2 parents 38a76f3 + f125538 commit 3984bc5

39 files changed

+130
-109
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
501501
layout: TyAndLayout<'tcx>,
502502
offset: Size,
503503
) {
504-
if !scalar.is_always_valid(bx) {
504+
if !scalar.is_uninit_valid() {
505505
bx.noundef_metadata(load);
506506
}
507507

compiler/rustc_ty_utils/src/abi.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,7 @@ fn adjust_for_rust_scalar<'tcx>(
219219
return;
220220
}
221221

222-
// Scalars which have invalid values cannot be undef.
223-
if !scalar.is_always_valid(&cx) {
222+
if !scalar.is_uninit_valid() {
224223
attrs.set(ArgAttribute::NoUndef);
225224
}
226225

@@ -246,11 +245,6 @@ fn adjust_for_rust_scalar<'tcx>(
246245
PointerKind::SharedMutable | PointerKind::UniqueOwned => Size::ZERO,
247246
};
248247

249-
// `Box`, `&T`, and `&mut T` cannot be undef.
250-
// Note that this only applies to the value of the pointer itself;
251-
// this attribute doesn't make it UB for the pointed-to data to be undef.
252-
attrs.set(ArgAttribute::NoUndef);
253-
254248
// The aliasing rules for `Box<T>` are still not decided, but currently we emit
255249
// `noalias` for it. This can be turned off using an unstable flag.
256250
// See https://github.com/rust-lang/unsafe-code-guidelines/issues/326

tests/codegen/abi-sysv64.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// of the sysv64 abi.
44
//
55
// needs-llvm-components: x86
6-
// compile-flags: -C no-prepopulate-passes --target=x86_64-unknown-linux-gnu
6+
// compile-flags: -C no-prepopulate-passes --target=x86_64-unknown-linux-gnu -Copt-level=0
77

88
#![crate_type = "lib"]
99
#![no_core]

tests/codegen/abi-x86-interrupt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// of the x86-interrupt abi.
44

55
// needs-llvm-components: x86
6-
// compile-flags: -C no-prepopulate-passes --target=x86_64-unknown-linux-gnu
6+
// compile-flags: -C no-prepopulate-passes --target=x86_64-unknown-linux-gnu -Copt-level=0
77

88
#![crate_type = "lib"]
99
#![no_core]

tests/codegen/adjustments.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// compile-flags: -C no-prepopulate-passes
1+
// compile-flags: -C no-prepopulate-passes -Copt-level=0
22

33
#![crate_type = "lib"]
44

tests/codegen/box-maybe-uninit-llvm14.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ pub fn box_uninitialized2() -> Box<MaybeUninit<[usize; 1024 * 1024]>> {
3131
// Hide the LLVM 15+ `allocalign` attribute in the declaration of __rust_alloc
3232
// from the CHECK-NOT above. We don't check the attributes here because we can't rely
3333
// on all of them being set until LLVM 15.
34-
// CHECK: declare noalias{{.*}} @__rust_alloc(i{{[0-9]+}}, i{{[0-9]+.*}})
34+
// CHECK: declare noalias{{.*}} @__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+.*}} noundef)

tests/codegen/box-maybe-uninit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ pub fn box_uninitialized2() -> Box<MaybeUninit<[usize; 1024 * 1024]>> {
2828

2929
// Hide the `allocalign` attribute in the declaration of __rust_alloc
3030
// from the CHECK-NOT above, and also verify the attributes got set reasonably.
31-
// CHECK: declare noalias ptr @__rust_alloc(i{{[0-9]+}}, i{{[0-9]+}} allocalign) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]]
31+
// CHECK: declare noalias noundef ptr @__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+}} allocalign noundef) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]]
3232

3333
// CHECK-DAG: attributes [[RUST_ALLOC_ATTRS]] = { {{.*}} allockind("alloc,uninitialized,aligned") allocsize(0) uwtable "alloc-family"="__rust_alloc" {{.*}} }

tests/codegen/c-variadic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// ignore-wasm32-bare compiled with panic=abort by default
2-
// compile-flags: -C no-prepopulate-passes
2+
// compile-flags: -C no-prepopulate-passes -Copt-level=0
33
//
44

55
#![crate_type = "lib"]

tests/codegen/call-llvm-intrinsics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// compile-flags: -C no-prepopulate-passes
1+
// compile-flags: -C no-prepopulate-passes -Copt-level=0
22

33
// ignore-riscv64
44

tests/codegen/comparison-operators-newtype.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::cmp::Ordering;
1313
pub struct Foo(u16);
1414

1515
// CHECK-LABEL: @check_lt
16-
// CHECK-SAME: (i16 %[[A:.+]], i16 %[[B:.+]])
16+
// CHECK-SAME: (i16 noundef %[[A:.+]], i16 noundef %[[B:.+]])
1717
#[no_mangle]
1818
pub fn check_lt(a: Foo, b: Foo) -> bool {
1919
// CHECK: %[[R:.+]] = icmp ult i16 %[[A]], %[[B]]
@@ -22,7 +22,7 @@ pub fn check_lt(a: Foo, b: Foo) -> bool {
2222
}
2323

2424
// CHECK-LABEL: @check_le
25-
// CHECK-SAME: (i16 %[[A:.+]], i16 %[[B:.+]])
25+
// CHECK-SAME: (i16 noundef %[[A:.+]], i16 noundef %[[B:.+]])
2626
#[no_mangle]
2727
pub fn check_le(a: Foo, b: Foo) -> bool {
2828
// CHECK: %[[R:.+]] = icmp ule i16 %[[A]], %[[B]]
@@ -31,7 +31,7 @@ pub fn check_le(a: Foo, b: Foo) -> bool {
3131
}
3232

3333
// CHECK-LABEL: @check_gt
34-
// CHECK-SAME: (i16 %[[A:.+]], i16 %[[B:.+]])
34+
// CHECK-SAME: (i16 noundef %[[A:.+]], i16 noundef %[[B:.+]])
3535
#[no_mangle]
3636
pub fn check_gt(a: Foo, b: Foo) -> bool {
3737
// CHECK: %[[R:.+]] = icmp ugt i16 %[[A]], %[[B]]
@@ -40,7 +40,7 @@ pub fn check_gt(a: Foo, b: Foo) -> bool {
4040
}
4141

4242
// CHECK-LABEL: @check_ge
43-
// CHECK-SAME: (i16 %[[A:.+]], i16 %[[B:.+]])
43+
// CHECK-SAME: (i16 noundef %[[A:.+]], i16 noundef %[[B:.+]])
4444
#[no_mangle]
4545
pub fn check_ge(a: Foo, b: Foo) -> bool {
4646
// CHECK: %[[R:.+]] = icmp uge i16 %[[A]], %[[B]]

0 commit comments

Comments
 (0)