]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_const_eval/src/interpret/validity.rs
Rollup merge of #93400 - ChayimFriedman2:dont-suggest-using-const-with-bounds-unused...
[rust.git] / compiler / rustc_const_eval / src / interpret / validity.rs
index e95e327618f0bf8fd9bcf7fad03fe08ec8deb7dc..5cacab823866ad81dc7804e103ae69a625e2b183 100644 (file)
@@ -503,7 +503,7 @@ fn try_visit_primitive(
                     value.to_bool(),
                     self.path,
                     err_ub!(InvalidBool(..)) | err_ub!(InvalidUninitBytes(None)) =>
-                        { "{}", value } expected { "a boolean" },
+                        { "{:x}", value } expected { "a boolean" },
                 );
                 Ok(true)
             }
@@ -513,7 +513,7 @@ fn try_visit_primitive(
                     value.to_char(),
                     self.path,
                     err_ub!(InvalidChar(..)) | err_ub!(InvalidUninitBytes(None)) =>
-                        { "{}", value } expected { "a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)" },
+                        { "{:x}", value } expected { "a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)" },
                 );
                 Ok(true)
             }
@@ -526,7 +526,7 @@ fn try_visit_primitive(
                     let is_bits = value.check_init().map_or(false, |v| v.try_to_int().is_ok());
                     if !is_bits {
                         throw_validation_failure!(self.path,
-                            { "{}", value } expected { "initialized plain (non-pointer) bytes" }
+                            { "{:x}", value } expected { "initialized plain (non-pointer) bytes" }
                         )
                     }
                 }
@@ -567,22 +567,31 @@ fn try_visit_primitive(
             }
             ty::FnPtr(_sig) => {
                 let value = try_validation!(
-                    self.ecx.read_immediate(value),
+                    self.ecx.read_scalar(value).and_then(|v| v.check_init()),
                     self.path,
                     err_unsup!(ReadPointerAsBytes) => { "part of a pointer" } expected { "a proper pointer or integer value" },
+                    err_ub!(InvalidUninitBytes(None)) => { "uninitialized bytes" } expected { "a proper pointer or integer value" },
                 );
-                // Make sure we print a `ScalarMaybeUninit` (and not an `ImmTy`) in the error
-                // message below.
-                let value = value.to_scalar_or_uninit();
-                let _fn = try_validation!(
-                    value.check_init().and_then(|ptr| self.ecx.memory.get_fn(self.ecx.scalar_to_ptr(ptr))),
-                    self.path,
-                    err_ub!(DanglingIntPointer(..)) |
-                    err_ub!(InvalidFunctionPointer(..)) |
-                    err_ub!(InvalidUninitBytes(None)) =>
-                        { "{}", value } expected { "a function pointer" },
-                );
-                // FIXME: Check if the signature matches
+
+                // If we check references recursively, also check that this points to a function.
+                if let Some(_) = self.ref_tracking {
+                    let ptr = self.ecx.scalar_to_ptr(value);
+                    let _fn = try_validation!(
+                        self.ecx.memory.get_fn(ptr),
+                        self.path,
+                        err_ub!(DanglingIntPointer(0, _)) =>
+                            { "a null function pointer" },
+                        err_ub!(DanglingIntPointer(..)) |
+                        err_ub!(InvalidFunctionPointer(..)) =>
+                            { "{:x}", value } expected { "a function pointer" },
+                    );
+                    // FIXME: Check if the signature matches
+                } else {
+                    // Otherwise (for standalone Miri), we have to still check it to be non-null.
+                    if self.ecx.scalar_may_be_null(value) {
+                        throw_validation_failure!(self.path, { "a null function pointer" });
+                    }
+                }
                 Ok(true)
             }
             ty::Never => throw_validation_failure!(self.path, { "a value of the never type `!`" }),
@@ -632,17 +641,16 @@ fn visit_scalar(
         let value = try_validation!(
             value.check_init(),
             self.path,
-            err_ub!(InvalidUninitBytes(None)) => { "{}", value }
+            err_ub!(InvalidUninitBytes(None)) => { "{:x}", value }
                 expected { "something {}", wrapping_range_format(valid_range, max_value) },
         );
         let bits = match value.try_to_int() {
             Err(_) => {
                 // So this is a pointer then, and casting to an int failed.
                 // Can only happen during CTFE.
-                let ptr = self.ecx.scalar_to_ptr(value);
                 if start == 1 && end == max_value {
                     // Only null is the niche.  So make sure the ptr is NOT null.
-                    if self.ecx.memory.ptr_may_be_null(ptr) {
+                    if self.ecx.scalar_may_be_null(value) {
                         throw_validation_failure!(self.path,
                             { "a potentially null pointer" }
                             expected {
@@ -697,7 +705,7 @@ fn read_discriminant(
                 this.ecx.read_discriminant(op),
                 this.path,
                 err_ub!(InvalidTag(val)) =>
-                    { "{}", val } expected { "a valid enum tag" },
+                    { "{:x}", val } expected { "a valid enum tag" },
                 err_ub!(InvalidUninitBytes(None)) =>
                     { "uninitialized bytes" } expected { "a valid enum tag" },
                 err_unsup!(ReadPointerAsBytes) =>
@@ -753,7 +761,7 @@ fn visit_union(
     fn visit_value(&mut self, op: &OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> {
         trace!("visit_value: {:?}, {:?}", *op, op.layout);
 
-        // Check primitive types -- the leafs of our recursive descend.
+        // Check primitive types -- the leaves of our recursive descent.
         if self.try_visit_primitive(op)? {
             return Ok(());
         }
@@ -851,12 +859,9 @@ fn visit_aggregate(
                 // to reject those pointers, we just do not have the machinery to
                 // talk about parts of a pointer.
                 // We also accept uninit, for consistency with the slow path.
-                let alloc = match self.ecx.memory.get(mplace.ptr, size, mplace.align)? {
-                    Some(a) => a,
-                    None => {
-                        // Size 0, nothing more to check.
-                        return Ok(());
-                    }
+                let Some(alloc) = self.ecx.memory.get(mplace.ptr, size, mplace.align)? else {
+                    // Size 0, nothing more to check.
+                    return Ok(());
                 };
 
                 let allow_uninit_and_ptr = !M::enforce_number_validity(self.ecx);