diff options
| author | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2022-03-03 12:02:12 +0000 |
|---|---|---|
| committer | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2022-04-05 13:18:21 +0000 |
| commit | d32ce37a171663048a4c4a536803434e40f52bd6 (patch) | |
| tree | 3305f97d4481ab2ca15fa3f1dcec4f6331c0bc30 /compiler/rustc_const_eval/src | |
| parent | 2ed6786404be276874fbcc7c3540f3237a87e0f3 (diff) | |
Mark scalar layout unions so that backends that do not support partially initialized scalars can special case them.
Diffstat (limited to 'compiler/rustc_const_eval/src')
5 files changed, 18 insertions, 13 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index c80d7d71787..66fa846ee73 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -188,7 +188,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val = self.read_scalar(&args[0])?.check_init()?; let bits = val.to_bits(layout_of.size)?; let kind = match layout_of.abi { - Abi::Scalar(scalar) => scalar.value, + Abi::Scalar(scalar) => scalar.primitive(), _ => span_bug!( self.cur_span(), "{} called on invalid type {:?}", diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 9000567558b..73009052e04 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -265,6 +265,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { })); }; + // It may seem like all types with `Scalar` or `ScalarPair` ABI are fair game at this point. + // However, `MaybeUninit<u64>` is considered a `Scalar` as far as its layout is concerned -- + // and yet cannot be represented by an interpreter `Scalar`, since we have to handle the + // case where some of the bytes are initialized and others are not. So, we only permit + // reads from `Scalar`s and `ScalarPair`s that cannot be uninitialized. match mplace.layout.abi { Abi::Scalar(..) => { let scalar = alloc.read_scalar(alloc_range(Size::ZERO, mplace.layout.size))?; @@ -274,7 +279,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // We checked `ptr_align` above, so all fields will have the alignment they need. // We would anyway check against `ptr_align.restrict_for_offset(b_offset)`, // which `ptr.offset(b_offset)` cannot possibly fail to satisfy. - let (a, b) = (a.value, b.value); let (a_size, b_size) = (a.size(self), b.size(self)); let b_offset = a_size.align_to(b.align(self).abi); assert!(b_offset.bytes() > 0); // we later use the offset to tell apart the fields @@ -676,7 +680,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // may be a pointer. This is `tag_val.layout`; we just use it for sanity checks. // Get layout for tag. - let tag_layout = self.layout_of(tag_scalar_layout.value.to_int_ty(*self.tcx))?; + let tag_layout = self.layout_of(tag_scalar_layout.primitive().to_int_ty(*self.tcx))?; // Read tag and sanity-check `tag_layout`. let tag_val = self.read_immediate(&self.operand_field(op, tag_field)?)?; diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 5b8d74b4307..e8b3874ec07 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -772,13 +772,11 @@ where // We checked `ptr_align` above, so all fields will have the alignment they need. // We would anyway check against `ptr_align.restrict_for_offset(b_offset)`, // which `ptr.offset(b_offset)` cannot possibly fail to satisfy. - let (a, b) = match dest.layout.abi { - Abi::ScalarPair(a, b) => (a.value, b.value), - _ => span_bug!( + let Abi::ScalarPair(a, b) = dest.layout.abi else { span_bug!( self.cur_span(), "write_immediate_to_mplace: invalid ScalarPair layout: {:#?}", dest.layout - ), + ) }; let (a_size, b_size) = (a.size(&tcx), b.size(&tcx)); let b_offset = a_size.align_to(b.align(&tcx).abi); @@ -1047,7 +1045,7 @@ where // raw discriminants for enums are isize or bigger during // their computation, but the in-memory tag is the smallest possible // representation - let size = tag_layout.value.size(self); + let size = tag_layout.size(self); let tag_val = size.truncate(discr_val); let tag_dest = self.place_field(dest, tag_field)?; @@ -1071,7 +1069,7 @@ where .expect("overflow computing relative variant idx"); // We need to use machine arithmetic when taking into account `niche_start`: // tag_val = variant_index_relative + niche_start_val - let tag_layout = self.layout_of(tag_layout.value.to_int_ty(*self.tcx))?; + let tag_layout = self.layout_of(tag_layout.primitive().to_int_ty(*self.tcx))?; let niche_start_val = ImmTy::from_uint(niche_start, tag_layout); let variant_index_relative_val = ImmTy::from_uint(variant_index_relative, tag_layout); diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index d33358499e2..3ffa514a7b9 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -189,12 +189,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // that will take care to make it UB to leave the range, just // like for transmute). (abi::Abi::Scalar(caller), abi::Abi::Scalar(callee)) => { - caller.value == callee.value + caller.primitive() == callee.primitive() } ( abi::Abi::ScalarPair(caller1, caller2), abi::Abi::ScalarPair(callee1, callee2), - ) => caller1.value == callee1.value && caller2.value == callee2.value, + ) => { + caller1.primitive() == callee1.primitive() + && caller2.primitive() == callee2.primitive() + } // Be conservative _ => false, } diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 9da7f5e30cb..3d5ad153c9b 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -629,12 +629,12 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' op: &OpTy<'tcx, M::PointerTag>, scalar_layout: ScalarAbi, ) -> InterpResult<'tcx> { - if scalar_layout.valid_range.is_full_for(op.layout.size) { + if scalar_layout.valid_range(self.ecx).is_full_for(op.layout.size) { // Nothing to check return Ok(()); } // At least one value is excluded. - let valid_range = scalar_layout.valid_range; + let valid_range = scalar_layout.valid_range(self.ecx); let WrappingRange { start, end } = valid_range; let max_value = op.layout.size.unsigned_int_max(); assert!(end <= max_value); |
