summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/interpret
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2021-11-28 13:00:37 -0500
committerRalf Jung <post@ralfj.de>2021-11-29 11:49:31 -0500
commit6c3c3e0952b63cfae51392863e94d79c2d76deb9 (patch)
treeecdda752236c95b4443ce78f9b89f1ff348015a5 /compiler/rustc_const_eval/src/interpret
parent58f9efd36de5669ab731ec7ebf565999ff17b159 (diff)
downloadrust-6c3c3e0952b63cfae51392863e94d79c2d76deb9.tar.gz
rust-6c3c3e0952b63cfae51392863e94d79c2d76deb9.zip
CTFE: support assert_zero_valid and assert_uninit_valid
Diffstat (limited to 'compiler/rustc_const_eval/src/interpret')
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs26
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()?);