diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/intrinsics.rs | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 44da27a43db..025d2998b00 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -394,10 +394,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { sym::transmute => { self.copy_op_transmute(&args[0], dest)?; } - sym::assert_inhabited => { + sym::assert_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => { let ty = instance.substs.type_at(0); let layout = self.layout_of(ty)?; + // For *all* intrinsics we first check `is_uninhabited` to give a more specific + // error message. if layout.abi.is_uninhabited() { // The run-time intrinsic panics just to get a good backtrace; here we abort // since there is no problem showing a backtrace even for aborts. @@ -409,6 +411,28 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ), )?; } + if intrinsic_name == sym::assert_zero_valid + && !layout.might_permit_raw_init(self, /*zero:*/ true) + { + M::abort( + self, + format!( + "aborted execution: attempted to zero-initialize type `{}`, which is invalid", + ty + ), + )?; + } + if intrinsic_name == sym::assert_uninit_valid + && !layout.might_permit_raw_init(self, /*zero:*/ false) + { + M::abort( + self, + format!( + "aborted execution: attempted to leave type `{}` uninitialized, which is invalid", + ty + ), + )?; + } } sym::simd_insert => { let index = u64::from(self.read_scalar(&args[1])?.to_u32()?); |
