Skip to content

Commit 6b327aa

Browse files
Check for ptr-to-int casts in const functions in THIR unsafeck
1 parent 592fecb commit 6b327aa

6 files changed

+105
-14
lines changed

compiler/rustc_mir_build/src/check_unsafety.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
2525
/// The `#[target_feature]` attributes of the body. Used for checking
2626
/// calls to functions with `#[target_feature]` (RFC 2396).
2727
body_target_features: &'tcx Vec<Symbol>,
28+
is_const: bool,
2829
}
2930

3031
impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
@@ -187,6 +188,16 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
187188
(Bound::Unbounded, Bound::Unbounded) => {}
188189
_ => self.requires_unsafe(expr.span, InitializingTypeWith),
189190
},
191+
ExprKind::Cast { source } => {
192+
let source = &self.thir[source];
193+
if self.tcx.features().const_raw_ptr_to_usize_cast
194+
&& self.is_const
195+
&& (source.ty.is_unsafe_ptr() || source.ty.is_fn_ptr())
196+
&& expr.ty.is_integral()
197+
{
198+
self.requires_unsafe(expr.span, CastOfPointerToInt);
199+
}
200+
}
190201
_ => {}
191202
}
192203

@@ -230,7 +241,6 @@ enum UnsafeOpKind {
230241
CallToUnsafeFunction,
231242
UseOfInlineAssembly,
232243
InitializingTypeWith,
233-
#[allow(dead_code)] // FIXME
234244
CastOfPointerToInt,
235245
#[allow(dead_code)] // FIXME
236246
UseOfMutableStatic,
@@ -331,13 +341,19 @@ pub fn check_unsafety<'tcx>(
331341
let body_target_features = &tcx.codegen_fn_attrs(def_id).target_features;
332342
let safety_context =
333343
if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
344+
let is_const = match tcx.hir().body_owner_kind(hir_id) {
345+
hir::BodyOwnerKind::Closure => false,
346+
hir::BodyOwnerKind::Fn => tcx.is_const_fn_raw(def_id.to_def_id()),
347+
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => true,
348+
};
334349
let mut visitor = UnsafetyVisitor {
335350
tcx,
336351
thir,
337352
safety_context,
338353
hir_context: hir_id,
339354
body_unsafety,
340355
body_target_features,
356+
is_const,
341357
};
342358
visitor.visit_expr(&thir[expr]);
343359
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0133]: cast of pointer to int is unsafe and requires unsafe function or block
2+
--> $DIR/cast-ptr-to-int-const.rs:10:9
3+
|
4+
LL | &Y as *const u32 as usize
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cast of pointer to int
6+
|
7+
= note: casting pointers to integers in constants
8+
9+
error[E0133]: cast of pointer to int is unsafe and requires unsafe function or block
10+
--> $DIR/cast-ptr-to-int-const.rs:17:5
11+
|
12+
LL | &0 as *const i32 as usize
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cast of pointer to int
14+
|
15+
= note: casting pointers to integers in constants
16+
17+
error: aborting due to 2 previous errors
18+
19+
For more information about this error, try `rustc --explain E0133`.
+7-13
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,19 @@
1-
// gate-test-const_raw_ptr_to_usize_cast
2-
// revisions: with_feature without_feature
1+
// revisions: mir thir
2+
// [thir]compile-flags: -Z thir-unsafeck
33

4-
#![cfg_attr(with_feature, feature(const_raw_ptr_to_usize_cast))]
4+
#![feature(const_raw_ptr_to_usize_cast)]
55

66
fn main() {
7-
const X: usize = unsafe {
8-
main as usize //[without_feature]~ ERROR casting pointers to integers in constants is unstable
9-
};
107
const Y: u32 = 0;
11-
const Z: usize = unsafe {
12-
&Y as *const u32 as usize //[without_feature]~ ERROR is unstable
13-
};
148
// Cast in `const` without `unsafe` block
159
const SAFE: usize = {
16-
&Y as *const u32 as usize //[without_feature]~ ERROR is unstable
17-
//[with_feature]~^ ERROR cast of pointer to int is unsafe and requires unsafe
10+
&Y as *const u32 as usize
11+
//~^ ERROR cast of pointer to int is unsafe and requires unsafe
1812
};
1913
}
2014

2115
// Cast in `const fn` without `unsafe` block
2216
const fn test() -> usize {
23-
&0 as *const i32 as usize //[without_feature]~ ERROR is unstable
24-
//[with_feature]~^ ERROR cast of pointer to int is unsafe and requires unsafe
17+
&0 as *const i32 as usize
18+
//~^ ERROR cast of pointer to int is unsafe and requires unsafe
2519
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0133]: cast of pointer to int is unsafe and requires unsafe function or block
2+
--> $DIR/cast-ptr-to-int-const.rs:10:9
3+
|
4+
LL | &Y as *const u32 as usize
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cast of pointer to int
6+
|
7+
= note: casting pointers to integers in constants
8+
9+
error[E0133]: cast of pointer to int is unsafe and requires unsafe function or block
10+
--> $DIR/cast-ptr-to-int-const.rs:17:5
11+
|
12+
LL | &0 as *const i32 as usize
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cast of pointer to int
14+
|
15+
= note: casting pointers to integers in constants
16+
17+
error: aborting due to 2 previous errors
18+
19+
For more information about this error, try `rustc --explain E0133`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
fn main() {
2+
const X: usize = unsafe {
3+
main as usize //~ ERROR casting pointers to integers in constants is unstable
4+
};
5+
const Y: u32 = 0;
6+
const Z: usize = unsafe {
7+
&Y as *const u32 as usize //~ ERROR is unstable
8+
};
9+
}
10+
11+
const fn test() -> usize {
12+
&0 as *const i32 as usize //~ ERROR is unstable
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error[E0658]: casting pointers to integers in constants is unstable
2+
--> $DIR/feature-gate-const_raw_ptr_to_usize_cast.rs:3:9
3+
|
4+
LL | main as usize
5+
| ^^^^^^^^^^^^^
6+
|
7+
= note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
8+
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
9+
10+
error[E0658]: casting pointers to integers in constants is unstable
11+
--> $DIR/feature-gate-const_raw_ptr_to_usize_cast.rs:7:9
12+
|
13+
LL | &Y as *const u32 as usize
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
15+
|
16+
= note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
17+
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
18+
19+
error[E0658]: casting pointers to integers in constant functions is unstable
20+
--> $DIR/feature-gate-const_raw_ptr_to_usize_cast.rs:12:5
21+
|
22+
LL | &0 as *const i32 as usize
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
24+
|
25+
= note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
26+
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
27+
28+
error: aborting due to 3 previous errors
29+
30+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)