diff options
| author | Ralf Jung <post@ralfj.de> | 2022-02-22 18:49:12 -0500 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2022-02-23 15:11:38 -0500 |
| commit | 182d335870265a102c0f6467db65b5e59bd97e24 (patch) | |
| tree | 1d6f73b4ae0b5b21eb69d7e233798eaff39799fc /compiler/rustc_const_eval/src/interpret | |
| parent | 68369a041cea809a87e5bd80701da90e0e0a4799 (diff) | |
| download | rust-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.rs | 31 |
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 `!`" }), |
