]> git.lizzy.rs Git - rust.git/commitdiff
Make sure the feature gate actually works and never allows promoting these operations
authorOliver Schneider <github35764891676564198441@oli-obk.de>
Fri, 3 Aug 2018 11:27:35 +0000 (13:27 +0200)
committerOliver Schneider <github35764891676564198441@oli-obk.de>
Tue, 7 Aug 2018 12:41:33 +0000 (14:41 +0200)
src/librustc_mir/transform/qualify_consts.rs
src/test/ui/const-eval/const_raw_ptr_ops.rs [new file with mode: 0644]
src/test/ui/const-eval/const_raw_ptr_ops.stderr [new file with mode: 0644]
src/test/ui/const-eval/promoted_raw_ptr_ops.rs [new file with mode: 0644]
src/test/ui/const-eval/promoted_raw_ptr_ops.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0395.stderr

index 1a66a1751ffa0cede1dfa89ca0bc1e0b4ff6931b..d876ee77e76cf7ccbdf5c0a20d0e778a05895bbb 100644 (file)
@@ -491,20 +491,21 @@ fn visit_place(&mut self,
                     this.super_place(place, context, location);
                     match proj.elem {
                         ProjectionElem::Deref => {
-                            this.add(Qualif::NOT_CONST);
-
-                            let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx);
-                            if let ty::TyRawPtr(_) = base_ty.sty {
-                                if this.mode != Mode::Fn &&
-                                   !this.tcx.sess.features_untracked().const_raw_ptr_deref {
-                                    emit_feature_err(
-                                        &this.tcx.sess.parse_sess, "const_raw_ptr_deref",
-                                        this.span, GateIssue::Language,
-                                        &format!(
-                                            "dereferencing raw pointers in {}s is unstable",
-                                            this.mode,
-                                        ),
-                                    );
+                            if let Mode::Fn = this.mode {
+                                this.add(Qualif::NOT_CONST);
+                            } else {
+                                let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx);
+                                if let ty::TyRawPtr(_) = base_ty.sty {
+                                    if !this.tcx.sess.features_untracked().const_raw_ptr_deref {
+                                        emit_feature_err(
+                                            &this.tcx.sess.parse_sess, "const_raw_ptr_deref",
+                                            this.span, GateIssue::Language,
+                                            &format!(
+                                                "dereferencing raw pointers in {}s is unstable",
+                                                this.mode,
+                                            ),
+                                        );
+                                    }
                                 }
                             }
                         }
@@ -726,9 +727,9 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
                 match (cast_in, cast_out) {
                     (CastTy::Ptr(_), CastTy::Int(_)) |
                     (CastTy::FnPtr, CastTy::Int(_)) => {
-                        self.add(Qualif::NOT_CONST);
-                        if self.mode != Mode::Fn &&
-                           !self.tcx.sess.features_untracked().const_raw_ptr_to_usize_cast {
+                        if let Mode::Fn = self.mode {
+                            self.add(Qualif::NOT_CONST);
+                        } else if !self.tcx.sess.features_untracked().const_raw_ptr_to_usize_cast {
                             emit_feature_err(
                                 &self.tcx.sess.parse_sess, "const_raw_ptr_to_usize_cast",
                                 self.span, GateIssue::Language,
@@ -750,8 +751,9 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
                             op == BinOp::Ge || op == BinOp::Gt ||
                             op == BinOp::Offset);
 
-                    self.add(Qualif::NOT_CONST);
-                    if self.mode != Mode::Fn {
+                    if let Mode::Fn = self.mode {
+                        self.add(Qualif::NOT_CONST);
+                    } else if !self.tcx.sess.features_untracked().const_compare_raw_pointers {
                         emit_feature_err(
                             &self.tcx.sess.parse_sess,
                             "const_compare_raw_pointers",
diff --git a/src/test/ui/const-eval/const_raw_ptr_ops.rs b/src/test/ui/const-eval/const_raw_ptr_ops.rs
new file mode 100644 (file)
index 0000000..9121c67
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2018 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.
+
+#![feature(const_raw_ptr_to_usize_cast, const_compare_raw_pointers, const_raw_ptr_deref)]
+
+fn main() {}
+
+// unconst and bad, will thus error in miri
+const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR cannot be used
+// unconst and fine
+const X2: bool = 42 as *const i32 == 43 as *const i32;
+// unconst and fine
+const Y: usize = 42usize as *const i32 as usize + 1;
+// unconst and bad, will thus error in miri
+const Y2: usize = &1 as *const i32 as usize + 1; //~ ERROR cannot be used
+// unconst and fine
+const Z: i32 = unsafe { *(&1 as *const i32) };
+// unconst and bad, will thus error in miri
+const Z2: i32 = unsafe { *(42 as *const i32) }; //~ ERROR cannot be used
+const Z3: i32 = unsafe { *(44 as *const i32) }; //~ ERROR cannot be used
\ No newline at end of file
diff --git a/src/test/ui/const-eval/const_raw_ptr_ops.stderr b/src/test/ui/const-eval/const_raw_ptr_ops.stderr
new file mode 100644 (file)
index 0000000..a9442be
--- /dev/null
@@ -0,0 +1,36 @@
+error: this constant cannot be used
+  --> $DIR/const_raw_ptr_ops.rs:16:1
+   |
+LL | const X: bool = &1 as *const i32 == &2 as *const i32; //~ ERROR cannot be used
+   | ^^^^^^^^^^^^^^^^------------------------------------^
+   |                 |
+   |                 "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
+   |
+   = note: #[deny(const_err)] on by default
+
+error: this constant cannot be used
+  --> $DIR/const_raw_ptr_ops.rs:22:1
+   |
+LL | const Y2: usize = &1 as *const i32 as usize + 1; //~ ERROR cannot be used
+   | ^^^^^^^^^^^^^^^^^^-----------------------------^
+   |                   |
+   |                   "pointer arithmetic or comparison" needs an rfc before being allowed inside constants
+
+error: this constant cannot be used
+  --> $DIR/const_raw_ptr_ops.rs:26:1
+   |
+LL | const Z2: i32 = unsafe { *(42 as *const i32) }; //~ ERROR cannot be used
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^-------------------^^^
+   |                          |
+   |                          tried to access memory with alignment 2, but alignment 4 is required
+
+error: this constant cannot be used
+  --> $DIR/const_raw_ptr_ops.rs:27:1
+   |
+LL | const Z3: i32 = unsafe { *(44 as *const i32) }; //~ ERROR cannot be used
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^-------------------^^^
+   |                          |
+   |                          a memory access tried to interpret some bytes as a pointer
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/const-eval/promoted_raw_ptr_ops.rs b/src/test/ui/const-eval/promoted_raw_ptr_ops.rs
new file mode 100644 (file)
index 0000000..30e7648
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2018 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.
+
+#![feature(const_raw_ptr_to_usize_cast, const_compare_raw_pointers, const_raw_ptr_deref)]
+
+fn main() {
+    let x: &'static bool = &(42 as *const i32 == 43 as *const i32);
+    //~^ ERROR does not live long enough
+    let y: &'static usize = &(&1 as *const i32 as usize + 1); //~ ERROR does not live long enough
+    let z: &'static i32 = &(unsafe { *(42 as *const i32) }); //~ ERROR does not live long enough
+}
\ No newline at end of file
diff --git a/src/test/ui/const-eval/promoted_raw_ptr_ops.stderr b/src/test/ui/const-eval/promoted_raw_ptr_ops.stderr
new file mode 100644 (file)
index 0000000..90c73c0
--- /dev/null
@@ -0,0 +1,35 @@
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promoted_raw_ptr_ops.rs:14:29
+   |
+LL |     let x: &'static bool = &(42 as *const i32 == 43 as *const i32);
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
+...
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promoted_raw_ptr_ops.rs:16:30
+   |
+LL |     let y: &'static usize = &(&1 as *const i32 as usize + 1); //~ ERROR does not live long enough
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
+LL |     let z: &'static i32 = &(unsafe { *(42 as *const i32) }); //~ ERROR does not live long enough
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promoted_raw_ptr_ops.rs:17:28
+   |
+LL |     let z: &'static i32 = &(unsafe { *(42 as *const i32) }); //~ ERROR does not live long enough
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
index 90f9ab9ec3641a1319e87be9e5de9d878fabd8d1..0fb9a9e854ddb9d5b09882c8ecd4207f4360d703 100644 (file)
@@ -1,5 +1,5 @@
 error[E0658]: comparing raw pointers inside static (see issue #53020)
-  --> $DIR/E0395.rs:14:22
+  --> $DIR/E0395.rs:16:22
    |
 LL | static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ERROR issue #53020
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^