Skip to content

Commit e2c01ca

Browse files
committed
const-eval: error when encountering references to functions / vtables
1 parent d2e8ecd commit e2c01ca

File tree

6 files changed

+47
-4
lines changed

6 files changed

+47
-4
lines changed

compiler/rustc_const_eval/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,8 +464,10 @@ const_eval_validation_out_of_range = {$front_matter}: encountered {$value}, but
464464
const_eval_validation_partial_pointer = {$front_matter}: encountered a partial pointer or a mix of pointers
465465
const_eval_validation_pointer_as_int = {$front_matter}: encountered a pointer, but {$expected}
466466
const_eval_validation_ptr_out_of_range = {$front_matter}: encountered a pointer, but expected something that cannot possibly fail to be {$in_range}
467+
const_eval_validation_ref_to_function = {$front_matter}: encountered a reference pointing to a function
467468
const_eval_validation_ref_to_static = {$front_matter}: encountered a reference pointing to a static variable in a constant
468469
const_eval_validation_ref_to_uninhabited = {$front_matter}: encountered a reference pointing to uninhabited type {$ty}
470+
const_eval_validation_ref_to_vtable = {$front_matter}: encountered a reference pointing to a vtable
469471
const_eval_validation_unaligned_box = {$front_matter}: encountered an unaligned box (required {$required_bytes} byte alignment but found {$found_bytes})
470472
const_eval_validation_unaligned_ref = {$front_matter}: encountered an unaligned reference (required {$required_bytes} byte alignment but found {$found_bytes})
471473
const_eval_validation_uninhabited_enum_variant = {$front_matter}: encountered an uninhabited enum variant

compiler/rustc_const_eval/src/errors.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,8 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
614614
PartialPointer => const_eval_validation_partial_pointer,
615615
ConstRefToMutable => const_eval_validation_const_ref_to_mutable,
616616
ConstRefToExtern => const_eval_validation_const_ref_to_extern,
617+
RefToFunction => const_eval_validation_ref_to_function,
618+
RefToVtable => const_eval_validation_ref_to_vtable,
617619
MutableRefInConstOrStatic => const_eval_validation_mutable_ref_in_const_or_static,
618620
MutableRefToImmutable => const_eval_validation_mutable_ref_to_immutable,
619621
NullFnPtr => const_eval_validation_null_fn_ptr,
@@ -771,6 +773,8 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
771773
| MutableRefInConstOrStatic
772774
| ConstRefToMutable
773775
| ConstRefToExtern
776+
| RefToFunction
777+
| RefToVtable
774778
| MutableRefToImmutable
775779
| NullFnPtr
776780
| NeverVal

compiler/rustc_const_eval/src/interpret/validity.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -502,9 +502,11 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
502502
if is_mut { Mutability::Mut } else { Mutability::Not }
503503
}
504504
GlobalAlloc::Memory(alloc) => alloc.inner().mutability,
505-
GlobalAlloc::Function(..) | GlobalAlloc::VTable(..) => {
506-
// These are immutable, we better don't allow mutable pointers here.
507-
Mutability::Not
505+
GlobalAlloc::Function(..) => {
506+
throw_validation_failure!(self.path, RefToFunction);
507+
}
508+
GlobalAlloc::VTable(..) => {
509+
throw_validation_failure!(self.path, RefToVtable);
508510
}
509511
};
510512
// Mutability check.

compiler/rustc_middle/src/mir/interpret/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,8 @@ pub enum ValidationErrorKind<'tcx> {
425425
ConstRefToExtern,
426426
MutableRefToImmutable,
427427
UnsafeCellInImmutable,
428+
RefToFunction,
429+
RefToVtable,
428430
NullFnPtr,
429431
NeverVal,
430432
NullablePtrOutOfRange { range: WrappingRange, max_value: u128 },

tests/ui/consts/const-eval/ub-ref-ptr.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,16 @@ const UNALIGNED_READ: () = unsafe {
6666
ptr.read(); //~ inside `UNALIGNED_READ`
6767
};
6868

69+
const POINTS_TO_FUNCTION: &() = unsafe {
70+
//~^ ERROR it is undefined behavior to use this value
71+
//~| function
72+
mem::transmute(main as fn())
73+
};
74+
const POINTS_TO_VTABLE: (&(), &()) = unsafe {
75+
//~^ ERROR it is undefined behavior to use this value
76+
//~| vtable
77+
mem::transmute(&() as &dyn Send)
78+
};
79+
6980

7081
fn main() {}

tests/ui/consts/const-eval/ub-ref-ptr.stderr

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,28 @@ note: inside `UNALIGNED_READ`
163163
LL | ptr.read();
164164
| ^^^^^^^^^^
165165

166-
error: aborting due to 15 previous errors
166+
error[E0080]: it is undefined behavior to use this value
167+
--> $DIR/ub-ref-ptr.rs:69:1
168+
|
169+
LL | const POINTS_TO_FUNCTION: &() = unsafe {
170+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a function
171+
|
172+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
173+
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
174+
HEX_DUMP
175+
}
176+
177+
error[E0080]: it is undefined behavior to use this value
178+
--> $DIR/ub-ref-ptr.rs:74:1
179+
|
180+
LL | const POINTS_TO_VTABLE: (&(), &()) = unsafe {
181+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .1: encountered a reference pointing to a vtable
182+
|
183+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
184+
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
185+
HEX_DUMP
186+
}
187+
188+
error: aborting due to 17 previous errors
167189

168190
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)