Skip to content

Commit b75a512

Browse files
author
Ariel Ben-Yehuda
committed
Prevent comparison and dereferencing of raw pointers in constexprs
Fixes rust-lang#25826.
1 parent 47f9e52 commit b75a512

File tree

6 files changed

+75
-7
lines changed

6 files changed

+75
-7
lines changed

src/librustc/diagnostics.rs

+2
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,8 @@ register_diagnostics! {
892892
E0316, // nested quantification of lifetimes
893893
E0370, // discriminant overflow
894894
E0378, // method calls limited to constant inherent methods
895+
E0380, // pointer comparison in const-expr
896+
E0381, // pointer dereference in const-expr
895897
E0394 // cannot refer to other statics by value, use the address-of
896898
// operator or a constant instead
897899
}

src/librustc/middle/check_const.rs

+25-6
Original file line numberDiff line numberDiff line change
@@ -536,11 +536,32 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
536536
"allocations are not allowed in {}s", v.msg());
537537
}
538538
}
539-
ast::ExprUnary(ast::UnDeref, ref ptr) => {
540-
match ty::node_id_to_type(v.tcx, ptr.id).sty {
539+
ast::ExprUnary(op, ref inner) => {
540+
match ty::node_id_to_type(v.tcx, inner.id).sty {
541541
ty::ty_ptr(_) => {
542-
// This shouldn't be allowed in constants at all.
542+
assert!(op == ast::UnDeref);
543+
544+
v.add_qualif(ConstQualif::NOT_CONST);
545+
if v.mode != Mode::Var {
546+
span_err!(v.tcx.sess, e.span, E0381,
547+
"raw pointers cannot be dereferenced in {}s", v.msg());
548+
}
549+
}
550+
_ => {}
551+
}
552+
}
553+
ast::ExprBinary(op, ref lhs, _) => {
554+
match ty::node_id_to_type(v.tcx, lhs.id).sty {
555+
ty::ty_ptr(_) => {
556+
assert!(op.node == ast::BiEq || op.node == ast::BiNe ||
557+
op.node == ast::BiLe || op.node == ast::BiLt ||
558+
op.node == ast::BiGe || op.node == ast::BiGt);
559+
543560
v.add_qualif(ConstQualif::NOT_CONST);
561+
if v.mode != Mode::Var {
562+
span_err!(v.tcx.sess, e.span, E0380,
563+
"raw pointers cannot be compared in {}s", v.msg());
564+
}
544565
}
545566
_ => {}
546567
}
@@ -553,7 +574,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
553574
v.add_qualif(ConstQualif::NOT_CONST);
554575
if v.mode != Mode::Var {
555576
span_err!(v.tcx.sess, e.span, E0018,
556-
"can't cast a pointer to an integer in {}s", v.msg());
577+
"raw pointers cannot be cast to integers in {}s", v.msg());
557578
}
558579
}
559580
_ => {}
@@ -695,8 +716,6 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
695716
}
696717

697718
ast::ExprBlock(_) |
698-
ast::ExprUnary(..) |
699-
ast::ExprBinary(..) |
700719
ast::ExprIndex(..) |
701720
ast::ExprField(..) |
702721
ast::ExprTupField(..) |
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Check that you can't dereference raw pointers in constants.
12+
13+
fn main() {
14+
static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; //~ ERROR E0381
15+
println!("{}", C);
16+
}

src/test/compile-fail/issue-17458.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
static X: usize = 0 as *const usize as usize;
12-
//~^ ERROR: can't cast a pointer to an integer in statics
12+
//~^ ERROR: raw pointers cannot be cast to integers in statics
1313

1414
fn main() {
1515
assert_eq!(X, 0);

src/test/compile-fail/issue-25768.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
let y: *const str = "";
13+
y == y; //~ ERROR binary operation `==` cannot be applied
14+
y < y; //~ ERROR binary operation `<` cannot be applied
15+
}

src/test/compile-fail/issue-25826.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn id<T>(t: T) -> T { t }
12+
fn main() {
13+
const A: bool = id::<u8> as *const () < id::<u16> as *const ();
14+
//~^ ERROR E0380 raw pointers cannot be compared in constants
15+
println!("{}", A);
16+
}

0 commit comments

Comments
 (0)