From 6b327aaa08aea817e51640585b4d63cf4017965f Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sat, 15 May 2021 16:29:57 +0200 Subject: [PATCH] Check for ptr-to-int casts in const functions in THIR unsafeck --- .../rustc_mir_build/src/check_unsafety.rs | 18 ++++++++++- .../ui/cast/cast-ptr-to-int-const.mir.stderr | 19 ++++++++++++ src/test/ui/cast/cast-ptr-to-int-const.rs | 20 +++++-------- .../ui/cast/cast-ptr-to-int-const.thir.stderr | 19 ++++++++++++ ...eature-gate-const_raw_ptr_to_usize_cast.rs | 13 ++++++++ ...re-gate-const_raw_ptr_to_usize_cast.stderr | 30 +++++++++++++++++++ 6 files changed, 105 insertions(+), 14 deletions(-) create mode 100644 src/test/ui/cast/cast-ptr-to-int-const.mir.stderr create mode 100644 src/test/ui/cast/cast-ptr-to-int-const.thir.stderr create mode 100644 src/test/ui/cast/feature-gate-const_raw_ptr_to_usize_cast.rs create mode 100644 src/test/ui/cast/feature-gate-const_raw_ptr_to_usize_cast.stderr diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 2eae6ec9e3bcd..66b30679ccb98 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -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, + is_const: bool, } impl<'tcx> UnsafetyVisitor<'_, 'tcx> { @@ -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); + } + } _ => {} } @@ -230,7 +241,6 @@ enum UnsafeOpKind { CallToUnsafeFunction, UseOfInlineAssembly, InitializingTypeWith, - #[allow(dead_code)] // FIXME CastOfPointerToInt, #[allow(dead_code)] // FIXME UseOfMutableStatic, @@ -331,6 +341,11 @@ 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, @@ -338,6 +353,7 @@ pub fn check_unsafety<'tcx>( hir_context: hir_id, body_unsafety, body_target_features, + is_const, }; visitor.visit_expr(&thir[expr]); } diff --git a/src/test/ui/cast/cast-ptr-to-int-const.mir.stderr b/src/test/ui/cast/cast-ptr-to-int-const.mir.stderr new file mode 100644 index 0000000000000..dcc9a243f0f39 --- /dev/null +++ b/src/test/ui/cast/cast-ptr-to-int-const.mir.stderr @@ -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`. diff --git a/src/test/ui/cast/cast-ptr-to-int-const.rs b/src/test/ui/cast/cast-ptr-to-int-const.rs index aed099a53eaf4..01ea627679d13 100644 --- a/src/test/ui/cast/cast-ptr-to-int-const.rs +++ b/src/test/ui/cast/cast-ptr-to-int-const.rs @@ -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 } diff --git a/src/test/ui/cast/cast-ptr-to-int-const.thir.stderr b/src/test/ui/cast/cast-ptr-to-int-const.thir.stderr new file mode 100644 index 0000000000000..dcc9a243f0f39 --- /dev/null +++ b/src/test/ui/cast/cast-ptr-to-int-const.thir.stderr @@ -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`. diff --git a/src/test/ui/cast/feature-gate-const_raw_ptr_to_usize_cast.rs b/src/test/ui/cast/feature-gate-const_raw_ptr_to_usize_cast.rs new file mode 100644 index 0000000000000..03e99eb752740 --- /dev/null +++ b/src/test/ui/cast/feature-gate-const_raw_ptr_to_usize_cast.rs @@ -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 +} diff --git a/src/test/ui/cast/feature-gate-const_raw_ptr_to_usize_cast.stderr b/src/test/ui/cast/feature-gate-const_raw_ptr_to_usize_cast.stderr new file mode 100644 index 0000000000000..4a0b424e1816b --- /dev/null +++ b/src/test/ui/cast/feature-gate-const_raw_ptr_to_usize_cast.stderr @@ -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 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 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 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`.