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)?;
|
||||
}
|
||||
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!(
|
||||
"calling intrinsic `{}`",
|
||||
|
|
|
@ -460,6 +460,7 @@ symbols! {
|
|||
const_async_blocks,
|
||||
const_compare_raw_pointers,
|
||||
const_constructor,
|
||||
const_deallocate,
|
||||
const_eval_limit,
|
||||
const_eval_select,
|
||||
const_eval_select_ct,
|
||||
|
|
|
@ -297,6 +297,11 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
|||
sym::const_allocate => {
|
||||
(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 => {
|
||||
(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")]
|
||||
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.
|
||||
///
|
||||
/// 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
Reference in a new issue