Skip to content

Commit aa6795e

Browse files
committed
Add intrinsics::const_deallocate
1 parent 10c4c4a commit aa6795e

File tree

11 files changed

+156
-0
lines changed

11 files changed

+156
-0
lines changed

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,23 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
347347
)?;
348348
ecx.write_pointer(ptr, dest)?;
349349
}
350+
sym::const_deallocate => {
351+
let ptr = ecx.read_pointer(&args[0])?;
352+
let size = ecx.read_scalar(&args[1])?.to_machine_usize(ecx)?;
353+
let align = ecx.read_scalar(&args[2])?.to_machine_usize(ecx)?;
354+
355+
let size = Size::from_bytes(size);
356+
let align = match Align::from_bytes(align) {
357+
Ok(a) => a,
358+
Err(err) => throw_ub_format!("align has to be a power of 2, {}", err),
359+
};
360+
361+
ecx.memory.deallocate(
362+
ptr,
363+
Some((size, align)),
364+
interpret::MemoryKind::Machine(MemoryKind::Heap),
365+
)?;
366+
}
350367
_ => {
351368
return Err(ConstEvalErrKind::NeedsRfc(format!(
352369
"calling intrinsic `{}`",

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ symbols! {
460460
const_async_blocks,
461461
const_compare_raw_pointers,
462462
const_constructor,
463+
const_deallocate,
463464
const_eval_limit,
464465
const_eval_select,
465466
const_eval_select_ct,

compiler/rustc_typeck/src/check/intrinsic.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,11 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
297297
sym::const_allocate => {
298298
(0, vec![tcx.types.usize, tcx.types.usize], tcx.mk_mut_ptr(tcx.types.u8))
299299
}
300+
sym::const_deallocate => (
301+
0,
302+
vec![tcx.mk_mut_ptr(tcx.types.u8), tcx.types.usize, tcx.types.usize],
303+
tcx.mk_unit(),
304+
),
300305

301306
sym::ptr_offset_from => {
302307
(1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.isize)

library/core/src/intrinsics.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,6 +1918,12 @@ extern "rust-intrinsic" {
19181918
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
19191919
pub fn const_allocate(size: usize, align: usize) -> *mut u8;
19201920

1921+
/// Deallocate a memory which allocated by `intrinsics::const_allocate` at compile time.
1922+
/// Should not be called at runtime.
1923+
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
1924+
#[cfg(not(bootstrap))]
1925+
pub fn const_deallocate(ptr: *mut u8, size: usize, align: usize);
1926+
19211927
/// Determines whether the raw bytes of the two values are equal.
19221928
///
19231929
/// This is particularly handy for arrays, since it allows things like just
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// run-pass
2+
#![feature(core_intrinsics)]
3+
#![feature(const_heap)]
4+
5+
use std::intrinsics;
6+
7+
const _X: () = unsafe {
8+
let ptr = intrinsics::const_allocate(4, 4);
9+
intrinsics::const_deallocate(ptr, 4, 4);
10+
};
11+
12+
fn main() {}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#![feature(core_intrinsics)]
2+
#![feature(const_heap)]
3+
#![feature(const_mut_refs)]
4+
5+
use std::intrinsics;
6+
7+
const _X: &'static u8 = unsafe {
8+
let ptr = intrinsics::const_allocate(4, 4);
9+
intrinsics::const_deallocate(ptr, 4, 4);
10+
&*ptr
11+
//~^ error: evaluation of constant value failed
12+
};
13+
14+
const _Y: u8 = unsafe {
15+
let ptr = intrinsics::const_allocate(4, 4);
16+
let reference = &*ptr;
17+
intrinsics::const_deallocate(ptr, 4, 4);
18+
*reference
19+
//~^ error: evaluation of constant value failed
20+
};
21+
22+
fn main() {}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/dealloc_intrinsic_dangling.rs:10:5
3+
|
4+
LL | &*ptr
5+
| ^^^^^ pointer to alloc2 was dereferenced after this allocation got freed
6+
7+
error[E0080]: evaluation of constant value failed
8+
--> $DIR/dealloc_intrinsic_dangling.rs:18:5
9+
|
10+
LL | *reference
11+
| ^^^^^^^^^^ pointer to alloc4 was dereferenced after this allocation got freed
12+
13+
error: aborting due to 2 previous errors
14+
15+
For more information about this error, try `rustc --explain E0080`.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(core_intrinsics)]
2+
#![feature(const_heap)]
3+
4+
use std::intrinsics;
5+
6+
const _X: () = unsafe {
7+
let ptr = intrinsics::const_allocate(4, 4);
8+
intrinsics::const_deallocate(ptr, 4, 4);
9+
intrinsics::const_deallocate(ptr, 4, 4);
10+
//~^ error: evaluation of constant value failed
11+
};
12+
13+
fn main() {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/dealloc_intrinsic_duplicate.rs:9:5
3+
|
4+
LL | intrinsics::const_deallocate(ptr, 4, 4);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer to alloc2 was dereferenced after this allocation got freed
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0080`.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#![feature(core_intrinsics)]
2+
#![feature(const_heap)]
3+
4+
use std::intrinsics;
5+
6+
const _X: () = unsafe {
7+
let ptr = intrinsics::const_allocate(4, 4);
8+
intrinsics::const_deallocate(ptr, 4, 2);
9+
//~^ error: evaluation of constant value failed
10+
};
11+
const _Y: () = unsafe {
12+
let ptr = intrinsics::const_allocate(4, 4);
13+
intrinsics::const_deallocate(ptr, 2, 4);
14+
//~^ error: evaluation of constant value failed
15+
};
16+
17+
const _Z: () = unsafe {
18+
let ptr = intrinsics::const_allocate(4, 4);
19+
intrinsics::const_deallocate(ptr, 3, 4);
20+
//~^ error: evaluation of constant value failed
21+
};
22+
23+
const _W: () = unsafe {
24+
let ptr = intrinsics::const_allocate(4, 4);
25+
intrinsics::const_deallocate(ptr, 4, 3);
26+
//~^ error: evaluation of constant value failed
27+
};
28+
29+
fn main() {}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/dealloc_intrinsic_incorrect_layout.rs:8:5
3+
|
4+
LL | intrinsics::const_deallocate(ptr, 4, 2);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: alloc2 has size 4 and alignment 4, but gave size 4 and alignment 2
6+
7+
error[E0080]: evaluation of constant value failed
8+
--> $DIR/dealloc_intrinsic_incorrect_layout.rs:13:5
9+
|
10+
LL | intrinsics::const_deallocate(ptr, 2, 4);
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: alloc4 has size 4 and alignment 4, but gave size 2 and alignment 4
12+
13+
error[E0080]: evaluation of constant value failed
14+
--> $DIR/dealloc_intrinsic_incorrect_layout.rs:19:5
15+
|
16+
LL | intrinsics::const_deallocate(ptr, 3, 4);
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: alloc6 has size 4 and alignment 4, but gave size 3 and alignment 4
18+
19+
error[E0080]: evaluation of constant value failed
20+
--> $DIR/dealloc_intrinsic_incorrect_layout.rs:25:5
21+
|
22+
LL | intrinsics::const_deallocate(ptr, 4, 3);
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ align has to be a power of 2, `3` is not a power of 2
24+
25+
error: aborting due to 4 previous errors
26+
27+
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)