]> git.lizzy.rs Git - rust.git/commitdiff
Don't run UB in test suite
authorSmitty <me@smitop.com>
Mon, 21 Mar 2022 13:32:26 +0000 (09:32 -0400)
committerSmitty <me@smitop.com>
Mon, 21 Mar 2022 13:32:26 +0000 (09:32 -0400)
This splits ui/unsafe/union.rs to make it so only the non-UB parts are
run. It also means we can do more testing of the location of error
messages.

src/test/ui/unsafe/union-modification.rs [new file with mode: 0644]
src/test/ui/unsafe/union.mir.stderr
src/test/ui/unsafe/union.rs
src/test/ui/unsafe/union.thir.stderr [new file with mode: 0644]

diff --git a/src/test/ui/unsafe/union-modification.rs b/src/test/ui/unsafe/union-modification.rs
new file mode 100644 (file)
index 0000000..5c70b78
--- /dev/null
@@ -0,0 +1,39 @@
+// run-pass
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+
+#![feature(untagged_unions)]
+
+union Foo {
+    bar: i8,
+    _blah: isize,
+    _zst: (),
+}
+
+struct FooHolder {
+    inner_foo: Foo
+}
+
+fn do_nothing(_x: &mut Foo) {}
+
+pub fn main() {
+    let mut foo = Foo { bar: 5 };
+    do_nothing(&mut foo);
+    foo.bar = 6;
+    unsafe { foo.bar += 1; }
+    assert_eq!(unsafe { foo.bar }, 7);
+    unsafe {
+        let Foo { bar: inner } = foo;
+        assert_eq!(inner, 7);
+    }
+
+    let foo = Foo { bar: 5 };
+    let foo = if let 3 = if let true = true { 3 } else { 4 } { foo } else { foo };
+
+    let (_foo2, _random) = (foo, 42);
+
+    let mut foo_holder = FooHolder { inner_foo: Foo { bar: 5 } };
+    foo_holder.inner_foo.bar = 4;
+    assert_eq!(unsafe { foo_holder.inner_foo.bar }, 4);
+    drop(foo_holder);
+}
index f7bd411a74416681f7aeb6cd8755d881564386ca..787714cdd2dedf16db47ac1bdcdb94adffbb7c85 100644 (file)
@@ -1,16 +1,19 @@
-warning: unnecessary `unsafe` block
-  --> $DIR/union.rs:61:5
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union.rs:30:20
    |
-LL |     unsafe {
-   |     ^^^^^^ unnecessary `unsafe` block
+LL |         Foo { bar: _a } => {},
+   |                    ^^ access to union field
    |
-   = note: `#[warn(unused_unsafe)]` on by default
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
-warning: unnecessary `unsafe` block
-  --> $DIR/union.rs:66:5
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union.rs:32:11
    |
-LL |     unsafe {
-   |     ^^^^^^ unnecessary `unsafe` block
+LL |     match foo {
+   |           ^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
-warning: 2 warnings emitted
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0133`.
index 0130fa67f2328e9069352de28de16a0b91798409..5fe09933cfc486cc26bf44015767268905a773d3 100644 (file)
@@ -1,4 +1,3 @@
-// run-pass
 // revisions: mir thir
 // [thir]compile-flags: -Z thir-unsafeck
 
@@ -20,61 +19,35 @@ enum PizzaTopping {
     Pineapple,
 }
 
-struct FooHolder {
-    inner_foo: Foo
-}
-
 fn do_nothing(_x: &mut Foo) {}
 
 pub fn main() {
     let mut foo = Foo { bar: 5 };
     do_nothing(&mut foo);
-    foo.bar = 6;
-    unsafe { foo.bar += 1; }
-    assert_eq!(unsafe { foo.bar }, 7);
-    unsafe {
-        let Foo { bar: inner } = foo;
-        assert_eq!(inner, 7);
+
+    // This is UB, so this test isn't run
+    match foo {
+        Foo { bar: _a } => {}, //~ ERROR access to union field is unsafe
+    }
+    match foo { //[mir]~ ERROR access to union field is unsafe
+        Foo {
+            pizza: Pizza { //[thir]~ ERROR access to union field is unsafe
+                topping: Some(PizzaTopping::Cheese) | Some(PizzaTopping::Pineapple) | None
+            }
+        } => {},
     }
-    let foo = if let true = true { foo } else { foo };
 
-    unsafe {
-        match foo {
-            Foo { bar: _a } => {},
-        }
+    // MIR unsafeck incorrectly thinks that no unsafe block is needed to do these
+    match foo {
+        Foo { zst: () } => {}, //[thir]~ ERROR access to union field is unsafe
     }
-    unsafe {
-        match foo {
-            Foo {
-                pizza: Pizza {
-                    topping: Some(PizzaTopping::Cheese) | Some(PizzaTopping::Pineapple) | None
-                }
-            } => {},
-        }
+    match foo {
+        Foo { pizza: Pizza { .. } } => {}, //[thir]~ ERROR access to union field is unsafe
     }
+
     // binding to wildcard is okay
     match foo {
         Foo { bar: _ } => {},
     }
     let Foo { bar: _ } = foo;
-    // MIR unsafeck incorrectly thinks that it is safe to do these
-    unsafe { //[mir]~ WARNING
-        match foo {
-            Foo { zst: () } => {},
-        }
-    }
-    unsafe { //[mir]~ WARNING
-        match foo {
-            Foo { pizza: Pizza { .. } } => {},
-        }
-    }
-    let foo = Foo { bar: 5 };
-    let foo = if let 3 = if let true = true { 3 } else { 4 } { foo } else { foo };
-
-    let (_foo2, _random) = (foo, 42);
-
-    let mut foo_holder = FooHolder { inner_foo: Foo { bar: 5 } };
-    foo_holder.inner_foo.bar = 4;
-    assert_eq!(unsafe { foo_holder.inner_foo.bar }, 4);
-    drop(foo_holder);
 }
diff --git a/src/test/ui/unsafe/union.thir.stderr b/src/test/ui/unsafe/union.thir.stderr
new file mode 100644 (file)
index 0000000..e1a1bd6
--- /dev/null
@@ -0,0 +1,38 @@
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union.rs:30:20
+   |
+LL |         Foo { bar: _a } => {},
+   |                    ^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union.rs:34:20
+   |
+LL |               pizza: Pizza {
+   |  ____________________^
+LL | |                 topping: Some(PizzaTopping::Cheese) | Some(PizzaTopping::Pineapple) | None
+LL | |             }
+   | |_____________^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union.rs:42:20
+   |
+LL |         Foo { zst: () } => {},
+   |                    ^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union.rs:45:22
+   |
+LL |         Foo { pizza: Pizza { .. } } => {},
+   |                      ^^^^^^^^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0133`.