summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/interpret
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2022-02-22 18:49:12 -0500
committerRalf Jung <post@ralfj.de>2022-02-23 15:11:38 -0500
commit182d335870265a102c0f6467db65b5e59bd97e24 (patch)
tree1d6f73b4ae0b5b21eb69d7e233798eaff39799fc /compiler/rustc_const_eval/src/interpret
parent68369a041cea809a87e5bd80701da90e0e0a4799 (diff)
downloadrust-182d335870265a102c0f6467db65b5e59bd97e24.tar.gz
rust-182d335870265a102c0f6467db65b5e59bd97e24.zip
Miri: relax fn ptr check
Diffstat (limited to 'compiler/rustc_const_eval/src/interpret')
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs31
1 files changed, 18 insertions, 13 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 54e29299e6c..0bf86d52080 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -567,22 +567,27 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
             }
             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)) =>
-                        { "{:x}", value } expected { "a function pointer" },
-                );
-                // FIXME: Check if the signature matches
+                let ptr = self.ecx.scalar_to_ptr(value);
+                // Ensure the pointer is non-null.
+                if self.ecx.memory.ptr_may_be_null(ptr) {
+                    throw_validation_failure!(self.path, { "a potentially null function pointer" });
+                }
+                // If we check references recursively, also check that this points to a function.
+                if let Some(_) = self.ref_tracking {
+                    let _fn = try_validation!(
+                        self.ecx.memory.get_fn(ptr),
+                        self.path,
+                        err_ub!(DanglingIntPointer(..)) |
+                        err_ub!(InvalidFunctionPointer(..)) =>
+                            { "{:x}", value } expected { "a function pointer" },
+                    );
+                    // FIXME: Check if the signature matches
+                }
                 Ok(true)
             }
             ty::Never => throw_validation_failure!(self.path, { "a value of the never type `!`" }),