diff options
Diffstat (limited to '')
17 files changed, 539 insertions, 0 deletions
diff --git a/src/test/ui/transmute-equal-assoc-types.rs b/src/test/ui/transmute-equal-assoc-types.rs new file mode 100644 index 000000000..6f357543e --- /dev/null +++ b/src/test/ui/transmute-equal-assoc-types.rs @@ -0,0 +1,9 @@ +trait Foo { + type Bar; +} + +unsafe fn noop<F: Foo>(foo: F::Bar) -> F::Bar { + ::std::mem::transmute(foo) //~ ERROR cannot transmute between types of different sizes +} + +fn main() {} diff --git a/src/test/ui/transmute-equal-assoc-types.stderr b/src/test/ui/transmute-equal-assoc-types.stderr new file mode 100644 index 000000000..ce7657f96 --- /dev/null +++ b/src/test/ui/transmute-equal-assoc-types.stderr @@ -0,0 +1,11 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-equal-assoc-types.rs:6:5 + | +LL | ::std::mem::transmute(foo) + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: `<F as Foo>::Bar` does not have a fixed size + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/transmute-non-immediate-to-immediate.rs b/src/test/ui/transmute-non-immediate-to-immediate.rs new file mode 100644 index 000000000..cf77c113f --- /dev/null +++ b/src/test/ui/transmute-non-immediate-to-immediate.rs @@ -0,0 +1,11 @@ +// run-pass +// Issue #7988 +// Transmuting non-immediate type to immediate type + +// pretty-expanded FIXME #23616 + +pub fn main() { + unsafe { + ::std::mem::transmute::<[isize; 1],isize>([1]) + }; +} diff --git a/src/test/ui/transmute/main.rs b/src/test/ui/transmute/main.rs new file mode 100644 index 000000000..cb46fc5ec --- /dev/null +++ b/src/test/ui/transmute/main.rs @@ -0,0 +1,29 @@ +// normalize-stderr-32bit: "`&str` \(64 bits\)" -> "`&str` ($$STR bits)" +// normalize-stderr-64bit: "`&str` \(128 bits\)" -> "`&str` ($$STR bits)" + +use std::mem::transmute; + +pub trait TypeConstructor<'a> { + type T; +} + +unsafe fn transmute_lifetime<'a, 'b, C>(x: <C as TypeConstructor<'a>>::T) + -> <C as TypeConstructor<'b>>::T +where for<'z> C: TypeConstructor<'z> { + transmute(x) //~ ERROR cannot transmute between types of different sizes +} + +unsafe fn sizes() { + let x: u8 = transmute(10u16); //~ ERROR cannot transmute between types of different sizes +} + +unsafe fn ptrs() { + let x: u8 = transmute("test"); //~ ERROR cannot transmute between types of different sizes +} + +union Foo { x: () } +unsafe fn vary() { + let x: Foo = transmute(10); //~ ERROR cannot transmute between types of different sizes +} + +fn main() {} diff --git a/src/test/ui/transmute/main.stderr b/src/test/ui/transmute/main.stderr new file mode 100644 index 000000000..f48562094 --- /dev/null +++ b/src/test/ui/transmute/main.stderr @@ -0,0 +1,38 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/main.rs:13:5 + | +LL | transmute(x) + | ^^^^^^^^^ + | + = note: `<C as TypeConstructor>::T` does not have a fixed size + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/main.rs:17:17 + | +LL | let x: u8 = transmute(10u16); + | ^^^^^^^^^ + | + = note: source type: `u16` (16 bits) + = note: target type: `u8` (8 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/main.rs:21:17 + | +LL | let x: u8 = transmute("test"); + | ^^^^^^^^^ + | + = note: source type: `&str` ($STR bits) + = note: target type: `u8` (8 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/main.rs:26:18 + | +LL | let x: Foo = transmute(10); + | ^^^^^^^^^ + | + = note: source type: `i32` (32 bits) + = note: target type: `Foo` (0 bits) + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/transmute/transmute-different-sizes.rs b/src/test/ui/transmute/transmute-different-sizes.rs new file mode 100644 index 000000000..690decf63 --- /dev/null +++ b/src/test/ui/transmute/transmute-different-sizes.rs @@ -0,0 +1,31 @@ +// normalize-stderr-test "\d+ bits" -> "N bits" + +// Tests that `transmute` cannot be called on types of different size. + +#![allow(warnings)] +#![feature(specialization)] + +use std::mem::transmute; + +unsafe fn f() { + let _: i8 = transmute(16i16); + //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types +} + +unsafe fn g<T>(x: &T) { + let _: i8 = transmute(x); + //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types +} + +trait Specializable { type Output; } + +impl<T> Specializable for T { + default type Output = u16; +} + +unsafe fn specializable<T>(x: u16) -> <T as Specializable>::Output { + transmute(x) + //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types +} + +fn main() {} diff --git a/src/test/ui/transmute/transmute-different-sizes.stderr b/src/test/ui/transmute/transmute-different-sizes.stderr new file mode 100644 index 000000000..07a38df69 --- /dev/null +++ b/src/test/ui/transmute/transmute-different-sizes.stderr @@ -0,0 +1,30 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-different-sizes.rs:11:17 + | +LL | let _: i8 = transmute(16i16); + | ^^^^^^^^^ + | + = note: source type: `i16` (N bits) + = note: target type: `i8` (N bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-different-sizes.rs:16:17 + | +LL | let _: i8 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `&T` (N bits) + = note: target type: `i8` (N bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-different-sizes.rs:27:5 + | +LL | transmute(x) + | ^^^^^^^^^ + | + = note: source type: `u16` (N bits) + = note: target type: `<T as Specializable>::Output` (this type does not have a fixed size) + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/transmute/transmute-fat-pointers.rs b/src/test/ui/transmute/transmute-fat-pointers.rs new file mode 100644 index 000000000..7c1beffd1 --- /dev/null +++ b/src/test/ui/transmute/transmute-fat-pointers.rs @@ -0,0 +1,33 @@ +// normalize-stderr-test "\d+ bits" -> "N bits" + +// Tests that are conservative around thin/fat pointer mismatches. + +#![allow(dead_code)] + +use std::mem::transmute; + +fn a<T, U: ?Sized>(x: &[T]) -> &U { + unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes +} + +fn b<T: ?Sized, U: ?Sized>(x: &T) -> &U { + unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes +} + +fn c<T, U>(x: &T) -> &U { + unsafe { transmute(x) } +} + +fn d<T, U>(x: &[T]) -> &[U] { + unsafe { transmute(x) } +} + +fn e<T: ?Sized, U>(x: &T) -> &U { + unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes +} + +fn f<T, U: ?Sized>(x: &T) -> &U { + unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes +} + +fn main() { } diff --git a/src/test/ui/transmute/transmute-fat-pointers.stderr b/src/test/ui/transmute/transmute-fat-pointers.stderr new file mode 100644 index 000000000..e8335fcbe --- /dev/null +++ b/src/test/ui/transmute/transmute-fat-pointers.stderr @@ -0,0 +1,39 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-fat-pointers.rs:10:14 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^ + | + = note: source type: `&[T]` (N bits) + = note: target type: `&U` (pointer to `U`) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-fat-pointers.rs:14:14 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^ + | + = note: source type: `&T` (pointer to `T`) + = note: target type: `&U` (pointer to `U`) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-fat-pointers.rs:26:14 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^ + | + = note: source type: `&T` (pointer to `T`) + = note: target type: `&U` (N bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-fat-pointers.rs:30:14 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^ + | + = note: source type: `&T` (N bits) + = note: target type: `&U` (pointer to `U`) + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/transmute/transmute-from-fn-item-types-error.rs b/src/test/ui/transmute/transmute-from-fn-item-types-error.rs new file mode 100644 index 000000000..f858a199e --- /dev/null +++ b/src/test/ui/transmute/transmute-from-fn-item-types-error.rs @@ -0,0 +1,60 @@ +use std::mem; + +unsafe fn foo() -> (i8, *const (), Option<fn()>) { + let i = mem::transmute(bar); + //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types + + + let p = mem::transmute(foo); + //~^ ERROR can't transmute zero-sized type + + + let of = mem::transmute(main); + //~^ ERROR can't transmute zero-sized type + + + (i, p, of) +} + +unsafe fn bar() { + // Error as usual if the resulting type is not pointer-sized. + mem::transmute::<_, u8>(main); + //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types + + + mem::transmute::<_, *mut ()>(foo); + //~^ ERROR can't transmute zero-sized type + + + mem::transmute::<_, fn()>(bar); + //~^ ERROR can't transmute zero-sized type + + + // No error if a coercion would otherwise occur. + mem::transmute::<fn(), usize>(main); +} + +unsafe fn baz() { + mem::transmute::<_, *mut ()>(Some(foo)); + //~^ ERROR can't transmute zero-sized type + + + mem::transmute::<_, fn()>(Some(bar)); + //~^ ERROR can't transmute zero-sized type + + + mem::transmute::<_, Option<fn()>>(Some(baz)); + //~^ ERROR can't transmute zero-sized type + + + // No error if a coercion would otherwise occur. + mem::transmute::<Option<fn()>, usize>(Some(main)); +} + +fn main() { + unsafe { + foo(); + bar(); + baz(); + } +} diff --git a/src/test/ui/transmute/transmute-from-fn-item-types-error.stderr b/src/test/ui/transmute/transmute-from-fn-item-types-error.stderr new file mode 100644 index 000000000..aefe3fb8e --- /dev/null +++ b/src/test/ui/transmute/transmute-from-fn-item-types-error.stderr @@ -0,0 +1,92 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-from-fn-item-types-error.rs:4:13 + | +LL | let i = mem::transmute(bar); + | ^^^^^^^^^^^^^^ + | + = note: source type: `unsafe fn() {bar}` (0 bits) + = note: target type: `i8` (8 bits) + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:8:13 + | +LL | let p = mem::transmute(foo); + | ^^^^^^^^^^^^^^ + | + = note: source type: unsafe fn() -> (i8, *const (), Option<fn()>) {foo} + = note: target type: *const () + = help: cast with `as` to a pointer instead + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:12:14 + | +LL | let of = mem::transmute(main); + | ^^^^^^^^^^^^^^ + | + = note: source type: fn() {main} + = note: target type: Option<fn()> + = help: cast with `as` to a pointer instead + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-from-fn-item-types-error.rs:21:5 + | +LL | mem::transmute::<_, u8>(main); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `fn() {main}` (0 bits) + = note: target type: `u8` (8 bits) + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:25:5 + | +LL | mem::transmute::<_, *mut ()>(foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: unsafe fn() -> (i8, *const (), Option<fn()>) {foo} + = note: target type: *mut () + = help: cast with `as` to a pointer instead + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:29:5 + | +LL | mem::transmute::<_, fn()>(bar); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: unsafe fn() {bar} + = note: target type: fn() + = help: cast with `as` to a pointer instead + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:38:5 + | +LL | mem::transmute::<_, *mut ()>(Some(foo)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: unsafe fn() -> (i8, *const (), Option<fn()>) {foo} + = note: target type: *mut () + = help: cast with `as` to a pointer instead + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:42:5 + | +LL | mem::transmute::<_, fn()>(Some(bar)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: unsafe fn() {bar} + = note: target type: fn() + = help: cast with `as` to a pointer instead + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:46:5 + | +LL | mem::transmute::<_, Option<fn()>>(Some(baz)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: unsafe fn() {baz} + = note: target type: Option<fn()> + = help: cast with `as` to a pointer instead + +error: aborting due to 9 previous errors + +Some errors have detailed explanations: E0512, E0591. +For more information about an error, try `rustc --explain E0512`. diff --git a/src/test/ui/transmute/transmute-impl.rs b/src/test/ui/transmute/transmute-impl.rs new file mode 100644 index 000000000..df422bda1 --- /dev/null +++ b/src/test/ui/transmute/transmute-impl.rs @@ -0,0 +1,25 @@ +// normalize-stderr-test "\d+ bits" -> "N bits" + +// Tests that are conservative around thin/fat pointer mismatches. + +#![allow(dead_code)] + +use std::mem::transmute; + +struct Foo<T: ?Sized> { + t: Box<T> +} + +impl<T: ?Sized> Foo<T> { + fn m(x: &T) -> &isize where T : Sized { + // OK here, because T : Sized is in scope. + unsafe { transmute(x) } + } + + fn n(x: &T) -> &isize { + // Not OK here, because T : Sized is not in scope. + unsafe { transmute(x) } //~ ERROR cannot transmute between types of different sizes + } +} + +fn main() { } diff --git a/src/test/ui/transmute/transmute-impl.stderr b/src/test/ui/transmute/transmute-impl.stderr new file mode 100644 index 000000000..dd19bcd54 --- /dev/null +++ b/src/test/ui/transmute/transmute-impl.stderr @@ -0,0 +1,12 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-impl.rs:21:18 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^ + | + = note: source type: `&T` (pointer to `T`) + = note: target type: `&isize` (N bits) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/transmute/transmute-imut-to-mut.rs b/src/test/ui/transmute/transmute-imut-to-mut.rs new file mode 100644 index 000000000..9f3f76c1e --- /dev/null +++ b/src/test/ui/transmute/transmute-imut-to-mut.rs @@ -0,0 +1,8 @@ +// Tests that transmuting from &T to &mut T is Undefined Behavior. + +use std::mem::transmute; + +fn main() { + let _a: &mut u8 = unsafe { transmute(&1u8) }; + //~^ ERROR transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell +} diff --git a/src/test/ui/transmute/transmute-imut-to-mut.stderr b/src/test/ui/transmute/transmute-imut-to-mut.stderr new file mode 100644 index 000000000..1e9dff3ce --- /dev/null +++ b/src/test/ui/transmute/transmute-imut-to-mut.stderr @@ -0,0 +1,10 @@ +error: transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell + --> $DIR/transmute-imut-to-mut.rs:6:32 + | +LL | let _a: &mut u8 = unsafe { transmute(&1u8) }; + | ^^^^^^^^^ + | + = note: `#[deny(mutable_transmutes)]` on by default + +error: aborting due to previous error + diff --git a/src/test/ui/transmute/transmute-type-parameters.rs b/src/test/ui/transmute/transmute-type-parameters.rs new file mode 100644 index 000000000..5f44b2d0f --- /dev/null +++ b/src/test/ui/transmute/transmute-type-parameters.rs @@ -0,0 +1,44 @@ +// Tests that `transmute` cannot be called on type parameters. + +use std::mem::transmute; + +unsafe fn f<T>(x: T) { + let _: i32 = transmute(x); +//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types +} + +unsafe fn g<T>(x: (T, i32)) { + let _: i32 = transmute(x); +//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types +} + +unsafe fn h<T>(x: [T; 10]) { + let _: i32 = transmute(x); +//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types +} + +struct Bad<T> { + f: T, +} + +unsafe fn i<T>(x: Bad<T>) { + let _: i32 = transmute(x); +//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types +} + +enum Worse<T> { + A(T), + B, +} + +unsafe fn j<T>(x: Worse<T>) { + let _: i32 = transmute(x); +//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types +} + +unsafe fn k<T>(x: Option<T>) { + let _: i32 = transmute(x); +//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types +} + +fn main() {} diff --git a/src/test/ui/transmute/transmute-type-parameters.stderr b/src/test/ui/transmute/transmute-type-parameters.stderr new file mode 100644 index 000000000..220b929d4 --- /dev/null +++ b/src/test/ui/transmute/transmute-type-parameters.stderr @@ -0,0 +1,57 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-type-parameters.rs:6:18 + | +LL | let _: i32 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `T` (this type does not have a fixed size) + = note: target type: `i32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-type-parameters.rs:11:18 + | +LL | let _: i32 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `(T, i32)` (size can vary because of T) + = note: target type: `i32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-type-parameters.rs:16:18 + | +LL | let _: i32 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `[T; 10]` (size can vary because of T) + = note: target type: `i32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-type-parameters.rs:25:18 + | +LL | let _: i32 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `Bad<T>` (size can vary because of T) + = note: target type: `i32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-type-parameters.rs:35:18 + | +LL | let _: i32 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `Worse<T>` (size can vary because of T) + = note: target type: `i32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-type-parameters.rs:40:18 + | +LL | let _: i32 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `Option<T>` (size can vary because of T) + = note: target type: `i32` (32 bits) + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0512`. |