about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/diagnostics.rs4
-rw-r--r--src/librustc/middle/check_const.rs31
-rw-r--r--src/test/compile-fail/const-deref-ptr.rs16
-rw-r--r--src/test/compile-fail/issue-17458.rs2
-rw-r--r--src/test/compile-fail/issue-25826.rs16
5 files changed, 61 insertions, 8 deletions
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index 9d459027bf5..d1e7084150e 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -892,6 +892,8 @@ register_diagnostics! {
     E0316, // nested quantification of lifetimes
     E0370, // discriminant overflow
     E0378, // method calls limited to constant inherent methods
-    E0394  // cannot refer to other statics by value, use the address-of
+    E0394, // cannot refer to other statics by value, use the address-of
            // operator or a constant instead
+    E0395, // pointer comparison in const-expr
+    E0396  // pointer dereference in const-expr
 }
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index c54517e0017..3e084f3eeb3 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -536,11 +536,32 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                           "allocations are not allowed in {}s", v.msg());
             }
         }
-        ast::ExprUnary(ast::UnDeref, ref ptr) => {
-            match ty::node_id_to_type(v.tcx, ptr.id).sty {
+        ast::ExprUnary(op, ref inner) => {
+            match ty::node_id_to_type(v.tcx, inner.id).sty {
                 ty::ty_ptr(_) => {
-                    // This shouldn't be allowed in constants at all.
+                    assert!(op == ast::UnDeref);
+
+                    v.add_qualif(ConstQualif::NOT_CONST);
+                    if v.mode != Mode::Var {
+                        span_err!(v.tcx.sess, e.span, E0396,
+                                  "raw pointers cannot be dereferenced in {}s", v.msg());
+                    }
+                }
+                _ => {}
+            }
+        }
+        ast::ExprBinary(op, ref lhs, _) => {
+            match ty::node_id_to_type(v.tcx, lhs.id).sty {
+                ty::ty_ptr(_) => {
+                    assert!(op.node == ast::BiEq || op.node == ast::BiNe ||
+                            op.node == ast::BiLe || op.node == ast::BiLt ||
+                            op.node == ast::BiGe || op.node == ast::BiGt);
+
                     v.add_qualif(ConstQualif::NOT_CONST);
+                    if v.mode != Mode::Var {
+                        span_err!(v.tcx.sess, e.span, E0395,
+                                  "raw pointers cannot be compared in {}s", v.msg());
+                    }
                 }
                 _ => {}
             }
@@ -553,7 +574,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                     v.add_qualif(ConstQualif::NOT_CONST);
                     if v.mode != Mode::Var {
                         span_err!(v.tcx.sess, e.span, E0018,
-                                  "can't cast a pointer to an integer in {}s", v.msg());
+                                  "raw pointers cannot be cast to integers in {}s", v.msg());
                     }
                 }
                 _ => {}
@@ -695,8 +716,6 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
         }
 
         ast::ExprBlock(_) |
-        ast::ExprUnary(..) |
-        ast::ExprBinary(..) |
         ast::ExprIndex(..) |
         ast::ExprField(..) |
         ast::ExprTupField(..) |
diff --git a/src/test/compile-fail/const-deref-ptr.rs b/src/test/compile-fail/const-deref-ptr.rs
new file mode 100644
index 00000000000..fa15f3e87c6
--- /dev/null
+++ b/src/test/compile-fail/const-deref-ptr.rs
@@ -0,0 +1,16 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Check that you can't dereference raw pointers in constants.
+
+fn main() {
+    static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; //~ ERROR E0396
+    println!("{}", C);
+}
diff --git a/src/test/compile-fail/issue-17458.rs b/src/test/compile-fail/issue-17458.rs
index a3a9e17cb3c..f5b7a0c13b7 100644
--- a/src/test/compile-fail/issue-17458.rs
+++ b/src/test/compile-fail/issue-17458.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 static X: usize = 0 as *const usize as usize;
-//~^ ERROR: can't cast a pointer to an integer in statics
+//~^ ERROR: raw pointers cannot be cast to integers in statics
 
 fn main() {
     assert_eq!(X, 0);
diff --git a/src/test/compile-fail/issue-25826.rs b/src/test/compile-fail/issue-25826.rs
new file mode 100644
index 00000000000..00e1279d58a
--- /dev/null
+++ b/src/test/compile-fail/issue-25826.rs
@@ -0,0 +1,16 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn id<T>(t: T) -> T { t }
+fn main() {
+    const A: bool = id::<u8> as *const () < id::<u16> as *const ();
+    //~^ ERROR raw pointers cannot be compared in constants [E0395]
+    println!("{}", A);
+}