Miri: relax fn ptr check

This commit is contained in:
Ralf Jung 2022-02-22 18:49:12 -05:00
parent 68369a041c
commit 182d335870
4 changed files with 110 additions and 31 deletions

View file

@ -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 `!`" }),