about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeSeulArtichaut <leseulartichaut@gmail.com>2021-05-15 16:29:57 +0200
committerLeSeulArtichaut <leseulartichaut@gmail.com>2021-05-21 18:31:44 +0200
commit6b327aaa08aea817e51640585b4d63cf4017965f (patch)
tree37a87fbaaa68c67a4f02968a1af8c0275ddfd3cf
parent592fecbafb9c2fe7f793bdb0529fcb25032bda6e (diff)
downloadrust-6b327aaa08aea817e51640585b4d63cf4017965f.tar.gz
rust-6b327aaa08aea817e51640585b4d63cf4017965f.zip
Check for ptr-to-int casts in const functions in THIR unsafeck
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs18
-rw-r--r--src/test/ui/cast/cast-ptr-to-int-const.mir.stderr19
-rw-r--r--src/test/ui/cast/cast-ptr-to-int-const.rs20
-rw-r--r--src/test/ui/cast/cast-ptr-to-int-const.thir.stderr19
-rw-r--r--src/test/ui/cast/feature-gate-const_raw_ptr_to_usize_cast.rs13
-rw-r--r--src/test/ui/cast/feature-gate-const_raw_ptr_to_usize_cast.stderr30
6 files changed, 105 insertions, 14 deletions
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 2eae6ec9e3b..66b30679ccb 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<Symbol>,
+    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 00000000000..dcc9a243f0f
--- /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 aed099a53ea..01ea627679d 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 00000000000..dcc9a243f0f
--- /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 00000000000..03e99eb7527
--- /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 00000000000..4a0b424e181
--- /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 <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`.