Skip to content

Commit

Permalink
Check for ptr-to-int casts in const functions in THIR unsafeck
Browse files Browse the repository at this point in the history
  • Loading branch information
LeSeulArtichaut committed May 21, 2021
1 parent 592fecb commit 6b327aa
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 14 deletions.
18 changes: 17 additions & 1 deletion compiler/rustc_mir_build/src/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
/// The `#[target_feature]` attributes of the body. Used for checking
/// calls to functions with `#[target_feature]` (RFC 2396).
body_target_features: &'tcx Vec<Symbol>,
is_const: bool,
}

impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
Expand Down Expand Up @@ -187,6 +188,16 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
(Bound::Unbounded, Bound::Unbounded) => {}
_ => self.requires_unsafe(expr.span, InitializingTypeWith),
},
ExprKind::Cast { source } => {
let source = &self.thir[source];
if self.tcx.features().const_raw_ptr_to_usize_cast
&& self.is_const
&& (source.ty.is_unsafe_ptr() || source.ty.is_fn_ptr())
&& expr.ty.is_integral()
{
self.requires_unsafe(expr.span, CastOfPointerToInt);
}
}
_ => {}
}

Expand Down Expand Up @@ -230,7 +241,6 @@ enum UnsafeOpKind {
CallToUnsafeFunction,
UseOfInlineAssembly,
InitializingTypeWith,
#[allow(dead_code)] // FIXME
CastOfPointerToInt,
#[allow(dead_code)] // FIXME
UseOfMutableStatic,
Expand Down Expand Up @@ -331,13 +341,19 @@ pub fn check_unsafety<'tcx>(
let body_target_features = &tcx.codegen_fn_attrs(def_id).target_features;
let safety_context =
if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
let is_const = match tcx.hir().body_owner_kind(hir_id) {
hir::BodyOwnerKind::Closure => false,
hir::BodyOwnerKind::Fn => tcx.is_const_fn_raw(def_id.to_def_id()),
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => true,
};
let mut visitor = UnsafetyVisitor {
tcx,
thir,
safety_context,
hir_context: hir_id,
body_unsafety,
body_target_features,
is_const,
};
visitor.visit_expr(&thir[expr]);
}
Expand Down
19 changes: 19 additions & 0 deletions src/test/ui/cast/cast-ptr-to-int-const.mir.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error[E0133]: cast of pointer to int is unsafe and requires unsafe function or block
--> $DIR/cast-ptr-to-int-const.rs:10:9
|
LL | &Y as *const u32 as usize
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cast of pointer to int
|
= note: casting pointers to integers in constants

error[E0133]: cast of pointer to int is unsafe and requires unsafe function or block
--> $DIR/cast-ptr-to-int-const.rs:17:5
|
LL | &0 as *const i32 as usize
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cast of pointer to int
|
= note: casting pointers to integers in constants

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0133`.
20 changes: 7 additions & 13 deletions src/test/ui/cast/cast-ptr-to-int-const.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
// gate-test-const_raw_ptr_to_usize_cast
// revisions: with_feature without_feature
// revisions: mir thir
// [thir]compile-flags: -Z thir-unsafeck

#![cfg_attr(with_feature, feature(const_raw_ptr_to_usize_cast))]
#![feature(const_raw_ptr_to_usize_cast)]

fn main() {
const X: usize = unsafe {
main as usize //[without_feature]~ ERROR casting pointers to integers in constants is unstable
};
const Y: u32 = 0;
const Z: usize = unsafe {
&Y as *const u32 as usize //[without_feature]~ ERROR is unstable
};
// Cast in `const` without `unsafe` block
const SAFE: usize = {
&Y as *const u32 as usize //[without_feature]~ ERROR is unstable
//[with_feature]~^ ERROR cast of pointer to int is unsafe and requires unsafe
&Y as *const u32 as usize
//~^ ERROR cast of pointer to int is unsafe and requires unsafe
};
}

// Cast in `const fn` without `unsafe` block
const fn test() -> usize {
&0 as *const i32 as usize //[without_feature]~ ERROR is unstable
//[with_feature]~^ ERROR cast of pointer to int is unsafe and requires unsafe
&0 as *const i32 as usize
//~^ ERROR cast of pointer to int is unsafe and requires unsafe
}
19 changes: 19 additions & 0 deletions src/test/ui/cast/cast-ptr-to-int-const.thir.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error[E0133]: cast of pointer to int is unsafe and requires unsafe function or block
--> $DIR/cast-ptr-to-int-const.rs:10:9
|
LL | &Y as *const u32 as usize
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cast of pointer to int
|
= note: casting pointers to integers in constants

error[E0133]: cast of pointer to int is unsafe and requires unsafe function or block
--> $DIR/cast-ptr-to-int-const.rs:17:5
|
LL | &0 as *const i32 as usize
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cast of pointer to int
|
= note: casting pointers to integers in constants

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0133`.
13 changes: 13 additions & 0 deletions src/test/ui/cast/feature-gate-const_raw_ptr_to_usize_cast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
fn main() {
const X: usize = unsafe {
main as usize //~ ERROR casting pointers to integers in constants is unstable
};
const Y: u32 = 0;
const Z: usize = unsafe {
&Y as *const u32 as usize //~ ERROR is unstable
};
}

const fn test() -> usize {
&0 as *const i32 as usize //~ ERROR is unstable
}
30 changes: 30 additions & 0 deletions src/test/ui/cast/feature-gate-const_raw_ptr_to_usize_cast.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
error[E0658]: casting pointers to integers in constants is unstable
--> $DIR/feature-gate-const_raw_ptr_to_usize_cast.rs:3:9
|
LL | main as usize
| ^^^^^^^^^^^^^
|
= note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable

error[E0658]: casting pointers to integers in constants is unstable
--> $DIR/feature-gate-const_raw_ptr_to_usize_cast.rs:7:9
|
LL | &Y as *const u32 as usize
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable

error[E0658]: casting pointers to integers in constant functions is unstable
--> $DIR/feature-gate-const_raw_ptr_to_usize_cast.rs:12:5
|
LL | &0 as *const i32 as usize
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable

error: aborting due to 3 previous errors

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

0 comments on commit 6b327aa

Please sign in to comment.