]> git.lizzy.rs Git - rust.git/commitdiff
Prevent comparison and dereferencing of raw pointers in constexprs
authorAriel Ben-Yehuda <arielb1@mail.tau.ac.il>
Wed, 27 May 2015 21:35:56 +0000 (00:35 +0300)
committerAriel Ben-Yehuda <arielb1@mail.tau.ac.il>
Thu, 28 May 2015 00:22:44 +0000 (03:22 +0300)
Fixes #25826.

src/librustc/diagnostics.rs
src/librustc/middle/check_const.rs
src/test/compile-fail/const-deref-ptr.rs [new file with mode: 0644]
src/test/compile-fail/issue-17458.rs
src/test/compile-fail/issue-25826.rs [new file with mode: 0644]

index 9d459027bf5cdfa7360281ceb1c78337ea0b74e9..d1e7084150eb34b450614cb036e4512bd69e986c 100644 (file)
@@ -892,6 +892,8 @@ struct Foo<T: 'static> {
     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
 }
index c54517e00173b21f7fccd46c9b7b7f68139d4ede..3e084f3eeb3051aea5c57abef3cc6c66fdd2a785 100644 (file)
@@ -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 (file)
index 0000000..fa15f3e
--- /dev/null
@@ -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);
+}
index a3a9e17cb3c0676592539fbc1fd525f5f269deb8..f5b7a0c13b7287fb26616b3df28c39b89fe7ed13 100644 (file)
@@ -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 (file)
index 0000000..00e1279
--- /dev/null
@@ -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);
+}