Add intrinsics::const_deallocate
This commit is contained in:
parent
10c4c4afec
commit
aa6795e2d4
11 changed files with 156 additions and 0 deletions
|
@ -347,6 +347,23 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||||
)?;
|
)?;
|
||||||
ecx.write_pointer(ptr, dest)?;
|
ecx.write_pointer(ptr, dest)?;
|
||||||
}
|
}
|
||||||
|
sym::const_deallocate => {
|
||||||
|
let ptr = ecx.read_pointer(&args[0])?;
|
||||||
|
let size = ecx.read_scalar(&args[1])?.to_machine_usize(ecx)?;
|
||||||
|
let align = ecx.read_scalar(&args[2])?.to_machine_usize(ecx)?;
|
||||||
|
|
||||||
|
let size = Size::from_bytes(size);
|
||||||
|
let align = match Align::from_bytes(align) {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(err) => throw_ub_format!("align has to be a power of 2, {}", err),
|
||||||
|
};
|
||||||
|
|
||||||
|
ecx.memory.deallocate(
|
||||||
|
ptr,
|
||||||
|
Some((size, align)),
|
||||||
|
interpret::MemoryKind::Machine(MemoryKind::Heap),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ConstEvalErrKind::NeedsRfc(format!(
|
return Err(ConstEvalErrKind::NeedsRfc(format!(
|
||||||
"calling intrinsic `{}`",
|
"calling intrinsic `{}`",
|
||||||
|
|
|
@ -460,6 +460,7 @@ symbols! {
|
||||||
const_async_blocks,
|
const_async_blocks,
|
||||||
const_compare_raw_pointers,
|
const_compare_raw_pointers,
|
||||||
const_constructor,
|
const_constructor,
|
||||||
|
const_deallocate,
|
||||||
const_eval_limit,
|
const_eval_limit,
|
||||||
const_eval_select,
|
const_eval_select,
|
||||||
const_eval_select_ct,
|
const_eval_select_ct,
|
||||||
|
|
|
@ -297,6 +297,11 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
||||||
sym::const_allocate => {
|
sym::const_allocate => {
|
||||||
(0, vec![tcx.types.usize, tcx.types.usize], tcx.mk_mut_ptr(tcx.types.u8))
|
(0, vec![tcx.types.usize, tcx.types.usize], tcx.mk_mut_ptr(tcx.types.u8))
|
||||||
}
|
}
|
||||||
|
sym::const_deallocate => (
|
||||||
|
0,
|
||||||
|
vec![tcx.mk_mut_ptr(tcx.types.u8), tcx.types.usize, tcx.types.usize],
|
||||||
|
tcx.mk_unit(),
|
||||||
|
),
|
||||||
|
|
||||||
sym::ptr_offset_from => {
|
sym::ptr_offset_from => {
|
||||||
(1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.isize)
|
(1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.isize)
|
||||||
|
|
|
@ -1918,6 +1918,12 @@ extern "rust-intrinsic" {
|
||||||
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
|
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
|
||||||
pub fn const_allocate(size: usize, align: usize) -> *mut u8;
|
pub fn const_allocate(size: usize, align: usize) -> *mut u8;
|
||||||
|
|
||||||
|
/// Deallocate a memory which allocated by `intrinsics::const_allocate` at compile time.
|
||||||
|
/// Should not be called at runtime.
|
||||||
|
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
pub fn const_deallocate(ptr: *mut u8, size: usize, align: usize);
|
||||||
|
|
||||||
/// Determines whether the raw bytes of the two values are equal.
|
/// Determines whether the raw bytes of the two values are equal.
|
||||||
///
|
///
|
||||||
/// This is particularly handy for arrays, since it allows things like just
|
/// This is particularly handy for arrays, since it allows things like just
|
||||||
|
|
12
src/test/ui/consts/const-eval/heap/dealloc_intrinsic.rs
Normal file
12
src/test/ui/consts/const-eval/heap/dealloc_intrinsic.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// run-pass
|
||||||
|
#![feature(core_intrinsics)]
|
||||||
|
#![feature(const_heap)]
|
||||||
|
|
||||||
|
use std::intrinsics;
|
||||||
|
|
||||||
|
const _X: () = unsafe {
|
||||||
|
let ptr = intrinsics::const_allocate(4, 4);
|
||||||
|
intrinsics::const_deallocate(ptr, 4, 4);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#![feature(core_intrinsics)]
|
||||||
|
#![feature(const_heap)]
|
||||||
|
#![feature(const_mut_refs)]
|
||||||
|
|
||||||
|
use std::intrinsics;
|
||||||
|
|
||||||
|
const _X: &'static u8 = unsafe {
|
||||||
|
let ptr = intrinsics::const_allocate(4, 4);
|
||||||
|
intrinsics::const_deallocate(ptr, 4, 4);
|
||||||
|
&*ptr
|
||||||
|
//~^ error: evaluation of constant value failed
|
||||||
|
};
|
||||||
|
|
||||||
|
const _Y: u8 = unsafe {
|
||||||
|
let ptr = intrinsics::const_allocate(4, 4);
|
||||||
|
let reference = &*ptr;
|
||||||
|
intrinsics::const_deallocate(ptr, 4, 4);
|
||||||
|
*reference
|
||||||
|
//~^ error: evaluation of constant value failed
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,15 @@
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/dealloc_intrinsic_dangling.rs:10:5
|
||||||
|
|
|
||||||
|
LL | &*ptr
|
||||||
|
| ^^^^^ pointer to alloc2 was dereferenced after this allocation got freed
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/dealloc_intrinsic_dangling.rs:18:5
|
||||||
|
|
|
||||||
|
LL | *reference
|
||||||
|
| ^^^^^^^^^^ pointer to alloc4 was dereferenced after this allocation got freed
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
|
@ -0,0 +1,13 @@
|
||||||
|
#![feature(core_intrinsics)]
|
||||||
|
#![feature(const_heap)]
|
||||||
|
|
||||||
|
use std::intrinsics;
|
||||||
|
|
||||||
|
const _X: () = unsafe {
|
||||||
|
let ptr = intrinsics::const_allocate(4, 4);
|
||||||
|
intrinsics::const_deallocate(ptr, 4, 4);
|
||||||
|
intrinsics::const_deallocate(ptr, 4, 4);
|
||||||
|
//~^ error: evaluation of constant value failed
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/dealloc_intrinsic_duplicate.rs:9:5
|
||||||
|
|
|
||||||
|
LL | intrinsics::const_deallocate(ptr, 4, 4);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer to alloc2 was dereferenced after this allocation got freed
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
|
@ -0,0 +1,29 @@
|
||||||
|
#![feature(core_intrinsics)]
|
||||||
|
#![feature(const_heap)]
|
||||||
|
|
||||||
|
use std::intrinsics;
|
||||||
|
|
||||||
|
const _X: () = unsafe {
|
||||||
|
let ptr = intrinsics::const_allocate(4, 4);
|
||||||
|
intrinsics::const_deallocate(ptr, 4, 2);
|
||||||
|
//~^ error: evaluation of constant value failed
|
||||||
|
};
|
||||||
|
const _Y: () = unsafe {
|
||||||
|
let ptr = intrinsics::const_allocate(4, 4);
|
||||||
|
intrinsics::const_deallocate(ptr, 2, 4);
|
||||||
|
//~^ error: evaluation of constant value failed
|
||||||
|
};
|
||||||
|
|
||||||
|
const _Z: () = unsafe {
|
||||||
|
let ptr = intrinsics::const_allocate(4, 4);
|
||||||
|
intrinsics::const_deallocate(ptr, 3, 4);
|
||||||
|
//~^ error: evaluation of constant value failed
|
||||||
|
};
|
||||||
|
|
||||||
|
const _W: () = unsafe {
|
||||||
|
let ptr = intrinsics::const_allocate(4, 4);
|
||||||
|
intrinsics::const_deallocate(ptr, 4, 3);
|
||||||
|
//~^ error: evaluation of constant value failed
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,27 @@
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/dealloc_intrinsic_incorrect_layout.rs:8:5
|
||||||
|
|
|
||||||
|
LL | intrinsics::const_deallocate(ptr, 4, 2);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: alloc2 has size 4 and alignment 4, but gave size 4 and alignment 2
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/dealloc_intrinsic_incorrect_layout.rs:13:5
|
||||||
|
|
|
||||||
|
LL | intrinsics::const_deallocate(ptr, 2, 4);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: alloc4 has size 4 and alignment 4, but gave size 2 and alignment 4
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/dealloc_intrinsic_incorrect_layout.rs:19:5
|
||||||
|
|
|
||||||
|
LL | intrinsics::const_deallocate(ptr, 3, 4);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: alloc6 has size 4 and alignment 4, but gave size 3 and alignment 4
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/dealloc_intrinsic_incorrect_layout.rs:25:5
|
||||||
|
|
|
||||||
|
LL | intrinsics::const_deallocate(ptr, 4, 3);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ align has to be a power of 2, `3` is not a power of 2
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
Loading…
Add table
Add a link
Reference in a new issue