From 8b18860677a84778478deed4408586ebaaac868b Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Thu, 10 Nov 2022 11:37:28 -0500 Subject: [PATCH 1/6] A MIR transform that checks pointers are aligned --- src/base.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/base.rs b/src/base.rs index 2107ae147e980..67ed2b33c5ac8 100644 --- a/src/base.rs +++ b/src/base.rs @@ -379,6 +379,18 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { source_info.span, ); } + AssertKind::MisalignedPointerDereference { ref required, ref found } => { + let required = codegen_operand(fx, required).load_scalar(fx); + let found = codegen_operand(fx, found).load_scalar(fx); + let location = fx.get_caller_location(source_info).load_scalar(fx); + + codegen_panic_inner( + fx, + rustc_hir::LangItem::PanicBoundsCheck, + &[required, found, location], + source_info.span, + ); + } _ => { let msg_str = msg.description(); codegen_panic(fx, msg_str, source_info); From 406eb96437d9a75d17c0aa3dcc3cec7c0c8eb69d Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 28 Mar 2023 12:32:57 -0700 Subject: [PATCH 2/6] =?UTF-8?q?Move=20`mir::Field`=20=E2=86=92=20`abi::Fie?= =?UTF-8?q?ldIdx`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first PR for https://github.com/rust-lang/compiler-team/issues/606 This is just the move-and-rename, because it's plenty big-and-bitrotty already. Future PRs will start using `FieldIdx` more broadly, and concomitantly removing `FieldIdx::new`s. --- src/abi/mod.rs | 4 ++-- src/base.rs | 2 +- src/discriminant.rs | 6 +++--- src/intrinsics/llvm_x86.rs | 4 ++-- src/intrinsics/simd.rs | 2 +- src/lib.rs | 2 +- src/unsize.rs | 4 ++-- src/value_and_place.rs | 6 +++--- src/vtable.rs | 6 +++--- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 3bc64c44524ed..91c085d3d6986 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -327,7 +327,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ ArgKind::Spread(params) => { for (i, param) in params.into_iter().enumerate() { if let Some(param) = param { - place.place_field(fx, mir::Field::new(i)).write_cvalue(fx, param); + place.place_field(fx, FieldIdx::new(i)).write_cvalue(fx, param); } } } @@ -460,7 +460,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( args.push(self_arg); for i in 0..tupled_arguments.len() { args.push(CallArgument { - value: pack_arg.value.value_field(fx, mir::Field::new(i)), + value: pack_arg.value.value_field(fx, FieldIdx::new(i)), is_owned: pack_arg.is_owned, }); } diff --git a/src/base.rs b/src/base.rs index 1825fb8cb2288..615ef58ff5829 100644 --- a/src/base.rs +++ b/src/base.rs @@ -797,7 +797,7 @@ fn codegen_stmt<'tcx>( let index = fx.bcx.ins().iconst(fx.pointer_type, field_index as i64); variant_dest.place_index(fx, index) } else { - variant_dest.place_field(fx, mir::Field::new(field_index)) + variant_dest.place_field(fx, FieldIdx::new(field_index)) }; to.write_cvalue(fx, operand); } diff --git a/src/discriminant.rs b/src/discriminant.rs index 3cbf313adf0df..f740945a03c31 100644 --- a/src/discriminant.rs +++ b/src/discriminant.rs @@ -26,7 +26,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>( tag_encoding: TagEncoding::Direct, variants: _, } => { - let ptr = place.place_field(fx, mir::Field::new(tag_field)); + let ptr = place.place_field(fx, FieldIdx::new(tag_field)); let to = layout.ty.discriminant_for_variant(fx.tcx, variant_index).unwrap().val; let to = if ptr.layout().abi.is_signed() { ty::ScalarInt::try_from_int( @@ -47,7 +47,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>( variants: _, } => { if variant_index != untagged_variant { - let niche = place.place_field(fx, mir::Field::new(tag_field)); + let niche = place.place_field(fx, FieldIdx::new(tag_field)); let niche_type = fx.clif_type(niche.layout().ty).unwrap(); let niche_value = variant_index.as_u32() - niche_variants.start().as_u32(); let niche_value = (niche_value as u128).wrapping_add(niche_start); @@ -107,7 +107,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>( let cast_to = fx.clif_type(dest_layout.ty).unwrap(); // Read the tag/niche-encoded discriminant from memory. - let tag = value.value_field(fx, mir::Field::new(tag_field)); + let tag = value.value_field(fx, FieldIdx::new(tag_field)); let tag = tag.load_scalar(fx); // Decode the discriminant (specifically if it's niche-encoded). diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index e5c4b244a1afd..0f32d1a25ffad 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -179,8 +179,8 @@ fn llvm_add_sub<'tcx>( // c + carry -> c + first intermediate carry or borrow respectively let int0 = crate::num::codegen_checked_int_binop(fx, bin_op, a, b); - let c = int0.value_field(fx, mir::Field::new(0)); - let cb0 = int0.value_field(fx, mir::Field::new(1)).load_scalar(fx); + let c = int0.value_field(fx, FieldIdx::new(0)); + let cb0 = int0.value_field(fx, FieldIdx::new(1)).load_scalar(fx); // c + carry -> c + second intermediate carry or borrow respectively let cb_in_as_u64 = fx.bcx.ins().uextend(types::I64, cb_in); diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 034b4e8072cc5..6f54a8d49c867 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -253,7 +253,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( } ret.write_cvalue(fx, base); - let ret_lane = ret.place_field(fx, mir::Field::new(idx.try_into().unwrap())); + let ret_lane = ret.place_field(fx, FieldIdx::new(idx.try_into().unwrap())); ret_lane.write_cvalue(fx, val); } diff --git a/src/lib.rs b/src/lib.rs index 1bd03403f244b..8cc7f6c34b021 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,7 +86,7 @@ mod prelude { self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeVisitableExt, UintTy, }; - pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx, FIRST_VARIANT}; + pub(crate) use rustc_target::abi::{Abi, FieldIdx, Scalar, Size, VariantIdx, FIRST_VARIANT}; pub(crate) use rustc_data_structures::fx::FxHashMap; diff --git a/src/unsize.rs b/src/unsize.rs index 93eefd92342d8..ff0e12410e703 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -147,8 +147,8 @@ pub(crate) fn coerce_unsized_into<'tcx>( assert_eq!(def_a, def_b); for i in 0..def_a.variant(FIRST_VARIANT).fields.len() { - let src_f = src.value_field(fx, mir::Field::new(i)); - let dst_f = dst.place_field(fx, mir::Field::new(i)); + let src_f = src.value_field(fx, FieldIdx::new(i)); + let dst_f = dst.place_field(fx, FieldIdx::new(i)); if dst_f.layout().is_zst() { continue; diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 58e0a498292d4..ffe3ccb0eca04 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -10,7 +10,7 @@ fn codegen_field<'tcx>( base: Pointer, extra: Option, layout: TyAndLayout<'tcx>, - field: mir::Field, + field: FieldIdx, ) -> (Pointer, TyAndLayout<'tcx>) { let field_offset = layout.fields.offset(field.index()); let field_layout = layout.field(&*fx, field.index()); @@ -210,7 +210,7 @@ impl<'tcx> CValue<'tcx> { pub(crate) fn value_field( self, fx: &mut FunctionCx<'_, '_, 'tcx>, - field: mir::Field, + field: FieldIdx, ) -> CValue<'tcx> { let layout = self.1; match self.0 { @@ -687,7 +687,7 @@ impl<'tcx> CPlace<'tcx> { pub(crate) fn place_field( self, fx: &mut FunctionCx<'_, '_, 'tcx>, - field: mir::Field, + field: FieldIdx, ) -> CPlace<'tcx> { let layout = self.layout(); diff --git a/src/vtable.rs b/src/vtable.rs index 94806e0d798ed..b309695c190f8 100644 --- a/src/vtable.rs +++ b/src/vtable.rs @@ -50,7 +50,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>( if let Abi::Scalar(_) = arg.layout().abi { 'descend_newtypes: while !arg.layout().ty.is_unsafe_ptr() && !arg.layout().ty.is_ref() { for i in 0..arg.layout().fields.count() { - let field = arg.value_field(fx, mir::Field::new(i)); + let field = arg.value_field(fx, FieldIdx::new(i)); if !field.layout().is_zst() { // we found the one non-zero-sized field that is allowed // now find *its* non-zero-sized field, or stop if it's a @@ -68,9 +68,9 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>( if ty.is_dyn_star() { let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap().ty); let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout); - let ptr = dyn_star.place_field(fx, mir::Field::new(0)).to_ptr(); + let ptr = dyn_star.place_field(fx, FieldIdx::new(0)).to_ptr(); let vtable = - dyn_star.place_field(fx, mir::Field::new(1)).to_cvalue(fx).load_scalar(fx); + dyn_star.place_field(fx, FieldIdx::new(1)).to_cvalue(fx).load_scalar(fx); break 'block (ptr, vtable); } } From 69b57c2db5e8718525aa1cd5b954708387a5e594 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 28 Mar 2023 23:32:25 -0700 Subject: [PATCH 3/6] Update `ty::VariantDef` to use `IndexVec` And while doing the updates for that, also uses `FieldIdx` in `ProjectionKind::Field` and `TypeckResults::field_indices`. There's more places that could use it (like `rustc_const_eval` and `LayoutS`), but I tried to keep this PR from exploding to *even more* places. Part 2/? of https://github.com/rust-lang/compiler-team/issues/606 --- src/value_and_place.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index ffe3ccb0eca04..1b69862ce2ca1 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -701,7 +701,8 @@ impl<'tcx> CPlace<'tcx> { }; } ty::Adt(adt_def, substs) if layout.ty.is_simd() => { - let f0_ty = adt_def.non_enum_variant().fields[0].ty(fx.tcx, substs); + let f0 = &adt_def.non_enum_variant().fields[FieldIdx::from_u32(0)]; + let f0_ty = f0.ty(fx.tcx, substs); match f0_ty.kind() { ty::Array(_, _) => { From dc5a8c8881256c79c8fb57452aa38d4c9dfe6305 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 1 Apr 2023 20:11:38 -0700 Subject: [PATCH 4/6] Use `FieldIdx` in various things related to aggregates Shrank `AggregateKind` by 8 bytes on x64, since the active field of a union is tracked as an `Option` instead of `Option`. --- src/base.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/base.rs b/src/base.rs index 98112fe08305e..2630f02e6eb31 100644 --- a/src/base.rs +++ b/src/base.rs @@ -802,14 +802,15 @@ fn codegen_stmt<'tcx>( if active_field_index.is_some() { assert_eq!(operands.len(), 1); } - for (i, operand) in operands.iter().enumerate() { + for (i, operand) in operands.iter_enumerated() { let operand = codegen_operand(fx, operand); let field_index = active_field_index.unwrap_or(i); let to = if let mir::AggregateKind::Array(_) = **kind { - let index = fx.bcx.ins().iconst(fx.pointer_type, field_index as i64); + let array_index = i64::from(field_index.as_u32()); + let index = fx.bcx.ins().iconst(fx.pointer_type, array_index); variant_dest.place_index(fx, index) } else { - variant_dest.place_field(fx, FieldIdx::new(field_index)) + variant_dest.place_field(fx, field_index) }; to.write_cvalue(fx, operand); } From 9da329d243129b7383a65e4e2651ff9b663bdffd Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Sat, 8 Oct 2022 23:47:59 +0100 Subject: [PATCH 5/6] Refactor unwind from Option to a new enum --- src/base.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/base.rs b/src/base.rs index 2630f02e6eb31..94413318492f1 100644 --- a/src/base.rs +++ b/src/base.rs @@ -345,7 +345,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { TerminatorKind::Return => { crate::abi::codegen_return(fx); } - TerminatorKind::Assert { cond, expected, msg, target, cleanup: _ } => { + TerminatorKind::Assert { cond, expected, msg, target, unwind: _ } => { if !fx.tcx.sess.overflow_checks() && msg.is_optional_overflow_check() { let target = fx.get_block(*target); fx.bcx.ins().jump(target, &[]); @@ -450,7 +450,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { destination, target, fn_span, - cleanup: _, + unwind: _, from_hir_call: _, } => { fx.tcx.prof.generic_activity("codegen call").run(|| { @@ -470,7 +470,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { options, destination, line_spans: _, - cleanup: _, + unwind: _, } => { if options.contains(InlineAsmOptions::MAY_UNWIND) { fx.tcx.sess.span_fatal( From 446650cb008d7f7c3fee06b9692d2f42d48041d5 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Mon, 31 Oct 2022 01:01:24 +0000 Subject: [PATCH 6/6] Rename `Abort` terminator to `Terminate` Unify terminology used in unwind action and terminator, and reflect the fact that a nounwind panic is triggered instead of an immediate abort is triggered for this terminator. --- src/base.rs | 2 +- src/constant.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/base.rs b/src/base.rs index 94413318492f1..f5301f9f7f10b 100644 --- a/src/base.rs +++ b/src/base.rs @@ -488,7 +488,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { *destination, ); } - TerminatorKind::Abort => { + TerminatorKind::Terminate => { codegen_panic_cannot_unwind(fx, source_info); } TerminatorKind::Resume => { diff --git a/src/constant.rs b/src/constant.rs index ebb4de33f990a..e87f4e258911a 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -549,7 +549,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( TerminatorKind::Goto { .. } | TerminatorKind::SwitchInt { .. } | TerminatorKind::Resume - | TerminatorKind::Abort + | TerminatorKind::Terminate | TerminatorKind::Return | TerminatorKind::Unreachable | TerminatorKind::Drop { .. }