diff options
Diffstat (limited to 'tests/ui/intrinsics')
39 files changed, 1650 insertions, 0 deletions
diff --git a/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs b/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs new file mode 100644 index 000000000..f3b9d569c --- /dev/null +++ b/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs @@ -0,0 +1,14 @@ +#![feature(intrinsics)] + +pub mod rusti { + extern "rust-intrinsic" { + pub fn atomic_xchg_seqcst<T>(dst: *mut T, src: T) -> T; + } +} + +#[inline(always)] +pub fn atomic_xchg_seqcst(dst: *mut isize, src: isize) -> isize { + unsafe { + rusti::atomic_xchg_seqcst(dst, src) + } +} diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs new file mode 100644 index 000000000..f36a5f1ac --- /dev/null +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs @@ -0,0 +1,32 @@ +// build-fail + +#![feature(repr_simd, platform_intrinsics, core_intrinsics)] +#![allow(warnings)] +#![crate_type = "rlib"] + +// Bad monomorphizations could previously cause LLVM asserts even though the +// error was caught in the compiler. + +extern "platform-intrinsic" { + fn simd_add<T>(x: T, y: T) -> T; +} + +use std::intrinsics; + +#[derive(Copy, Clone)] +pub struct Foo(i64); + +pub fn test_cttz(v: Foo) -> Foo { + intrinsics::cttz(v) + //~^ ERROR `cttz` intrinsic: expected basic integer type, found `Foo` +} + +pub unsafe fn test_fadd_fast(a: Foo, b: Foo) -> Foo { + intrinsics::fadd_fast(a, b) + //~^ ERROR `fadd_fast` intrinsic: expected basic float type, found `Foo` +} + +pub unsafe fn test_simd_add(a: Foo, b: Foo) -> Foo { + simd_add(a, b) + //~^ ERROR `simd_add` intrinsic: expected SIMD input type, found non-SIMD `Foo` +} diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr b/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr new file mode 100644 index 000000000..c070f0181 --- /dev/null +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr @@ -0,0 +1,21 @@ +error[E0511]: invalid monomorphization of `cttz` intrinsic: expected basic integer type, found `Foo` + --> $DIR/bad-intrinsic-monomorphization.rs:20:5 + | +LL | intrinsics::cttz(v) + | ^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `fadd_fast` intrinsic: expected basic float type, found `Foo` + --> $DIR/bad-intrinsic-monomorphization.rs:25:5 + | +LL | intrinsics::fadd_fast(a, b) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `Foo` + --> $DIR/bad-intrinsic-monomorphization.rs:30:5 + | +LL | simd_add(a, b) + | ^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0511`. diff --git a/tests/ui/intrinsics/const-eval-select-backtrace-std.rs b/tests/ui/intrinsics/const-eval-select-backtrace-std.rs new file mode 100644 index 000000000..1164a3a5b --- /dev/null +++ b/tests/ui/intrinsics/const-eval-select-backtrace-std.rs @@ -0,0 +1,7 @@ +// See issue #100696. +// run-fail +// check-run-results +// exec-env:RUST_BACKTRACE=0 +fn main() { + &""[1..]; +} diff --git a/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr b/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr new file mode 100644 index 000000000..463cd52c5 --- /dev/null +++ b/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr @@ -0,0 +1,2 @@ +thread 'main' panicked at 'byte index 1 is out of bounds of ``', $DIR/const-eval-select-backtrace-std.rs:6:6 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/tests/ui/intrinsics/const-eval-select-backtrace.rs b/tests/ui/intrinsics/const-eval-select-backtrace.rs new file mode 100644 index 000000000..ef1c7c419 --- /dev/null +++ b/tests/ui/intrinsics/const-eval-select-backtrace.rs @@ -0,0 +1,19 @@ +#![feature(core_intrinsics)] +// See issue #100696. +// run-fail +// check-run-results +// exec-env:RUST_BACKTRACE=0 + +#[track_caller] +fn uhoh() { + panic!("Aaah!") +} + +const fn c() {} + +fn main() { + // safety: this is unsound and just used to test + unsafe { + std::intrinsics::const_eval_select((), c, uhoh); + } +} diff --git a/tests/ui/intrinsics/const-eval-select-backtrace.run.stderr b/tests/ui/intrinsics/const-eval-select-backtrace.run.stderr new file mode 100644 index 000000000..54e28db5e --- /dev/null +++ b/tests/ui/intrinsics/const-eval-select-backtrace.run.stderr @@ -0,0 +1,2 @@ +thread 'main' panicked at 'Aaah!', $DIR/const-eval-select-backtrace.rs:17:9 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/tests/ui/intrinsics/const-eval-select-bad.rs b/tests/ui/intrinsics/const-eval-select-bad.rs new file mode 100644 index 000000000..fa14efad7 --- /dev/null +++ b/tests/ui/intrinsics/const-eval-select-bad.rs @@ -0,0 +1,46 @@ +#![feature(const_eval_select)] +#![feature(core_intrinsics)] + +use std::intrinsics::const_eval_select; + +const fn not_fn_items() { + const_eval_select((), || {}, || {}); + //~^ ERROR this argument must be a function item + //~| ERROR this argument must be a function item + const_eval_select((), 42, 0xDEADBEEF); + //~^ ERROR expected a `FnOnce<()>` closure + //~| ERROR expected a `FnOnce<()>` closure + //~| ERROR this argument must be a function item + //~| ERROR this argument must be a function item +} + +const fn foo(n: i32) -> i32 { + n +} + +fn bar(n: i32) -> bool { + assert_eq!(n, 0, "{} must be equal to {}", n, 0); + n == 0 +} + +fn baz(n: bool) -> i32 { + assert!(n, "{} must be true", n); + n as i32 +} + +const fn return_ty_mismatch() { + const_eval_select((1,), foo, bar); + //~^ ERROR expected `fn(i32) -> bool {bar}` to be a fn item that returns `i32`, but it returns `bool` +} + +const fn args_ty_mismatch() { + const_eval_select((true,), foo, baz); + //~^ ERROR type mismatch +} + +const fn non_const_fn() { + const_eval_select((1,), bar, bar); + //~^ ERROR this argument must be a `const fn` +} + +fn main() {} diff --git a/tests/ui/intrinsics/const-eval-select-bad.stderr b/tests/ui/intrinsics/const-eval-select-bad.stderr new file mode 100644 index 000000000..fd7d061b6 --- /dev/null +++ b/tests/ui/intrinsics/const-eval-select-bad.stderr @@ -0,0 +1,101 @@ +error: this argument must be a function item + --> $DIR/const-eval-select-bad.rs:7:27 + | +LL | const_eval_select((), || {}, || {}); + | ^^^^^ + | + = note: expected a function item, found [closure@$DIR/const-eval-select-bad.rs:7:27: 7:29] + = help: consult the documentation on `const_eval_select` for more information + +error: this argument must be a function item + --> $DIR/const-eval-select-bad.rs:7:34 + | +LL | const_eval_select((), || {}, || {}); + | ^^^^^ + | + = note: expected a function item, found [closure@$DIR/const-eval-select-bad.rs:7:34: 7:36] + = help: consult the documentation on `const_eval_select` for more information + +error: this argument must be a function item + --> $DIR/const-eval-select-bad.rs:10:27 + | +LL | const_eval_select((), 42, 0xDEADBEEF); + | ^^ + | + = note: expected a function item, found {integer} + = help: consult the documentation on `const_eval_select` for more information + +error[E0277]: expected a `FnOnce<()>` closure, found `{integer}` + --> $DIR/const-eval-select-bad.rs:10:27 + | +LL | const_eval_select((), 42, 0xDEADBEEF); + | ----------------- ^^ expected an `FnOnce<()>` closure, found `{integer}` + | | + | required by a bound introduced by this call + | + = help: the trait `FnOnce<()>` is not implemented for `{integer}` + = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `const_eval_select` + --> $SRC_DIR/core/src/intrinsics.rs:LL:COL + +error: this argument must be a function item + --> $DIR/const-eval-select-bad.rs:10:31 + | +LL | const_eval_select((), 42, 0xDEADBEEF); + | ^^^^^^^^^^ + | + = note: expected a function item, found {integer} + = help: consult the documentation on `const_eval_select` for more information + +error[E0277]: expected a `FnOnce<()>` closure, found `{integer}` + --> $DIR/const-eval-select-bad.rs:10:31 + | +LL | const_eval_select((), 42, 0xDEADBEEF); + | ----------------- ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `{integer}` + | | + | required by a bound introduced by this call + | + = help: the trait `FnOnce<()>` is not implemented for `{integer}` + = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `const_eval_select` + --> $SRC_DIR/core/src/intrinsics.rs:LL:COL + +error[E0271]: expected `fn(i32) -> bool {bar}` to be a fn item that returns `i32`, but it returns `bool` + --> $DIR/const-eval-select-bad.rs:32:34 + | +LL | const_eval_select((1,), foo, bar); + | ----------------- ^^^ expected `i32`, found `bool` + | | + | required by a bound introduced by this call + | +note: required by a bound in `const_eval_select` + --> $SRC_DIR/core/src/intrinsics.rs:LL:COL + +error[E0631]: type mismatch in function arguments + --> $DIR/const-eval-select-bad.rs:37:32 + | +LL | const fn foo(n: i32) -> i32 { + | --------------------------- found signature defined here +... +LL | const_eval_select((true,), foo, baz); + | ----------------- ^^^ expected due to this + | | + | required by a bound introduced by this call + | + = note: expected function signature `fn(bool) -> _` + found function signature `fn(i32) -> _` +note: required by a bound in `const_eval_select` + --> $SRC_DIR/core/src/intrinsics.rs:LL:COL + +error: this argument must be a `const fn` + --> $DIR/const-eval-select-bad.rs:42:29 + | +LL | const_eval_select((1,), bar, bar); + | ^^^ + | + = help: consult the documentation on `const_eval_select` for more information + +error: aborting due to 9 previous errors + +Some errors have detailed explanations: E0271, E0277, E0631. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/intrinsics/const-eval-select-stability.rs b/tests/ui/intrinsics/const-eval-select-stability.rs new file mode 100644 index 000000000..f9554dece --- /dev/null +++ b/tests/ui/intrinsics/const-eval-select-stability.rs @@ -0,0 +1,21 @@ +#![feature(staged_api)] +#![feature(const_eval_select)] +#![feature(core_intrinsics)] +#![stable(since = "1.0", feature = "ui_test")] + +use std::intrinsics::const_eval_select; + +fn log() { + println!("HEY HEY HEY") +} + +const fn nothing(){} + +#[stable(since = "1.0", feature = "hey")] +#[rustc_const_stable(since = "1.0", feature = "const_hey")] +pub const unsafe fn hey() { + const_eval_select((), nothing, log); + //~^ ERROR `const_eval_select` is not yet stable as a const fn +} + +fn main() {} diff --git a/tests/ui/intrinsics/const-eval-select-stability.stderr b/tests/ui/intrinsics/const-eval-select-stability.stderr new file mode 100644 index 000000000..65b507b88 --- /dev/null +++ b/tests/ui/intrinsics/const-eval-select-stability.stderr @@ -0,0 +1,10 @@ +error: `const_eval_select` is not yet stable as a const fn + --> $DIR/const-eval-select-stability.rs:17:5 + | +LL | const_eval_select((), nothing, log); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: const-stable functions can only call other const-stable functions + +error: aborting due to previous error + diff --git a/tests/ui/intrinsics/const-eval-select-x86_64.rs b/tests/ui/intrinsics/const-eval-select-x86_64.rs new file mode 100644 index 000000000..f3924acf0 --- /dev/null +++ b/tests/ui/intrinsics/const-eval-select-x86_64.rs @@ -0,0 +1,40 @@ +// run-pass +// only-x86_64 + +#![feature(const_eval_select)] +#![feature(core_intrinsics)] +use std::intrinsics::const_eval_select; +use std::arch::x86_64::*; +use std::mem::transmute; + +const fn eq_ct(x: [i32; 4], y: [i32; 4]) -> bool { + x[0] == y[0] && x[1] == y[1] && x[2] == y[2] && x[3] == y[3] +} + +fn eq_rt(x: [i32; 4], y: [i32; 4]) -> bool { + unsafe { + let x = _mm_loadu_si128(&x as *const _ as *const _); + let y = _mm_loadu_si128(&y as *const _ as *const _); + let r = _mm_cmpeq_epi32(x, y); + let r = _mm_movemask_ps(transmute(r) ); + r == 0b1111 + } +} + +const fn eq(x: [i32; 4], y: [i32; 4]) -> bool { + unsafe { + const_eval_select((x, y), eq_ct, eq_rt) + } +} + +fn main() { + const X: bool = eq([0, 1, 2, 3], [0, 1, 2, 3]); + assert_eq!(X, true); + let x = eq([0, 1, 2, 3], [0, 1, 2, 3]); + assert_eq!(x, true); + + const Y: bool = eq([0, 1, 2, 3], [0, 1, 3, 2]); + assert_eq!(Y, false); + let y = eq([0, 1, 2, 3], [0, 1, 3, 2]); + assert_eq!(y, false); +} diff --git a/tests/ui/intrinsics/const-eval-select.rs b/tests/ui/intrinsics/const-eval-select.rs new file mode 100644 index 000000000..9ff20d3fb --- /dev/null +++ b/tests/ui/intrinsics/const-eval-select.rs @@ -0,0 +1,27 @@ +// run-pass + +#![feature(const_eval_select)] +#![feature(core_intrinsics)] + +use std::intrinsics::const_eval_select; + +const fn yes() -> bool { + true +} + +fn no() -> bool { + false +} + +// not a sound use case; testing only +const fn is_const_eval() -> bool { + unsafe { const_eval_select((), yes, no) } +} + +fn main() { + const YES: bool = is_const_eval(); + let no = is_const_eval(); + + assert_eq!(true, YES); + assert_eq!(false, no); +} diff --git a/tests/ui/intrinsics/intrinsic-alignment.rs b/tests/ui/intrinsics/intrinsic-alignment.rs new file mode 100644 index 000000000..c8b1ff1db --- /dev/null +++ b/tests/ui/intrinsics/intrinsic-alignment.rs @@ -0,0 +1,67 @@ +// run-pass +// ignore-wasm32-bare seems not important to test here + +#![feature(intrinsics)] + +mod rusti { + extern "rust-intrinsic" { + pub fn pref_align_of<T>() -> usize; + #[rustc_safe_intrinsic] + pub fn min_align_of<T>() -> usize; + } +} + +#[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "vxworks"))] +mod m { + #[cfg(target_arch = "x86")] + pub fn main() { + unsafe { + assert_eq!(::rusti::pref_align_of::<u64>(), 8); + assert_eq!(::rusti::min_align_of::<u64>(), 4); + } + } + + #[cfg(not(target_arch = "x86"))] + pub fn main() { + unsafe { + assert_eq!(::rusti::pref_align_of::<u64>(), 8); + assert_eq!(::rusti::min_align_of::<u64>(), 8); + } + } +} + +#[cfg(target_env = "sgx")] +mod m { + #[cfg(target_arch = "x86_64")] + pub fn main() { + unsafe { + assert_eq!(::rusti::pref_align_of::<u64>(), 8); + assert_eq!(::rusti::min_align_of::<u64>(), 8); + } + } +} + +#[cfg(target_os = "windows")] +mod m { + pub fn main() { + unsafe { + assert_eq!(::rusti::pref_align_of::<u64>(), 8); + assert_eq!(::rusti::min_align_of::<u64>(), 8); + } + } +} + +fn main() { + m::main(); +} diff --git a/tests/ui/intrinsics/intrinsic-assume.rs b/tests/ui/intrinsics/intrinsic-assume.rs new file mode 100644 index 000000000..3c9d70cb5 --- /dev/null +++ b/tests/ui/intrinsics/intrinsic-assume.rs @@ -0,0 +1,17 @@ +// run-pass +#![feature(core_intrinsics)] + +use std::intrinsics::assume; + +unsafe fn f(x: i32) -> i32 { + assume(x == 34); + match x { + 34 => 42, + _ => 30 + } +} + +fn main() { + let x = unsafe { f(34) }; + assert_eq!(x, 42); +} diff --git a/tests/ui/intrinsics/intrinsic-atomics-cc.rs b/tests/ui/intrinsics/intrinsic-atomics-cc.rs new file mode 100644 index 000000000..ce3fa7b0c --- /dev/null +++ b/tests/ui/intrinsics/intrinsic-atomics-cc.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:cci_intrinsic.rs + + +extern crate cci_intrinsic; +use cci_intrinsic::atomic_xchg_seqcst; + +pub fn main() { + let mut x = 1; + atomic_xchg_seqcst(&mut x, 5); + assert_eq!(x, 5); +} diff --git a/tests/ui/intrinsics/intrinsic-atomics.rs b/tests/ui/intrinsics/intrinsic-atomics.rs new file mode 100644 index 000000000..b17f4347b --- /dev/null +++ b/tests/ui/intrinsics/intrinsic-atomics.rs @@ -0,0 +1,102 @@ +// run-pass +#![feature(intrinsics)] + +mod rusti { + extern "rust-intrinsic" { + pub fn atomic_cxchg_seqcst_seqcst<T>(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchg_acquire_acquire<T>(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchg_release_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool); + + pub fn atomic_cxchgweak_seqcst_seqcst<T>(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchgweak_acquire_acquire<T>(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchgweak_release_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool); + + pub fn atomic_load_seqcst<T>(src: *const T) -> T; + pub fn atomic_load_acquire<T>(src: *const T) -> T; + + pub fn atomic_store_seqcst<T>(dst: *mut T, val: T); + pub fn atomic_store_release<T>(dst: *mut T, val: T); + + pub fn atomic_xchg_seqcst<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xchg_acquire<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xchg_release<T>(dst: *mut T, src: T) -> T; + + pub fn atomic_xadd_seqcst<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xadd_acquire<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xadd_release<T>(dst: *mut T, src: T) -> T; + + pub fn atomic_xsub_seqcst<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xsub_acquire<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xsub_release<T>(dst: *mut T, src: T) -> T; + } +} + +pub fn main() { + unsafe { + let mut x: Box<_> = Box::new(1); + + assert_eq!(rusti::atomic_load_seqcst(&*x), 1); + *x = 5; + assert_eq!(rusti::atomic_load_acquire(&*x), 5); + + rusti::atomic_store_seqcst(&mut *x,3); + assert_eq!(*x, 3); + rusti::atomic_store_release(&mut *x,1); + assert_eq!(*x, 1); + + assert_eq!(rusti::atomic_cxchg_seqcst_seqcst(&mut *x, 1, 2), (1, true)); + assert_eq!(*x, 2); + + assert_eq!(rusti::atomic_cxchg_acquire_acquire(&mut *x, 1, 3), (2, false)); + assert_eq!(*x, 2); + + assert_eq!(rusti::atomic_cxchg_release_relaxed(&mut *x, 2, 1), (2, true)); + assert_eq!(*x, 1); + + assert_eq!(rusti::atomic_xchg_seqcst(&mut *x, 0), 1); + assert_eq!(*x, 0); + + assert_eq!(rusti::atomic_xchg_acquire(&mut *x, 1), 0); + assert_eq!(*x, 1); + + assert_eq!(rusti::atomic_xchg_release(&mut *x, 0), 1); + assert_eq!(*x, 0); + + assert_eq!(rusti::atomic_xadd_seqcst(&mut *x, 1), 0); + assert_eq!(rusti::atomic_xadd_acquire(&mut *x, 1), 1); + assert_eq!(rusti::atomic_xadd_release(&mut *x, 1), 2); + assert_eq!(*x, 3); + + assert_eq!(rusti::atomic_xsub_seqcst(&mut *x, 1), 3); + assert_eq!(rusti::atomic_xsub_acquire(&mut *x, 1), 2); + assert_eq!(rusti::atomic_xsub_release(&mut *x, 1), 1); + assert_eq!(*x, 0); + + loop { + let res = rusti::atomic_cxchgweak_seqcst_seqcst(&mut *x, 0, 1); + assert_eq!(res.0, 0); + if res.1 { + break; + } + } + assert_eq!(*x, 1); + + loop { + let res = rusti::atomic_cxchgweak_acquire_acquire(&mut *x, 1, 2); + assert_eq!(res.0, 1); + if res.1 { + break; + } + } + assert_eq!(*x, 2); + + loop { + let res = rusti::atomic_cxchgweak_release_relaxed(&mut *x, 2, 3); + assert_eq!(res.0, 2); + if res.1 { + break; + } + } + assert_eq!(*x, 3); + } +} diff --git a/tests/ui/intrinsics/intrinsic-nearby.rs b/tests/ui/intrinsics/intrinsic-nearby.rs new file mode 100644 index 000000000..7b1d1eeaa --- /dev/null +++ b/tests/ui/intrinsics/intrinsic-nearby.rs @@ -0,0 +1,11 @@ +// run-pass +#![feature(core_intrinsics)] + +use std::intrinsics::*; + +fn main() { + unsafe { + assert_eq!(nearbyintf32(5.234f32), 5f32); + assert_eq!(nearbyintf64(6.777f64), 7f64); + } +} diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const-padding.rs b/tests/ui/intrinsics/intrinsic-raw_eq-const-padding.rs new file mode 100644 index 000000000..a93d777d2 --- /dev/null +++ b/tests/ui/intrinsics/intrinsic-raw_eq-const-padding.rs @@ -0,0 +1,10 @@ +#![feature(core_intrinsics)] +#![feature(const_intrinsic_raw_eq)] + +const BAD_RAW_EQ_CALL: bool = unsafe { + std::intrinsics::raw_eq(&(1_u8, 2_u16), &(1_u8, 2_u16)) +//~^ ERROR evaluation of constant value failed +}; + +pub fn main() { +} diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr b/tests/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr new file mode 100644 index 000000000..56d5a4857 --- /dev/null +++ b/tests/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/intrinsic-raw_eq-const-padding.rs:5:5 + | +LL | std::intrinsics::raw_eq(&(1_u8, 2_u16), &(1_u8, 2_u16)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at alloc3[0x0..0x4], but memory is uninitialized at [0x1..0x2], and this operation requires initialized memory + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const.rs b/tests/ui/intrinsics/intrinsic-raw_eq-const.rs new file mode 100644 index 000000000..32841f531 --- /dev/null +++ b/tests/ui/intrinsics/intrinsic-raw_eq-const.rs @@ -0,0 +1,26 @@ +// run-pass + +#![feature(core_intrinsics)] +#![feature(const_intrinsic_raw_eq)] + +pub fn main() { + use std::intrinsics::raw_eq; + + const RAW_EQ_I32_TRUE: bool = unsafe { raw_eq(&42_i32, &42) }; + assert!(RAW_EQ_I32_TRUE); + + const RAW_EQ_I32_FALSE: bool = unsafe { raw_eq(&4_i32, &2) }; + assert!(!RAW_EQ_I32_FALSE); + + const RAW_EQ_CHAR_TRUE: bool = unsafe { raw_eq(&'a', &'a') }; + assert!(RAW_EQ_CHAR_TRUE); + + const RAW_EQ_CHAR_FALSE: bool = unsafe { raw_eq(&'a', &'A') }; + assert!(!RAW_EQ_CHAR_FALSE); + + const RAW_EQ_ARRAY_TRUE: bool = unsafe { raw_eq(&[13_u8, 42], &[13, 42]) }; + assert!(RAW_EQ_ARRAY_TRUE); + + const RAW_EQ_ARRAY_FALSE: bool = unsafe { raw_eq(&[13_u8, 42], &[42, 13]) }; + assert!(!RAW_EQ_ARRAY_FALSE); +} diff --git a/tests/ui/intrinsics/intrinsic-unreachable.rs b/tests/ui/intrinsics/intrinsic-unreachable.rs new file mode 100644 index 000000000..73dd71d48 --- /dev/null +++ b/tests/ui/intrinsics/intrinsic-unreachable.rs @@ -0,0 +1,17 @@ +// run-pass +#![feature(core_intrinsics)] + +use std::intrinsics; + +// See also tests/run-make/intrinsic-unreachable. + +unsafe fn f(x: usize) -> usize { + match x { + 17 => 23, + _ => intrinsics::unreachable(), + } +} + +fn main() { + assert_eq!(unsafe { f(17) }, 23); +} diff --git a/tests/ui/intrinsics/intrinsic-volatile.rs b/tests/ui/intrinsics/intrinsic-volatile.rs new file mode 100644 index 000000000..7b2c825a2 --- /dev/null +++ b/tests/ui/intrinsics/intrinsic-volatile.rs @@ -0,0 +1,44 @@ +// run-pass + +#![feature(core_intrinsics)] + +use std::intrinsics::*; + +pub fn main() { + unsafe { + let mut x: Box<u8> = Box::new(0); + let mut y: Box<u8> = Box::new(0); + + // test volatile load + assert_eq!(volatile_load(&*x), 0); + *x = 1; + assert_eq!(volatile_load(&*x), 1); + + // test volatile store + volatile_store(&mut *x, 2); + assert_eq!(*x, 2); + + // test volatile copy memory + volatile_copy_memory(&mut *y, &*x, 1); + assert_eq!(*y, 2); + + // test volatile copy non-overlapping memory + *x = 3; + volatile_copy_nonoverlapping_memory(&mut *y, &*x, 1); + assert_eq!(*y, 3); + + // test volatile set memory + volatile_set_memory(&mut *x, 4, 1); + assert_eq!(*x, 4); + + // test unaligned volatile load + let arr: [u8; 3] = [1, 2, 3]; + let ptr = arr[1..].as_ptr() as *const u16; + assert_eq!(unaligned_volatile_load(ptr), u16::from_ne_bytes([arr[1], arr[2]])); + + // test unaligned volatile store + let ptr = arr[1..].as_ptr() as *mut u16; + unaligned_volatile_store(ptr, 0); + assert_eq!(arr, [1, 0, 0]); + } +} diff --git a/tests/ui/intrinsics/intrinsics-integer.rs b/tests/ui/intrinsics/intrinsics-integer.rs new file mode 100644 index 000000000..88bf42b68 --- /dev/null +++ b/tests/ui/intrinsics/intrinsics-integer.rs @@ -0,0 +1,177 @@ +// run-pass + +#![feature(intrinsics)] +#![feature(rustc_attrs)] + +mod rusti { + extern "rust-intrinsic" { + #[rustc_safe_intrinsic] + pub fn ctpop<T>(x: T) -> T; + #[rustc_safe_intrinsic] + pub fn ctlz<T>(x: T) -> T; + pub fn ctlz_nonzero<T>(x: T) -> T; + #[rustc_safe_intrinsic] + pub fn cttz<T>(x: T) -> T; + pub fn cttz_nonzero<T>(x: T) -> T; + #[rustc_safe_intrinsic] + pub fn bswap<T>(x: T) -> T; + #[rustc_safe_intrinsic] + pub fn bitreverse<T>(x: T) -> T; + } +} + +pub fn main() { + use rusti::*; + + assert_eq!(ctpop(0u8), 0); assert_eq!(ctpop(0i8), 0); + assert_eq!(ctpop(0u16), 0); assert_eq!(ctpop(0i16), 0); + assert_eq!(ctpop(0u32), 0); assert_eq!(ctpop(0i32), 0); + assert_eq!(ctpop(0u64), 0); assert_eq!(ctpop(0i64), 0); + assert_eq!(ctpop(0u128), 0); assert_eq!(ctpop(0i128), 0); + + assert_eq!(ctpop(1u8), 1); assert_eq!(ctpop(1i8), 1); + assert_eq!(ctpop(1u16), 1); assert_eq!(ctpop(1i16), 1); + assert_eq!(ctpop(1u32), 1); assert_eq!(ctpop(1i32), 1); + assert_eq!(ctpop(1u64), 1); assert_eq!(ctpop(1i64), 1); + assert_eq!(ctpop(1u128), 1); assert_eq!(ctpop(1i128), 1); + + assert_eq!(ctpop(10u8), 2); assert_eq!(ctpop(10i8), 2); + assert_eq!(ctpop(10u16), 2); assert_eq!(ctpop(10i16), 2); + assert_eq!(ctpop(10u32), 2); assert_eq!(ctpop(10i32), 2); + assert_eq!(ctpop(10u64), 2); assert_eq!(ctpop(10i64), 2); + assert_eq!(ctpop(10u128), 2); assert_eq!(ctpop(10i128), 2); + + assert_eq!(ctpop(100u8), 3); assert_eq!(ctpop(100i8), 3); + assert_eq!(ctpop(100u16), 3); assert_eq!(ctpop(100i16), 3); + assert_eq!(ctpop(100u32), 3); assert_eq!(ctpop(100i32), 3); + assert_eq!(ctpop(100u64), 3); assert_eq!(ctpop(100i64), 3); + assert_eq!(ctpop(100u128), 3); assert_eq!(ctpop(100i128), 3); + + assert_eq!(ctpop(-1i8 as u8), 8); assert_eq!(ctpop(-1i8), 8); + assert_eq!(ctpop(-1i16 as u16), 16); assert_eq!(ctpop(-1i16), 16); + assert_eq!(ctpop(-1i32 as u32), 32); assert_eq!(ctpop(-1i32), 32); + assert_eq!(ctpop(-1i64 as u64), 64); assert_eq!(ctpop(-1i64), 64); + assert_eq!(ctpop(-1i128 as u128), 128); assert_eq!(ctpop(-1i128), 128); + + assert_eq!(ctlz(0u8), 8); assert_eq!(ctlz(0i8), 8); + assert_eq!(ctlz(0u16), 16); assert_eq!(ctlz(0i16), 16); + assert_eq!(ctlz(0u32), 32); assert_eq!(ctlz(0i32), 32); + assert_eq!(ctlz(0u64), 64); assert_eq!(ctlz(0i64), 64); + assert_eq!(ctlz(0u128), 128); assert_eq!(ctlz(0i128), 128); + + assert_eq!(ctlz(1u8), 7); assert_eq!(ctlz(1i8), 7); + assert_eq!(ctlz(1u16), 15); assert_eq!(ctlz(1i16), 15); + assert_eq!(ctlz(1u32), 31); assert_eq!(ctlz(1i32), 31); + assert_eq!(ctlz(1u64), 63); assert_eq!(ctlz(1i64), 63); + assert_eq!(ctlz(1u128), 127); assert_eq!(ctlz(1i128), 127); + + assert_eq!(ctlz(10u8), 4); assert_eq!(ctlz(10i8), 4); + assert_eq!(ctlz(10u16), 12); assert_eq!(ctlz(10i16), 12); + assert_eq!(ctlz(10u32), 28); assert_eq!(ctlz(10i32), 28); + assert_eq!(ctlz(10u64), 60); assert_eq!(ctlz(10i64), 60); + assert_eq!(ctlz(10u128), 124); assert_eq!(ctlz(10i128), 124); + + assert_eq!(ctlz(100u8), 1); assert_eq!(ctlz(100i8), 1); + assert_eq!(ctlz(100u16), 9); assert_eq!(ctlz(100i16), 9); + assert_eq!(ctlz(100u32), 25); assert_eq!(ctlz(100i32), 25); + assert_eq!(ctlz(100u64), 57); assert_eq!(ctlz(100i64), 57); + assert_eq!(ctlz(100u128), 121); assert_eq!(ctlz(100i128), 121); + + unsafe { + assert_eq!(ctlz_nonzero(1u8), 7); assert_eq!(ctlz_nonzero(1i8), 7); + assert_eq!(ctlz_nonzero(1u16), 15); assert_eq!(ctlz_nonzero(1i16), 15); + assert_eq!(ctlz_nonzero(1u32), 31); assert_eq!(ctlz_nonzero(1i32), 31); + assert_eq!(ctlz_nonzero(1u64), 63); assert_eq!(ctlz_nonzero(1i64), 63); + assert_eq!(ctlz_nonzero(1u128), 127); assert_eq!(ctlz_nonzero(1i128), 127); + + assert_eq!(ctlz_nonzero(10u8), 4); assert_eq!(ctlz_nonzero(10i8), 4); + assert_eq!(ctlz_nonzero(10u16), 12); assert_eq!(ctlz_nonzero(10i16), 12); + assert_eq!(ctlz_nonzero(10u32), 28); assert_eq!(ctlz_nonzero(10i32), 28); + assert_eq!(ctlz_nonzero(10u64), 60); assert_eq!(ctlz_nonzero(10i64), 60); + assert_eq!(ctlz_nonzero(10u128), 124); assert_eq!(ctlz_nonzero(10i128), 124); + + assert_eq!(ctlz_nonzero(100u8), 1); assert_eq!(ctlz_nonzero(100i8), 1); + assert_eq!(ctlz_nonzero(100u16), 9); assert_eq!(ctlz_nonzero(100i16), 9); + assert_eq!(ctlz_nonzero(100u32), 25); assert_eq!(ctlz_nonzero(100i32), 25); + assert_eq!(ctlz_nonzero(100u64), 57); assert_eq!(ctlz_nonzero(100i64), 57); + assert_eq!(ctlz_nonzero(100u128), 121); assert_eq!(ctlz_nonzero(100i128), 121); + } + + assert_eq!(cttz(-1i8 as u8), 0); assert_eq!(cttz(-1i8), 0); + assert_eq!(cttz(-1i16 as u16), 0); assert_eq!(cttz(-1i16), 0); + assert_eq!(cttz(-1i32 as u32), 0); assert_eq!(cttz(-1i32), 0); + assert_eq!(cttz(-1i64 as u64), 0); assert_eq!(cttz(-1i64), 0); + assert_eq!(cttz(-1i128 as u128), 0); assert_eq!(cttz(-1i128), 0); + + assert_eq!(cttz(0u8), 8); assert_eq!(cttz(0i8), 8); + assert_eq!(cttz(0u16), 16); assert_eq!(cttz(0i16), 16); + assert_eq!(cttz(0u32), 32); assert_eq!(cttz(0i32), 32); + assert_eq!(cttz(0u64), 64); assert_eq!(cttz(0i64), 64); + assert_eq!(cttz(0u128), 128); assert_eq!(cttz(0i128), 128); + + assert_eq!(cttz(1u8), 0); assert_eq!(cttz(1i8), 0); + assert_eq!(cttz(1u16), 0); assert_eq!(cttz(1i16), 0); + assert_eq!(cttz(1u32), 0); assert_eq!(cttz(1i32), 0); + assert_eq!(cttz(1u64), 0); assert_eq!(cttz(1i64), 0); + assert_eq!(cttz(1u128), 0); assert_eq!(cttz(1i128), 0); + + assert_eq!(cttz(10u8), 1); assert_eq!(cttz(10i8), 1); + assert_eq!(cttz(10u16), 1); assert_eq!(cttz(10i16), 1); + assert_eq!(cttz(10u32), 1); assert_eq!(cttz(10i32), 1); + assert_eq!(cttz(10u64), 1); assert_eq!(cttz(10i64), 1); + assert_eq!(cttz(10u128), 1); assert_eq!(cttz(10i128), 1); + + assert_eq!(cttz(100u8), 2); assert_eq!(cttz(100i8), 2); + assert_eq!(cttz(100u16), 2); assert_eq!(cttz(100i16), 2); + assert_eq!(cttz(100u32), 2); assert_eq!(cttz(100i32), 2); + assert_eq!(cttz(100u64), 2); assert_eq!(cttz(100i64), 2); + assert_eq!(cttz(100u128), 2); assert_eq!(cttz(100i128), 2); + + unsafe { + assert_eq!(cttz_nonzero(-1i8 as u8), 0); assert_eq!(cttz_nonzero(-1i8), 0); + assert_eq!(cttz_nonzero(-1i16 as u16), 0); assert_eq!(cttz_nonzero(-1i16), 0); + assert_eq!(cttz_nonzero(-1i32 as u32), 0); assert_eq!(cttz_nonzero(-1i32), 0); + assert_eq!(cttz_nonzero(-1i64 as u64), 0); assert_eq!(cttz_nonzero(-1i64), 0); + assert_eq!(cttz_nonzero(-1i128 as u128), 0); assert_eq!(cttz_nonzero(-1i128), 0); + + assert_eq!(cttz_nonzero(1u8), 0); assert_eq!(cttz_nonzero(1i8), 0); + assert_eq!(cttz_nonzero(1u16), 0); assert_eq!(cttz_nonzero(1i16), 0); + assert_eq!(cttz_nonzero(1u32), 0); assert_eq!(cttz_nonzero(1i32), 0); + assert_eq!(cttz_nonzero(1u64), 0); assert_eq!(cttz_nonzero(1i64), 0); + assert_eq!(cttz_nonzero(1u128), 0); assert_eq!(cttz_nonzero(1i128), 0); + + assert_eq!(cttz_nonzero(10u8), 1); assert_eq!(cttz_nonzero(10i8), 1); + assert_eq!(cttz_nonzero(10u16), 1); assert_eq!(cttz_nonzero(10i16), 1); + assert_eq!(cttz_nonzero(10u32), 1); assert_eq!(cttz_nonzero(10i32), 1); + assert_eq!(cttz_nonzero(10u64), 1); assert_eq!(cttz_nonzero(10i64), 1); + assert_eq!(cttz_nonzero(10u128), 1); assert_eq!(cttz_nonzero(10i128), 1); + + assert_eq!(cttz_nonzero(100u8), 2); assert_eq!(cttz_nonzero(100i8), 2); + assert_eq!(cttz_nonzero(100u16), 2); assert_eq!(cttz_nonzero(100i16), 2); + assert_eq!(cttz_nonzero(100u32), 2); assert_eq!(cttz_nonzero(100i32), 2); + assert_eq!(cttz_nonzero(100u64), 2); assert_eq!(cttz_nonzero(100i64), 2); + assert_eq!(cttz_nonzero(100u128), 2); assert_eq!(cttz_nonzero(100i128), 2); + } + + assert_eq!(bswap(0x0Au8), 0x0A); // no-op + assert_eq!(bswap(0x0Ai8), 0x0A); // no-op + assert_eq!(bswap(0x0A0Bu16), 0x0B0A); + assert_eq!(bswap(0x0A0Bi16), 0x0B0A); + assert_eq!(bswap(0x0ABBCC0Du32), 0x0DCCBB0A); + assert_eq!(bswap(0x0ABBCC0Di32), 0x0DCCBB0A); + assert_eq!(bswap(0x0122334455667708u64), 0x0877665544332201); + assert_eq!(bswap(0x0122334455667708i64), 0x0877665544332201); + assert_eq!(bswap(0x0122334455667708u128), 0x08776655443322010000000000000000); + assert_eq!(bswap(0x0122334455667708i128), 0x08776655443322010000000000000000); + + assert_eq!(bitreverse(0x0Au8), 0x50); + assert_eq!(bitreverse(0x0Ai8), 0x50); + assert_eq!(bitreverse(0x0A0Cu16), 0x3050); + assert_eq!(bitreverse(0x0A0Ci16), 0x3050); + assert_eq!(bitreverse(0x0ABBCC0Eu32), 0x7033DD50); + assert_eq!(bitreverse(0x0ABBCC0Ei32), 0x7033DD50); + assert_eq!(bitreverse(0x0122334455667708u64), 0x10EE66AA22CC4480); + assert_eq!(bitreverse(0x0122334455667708i64), 0x10EE66AA22CC4480); + assert_eq!(bitreverse(0x0122334455667708u128), 0x10EE66AA22CC44800000000000000000); + assert_eq!(bitreverse(0x0122334455667708i128), 0x10EE66AA22CC44800000000000000000); +} diff --git a/tests/ui/intrinsics/intrinsics-math.rs b/tests/ui/intrinsics/intrinsics-math.rs new file mode 100644 index 000000000..aea9fde69 --- /dev/null +++ b/tests/ui/intrinsics/intrinsics-math.rs @@ -0,0 +1,60 @@ +// run-pass +// ignore-emscripten fma not implemented in emscripten + +macro_rules! assert_approx_eq { + ($a:expr, $b:expr) => ({ + let (a, b) = (&$a, &$b); + assert!((*a - *b).abs() < 1.0e-6, + "{} is not approximately equal to {}", *a, *b); + }) +} + +pub fn main() { + use std::f32; + use std::f64; + + assert_approx_eq!(64f32.sqrt(), 8f32); + assert_approx_eq!(64f64.sqrt(), 8f64); + + assert_approx_eq!(25f32.powi(-2), 0.0016f32); + assert_approx_eq!(23.2f64.powi(2), 538.24f64); + + assert_approx_eq!(0f32.sin(), 0f32); + assert_approx_eq!((f64::consts::PI / 2f64).sin(), 1f64); + + assert_approx_eq!(0f32.cos(), 1f32); + assert_approx_eq!((f64::consts::PI * 2f64).cos(), 1f64); + + assert_approx_eq!(25f32.powf(-2f32), 0.0016f32); + assert_approx_eq!(400f64.powf(0.5f64), 20f64); + + assert_approx_eq!((1f32.exp() - f32::consts::E).abs(), 0f32); + assert_approx_eq!(1f64.exp(), f64::consts::E); + + assert_approx_eq!(10f32.exp2(), 1024f32); + assert_approx_eq!(50f64.exp2(), 1125899906842624f64); + + assert_approx_eq!((f32::consts::E.ln() - 1f32).abs(), 0f32); + assert_approx_eq!(1f64.ln(), 0f64); + + assert_approx_eq!(10f32.log10(), 1f32); + assert_approx_eq!(f64::consts::E.log10(), f64::consts::LOG10_E); + + assert_approx_eq!(8f32.log2(), 3f32); + assert_approx_eq!(f64::consts::E.log2(), f64::consts::LOG2_E); + + assert_approx_eq!(1.0f32.mul_add(2.0f32, 5.0f32), 7.0f32); + assert_approx_eq!(0.0f64.mul_add(-2.0f64, f64::consts::E), f64::consts::E); + + assert_approx_eq!((-1.0f32).abs(), 1.0f32); + assert_approx_eq!(34.2f64.abs(), 34.2f64); + + assert_approx_eq!(3.8f32.floor(), 3.0f32); + assert_approx_eq!((-1.1f64).floor(), -2.0f64); + + assert_approx_eq!((-2.3f32).ceil(), -2.0f32); + assert_approx_eq!(3.8f64.ceil(), 4.0f64); + + assert_approx_eq!(0.1f32.trunc(), 0.0f32); + assert_approx_eq!((-0.1f64).trunc(), 0.0f64); +} diff --git a/tests/ui/intrinsics/issue-28575.mir.stderr b/tests/ui/intrinsics/issue-28575.mir.stderr new file mode 100644 index 000000000..c42498390 --- /dev/null +++ b/tests/ui/intrinsics/issue-28575.mir.stderr @@ -0,0 +1,11 @@ +error[E0133]: use of extern static is unsafe and requires unsafe function or block + --> $DIR/issue-28575.rs:11:5 + | +LL | FOO() + | ^^^ use of extern static + | + = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/intrinsics/issue-28575.rs b/tests/ui/intrinsics/issue-28575.rs new file mode 100644 index 000000000..410f664f8 --- /dev/null +++ b/tests/ui/intrinsics/issue-28575.rs @@ -0,0 +1,12 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +#![feature(intrinsics)] + +extern "C" { + pub static FOO: extern "rust-intrinsic" fn(); +} + +fn main() { + FOO() //~ ERROR: use of extern static is unsafe +} diff --git a/tests/ui/intrinsics/issue-28575.thir.stderr b/tests/ui/intrinsics/issue-28575.thir.stderr new file mode 100644 index 000000000..c42498390 --- /dev/null +++ b/tests/ui/intrinsics/issue-28575.thir.stderr @@ -0,0 +1,11 @@ +error[E0133]: use of extern static is unsafe and requires unsafe function or block + --> $DIR/issue-28575.rs:11:5 + | +LL | FOO() + | ^^^ use of extern static + | + = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/intrinsics/issue-84297-reifying-copy.rs b/tests/ui/intrinsics/issue-84297-reifying-copy.rs new file mode 100644 index 000000000..08ba9ce7e --- /dev/null +++ b/tests/ui/intrinsics/issue-84297-reifying-copy.rs @@ -0,0 +1,9 @@ +// check-pass + +fn main() { + let _unused = if true { + core::ptr::copy::<i32> + } else { + core::ptr::copy_nonoverlapping::<i32> + }; +} diff --git a/tests/ui/intrinsics/non-integer-atomic.rs b/tests/ui/intrinsics/non-integer-atomic.rs new file mode 100644 index 000000000..85ea81ba6 --- /dev/null +++ b/tests/ui/intrinsics/non-integer-atomic.rs @@ -0,0 +1,92 @@ +// build-fail + +#![feature(core_intrinsics)] +#![allow(warnings)] +#![crate_type = "rlib"] + +use std::intrinsics; + +#[derive(Copy, Clone)] +pub struct Foo(i64); +pub type Bar = &'static Fn(); +pub type Quux = [u8; 100]; + +pub unsafe fn test_bool_load(p: &mut bool, v: bool) { + intrinsics::atomic_load_seqcst(p); + //~^ ERROR `atomic_load_seqcst` intrinsic: expected basic integer type, found `bool` +} + +pub unsafe fn test_bool_store(p: &mut bool, v: bool) { + intrinsics::atomic_store_seqcst(p, v); + //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `bool` +} + +pub unsafe fn test_bool_xchg(p: &mut bool, v: bool) { + intrinsics::atomic_xchg_seqcst(p, v); + //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `bool` +} + +pub unsafe fn test_bool_cxchg(p: &mut bool, v: bool) { + intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); + //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `bool` +} + +pub unsafe fn test_Foo_load(p: &mut Foo, v: Foo) { + intrinsics::atomic_load_seqcst(p); + //~^ ERROR `atomic_load_seqcst` intrinsic: expected basic integer type, found `Foo` +} + +pub unsafe fn test_Foo_store(p: &mut Foo, v: Foo) { + intrinsics::atomic_store_seqcst(p, v); + //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `Foo` +} + +pub unsafe fn test_Foo_xchg(p: &mut Foo, v: Foo) { + intrinsics::atomic_xchg_seqcst(p, v); + //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `Foo` +} + +pub unsafe fn test_Foo_cxchg(p: &mut Foo, v: Foo) { + intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); + //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `Foo` +} + +pub unsafe fn test_Bar_load(p: &mut Bar, v: Bar) { + intrinsics::atomic_load_seqcst(p); + //~^ ERROR expected basic integer type, found `&dyn Fn()` +} + +pub unsafe fn test_Bar_store(p: &mut Bar, v: Bar) { + intrinsics::atomic_store_seqcst(p, v); + //~^ ERROR expected basic integer type, found `&dyn Fn()` +} + +pub unsafe fn test_Bar_xchg(p: &mut Bar, v: Bar) { + intrinsics::atomic_xchg_seqcst(p, v); + //~^ ERROR expected basic integer type, found `&dyn Fn()` +} + +pub unsafe fn test_Bar_cxchg(p: &mut Bar, v: Bar) { + intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); + //~^ ERROR expected basic integer type, found `&dyn Fn()` +} + +pub unsafe fn test_Quux_load(p: &mut Quux, v: Quux) { + intrinsics::atomic_load_seqcst(p); + //~^ ERROR `atomic_load_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` +} + +pub unsafe fn test_Quux_store(p: &mut Quux, v: Quux) { + intrinsics::atomic_store_seqcst(p, v); + //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` +} + +pub unsafe fn test_Quux_xchg(p: &mut Quux, v: Quux) { + intrinsics::atomic_xchg_seqcst(p, v); + //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` +} + +pub unsafe fn test_Quux_cxchg(p: &mut Quux, v: Quux) { + intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); + //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` +} diff --git a/tests/ui/intrinsics/non-integer-atomic.stderr b/tests/ui/intrinsics/non-integer-atomic.stderr new file mode 100644 index 000000000..32791a8e8 --- /dev/null +++ b/tests/ui/intrinsics/non-integer-atomic.stderr @@ -0,0 +1,99 @@ +error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `bool` + --> $DIR/non-integer-atomic.rs:15:5 + | +LL | intrinsics::atomic_load_seqcst(p); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `bool` + --> $DIR/non-integer-atomic.rs:20:5 + | +LL | intrinsics::atomic_store_seqcst(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `bool` + --> $DIR/non-integer-atomic.rs:25:5 + | +LL | intrinsics::atomic_xchg_seqcst(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `bool` + --> $DIR/non-integer-atomic.rs:30:5 + | +LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `Foo` + --> $DIR/non-integer-atomic.rs:35:5 + | +LL | intrinsics::atomic_load_seqcst(p); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `Foo` + --> $DIR/non-integer-atomic.rs:40:5 + | +LL | intrinsics::atomic_store_seqcst(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `Foo` + --> $DIR/non-integer-atomic.rs:45:5 + | +LL | intrinsics::atomic_xchg_seqcst(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `Foo` + --> $DIR/non-integer-atomic.rs:50:5 + | +LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()` + --> $DIR/non-integer-atomic.rs:55:5 + | +LL | intrinsics::atomic_load_seqcst(p); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()` + --> $DIR/non-integer-atomic.rs:60:5 + | +LL | intrinsics::atomic_store_seqcst(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()` + --> $DIR/non-integer-atomic.rs:65:5 + | +LL | intrinsics::atomic_xchg_seqcst(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()` + --> $DIR/non-integer-atomic.rs:70:5 + | +LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` + --> $DIR/non-integer-atomic.rs:75:5 + | +LL | intrinsics::atomic_load_seqcst(p); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` + --> $DIR/non-integer-atomic.rs:80:5 + | +LL | intrinsics::atomic_store_seqcst(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` + --> $DIR/non-integer-atomic.rs:85:5 + | +LL | intrinsics::atomic_xchg_seqcst(p, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `[u8; 100]` + --> $DIR/non-integer-atomic.rs:90:5 + | +LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 16 previous errors + +For more information about this error, try `rustc --explain E0511`. diff --git a/tests/ui/intrinsics/panic-uninitialized-zeroed.rs b/tests/ui/intrinsics/panic-uninitialized-zeroed.rs new file mode 100644 index 000000000..1a0104b85 --- /dev/null +++ b/tests/ui/intrinsics/panic-uninitialized-zeroed.rs @@ -0,0 +1,397 @@ +// run-pass +// revisions: default strict +// [strict]compile-flags: -Zstrict-init-checks +// ignore-tidy-linelength +// ignore-emscripten spawning processes is not supported +// ignore-sgx no processes + +// This test checks panic emitted from `mem::{uninitialized,zeroed}`. + +#![feature(never_type)] +#![allow(deprecated, invalid_value)] + +use std::{ + mem::{self, MaybeUninit, ManuallyDrop}, + ptr::NonNull, + num, +}; + +#[allow(dead_code)] +struct Foo { + x: u8, + y: !, +} + +enum Bar {} + +#[allow(dead_code)] +enum OneVariant { Variant(i32) } + +#[allow(dead_code, non_camel_case_types)] +enum OneVariant_NonZero { + Variant(i32, i32, num::NonZeroI32), + DeadVariant(Bar), +} + +#[allow(dead_code, non_camel_case_types)] +enum OneVariant_Ref { + Variant(&'static i32), + DeadVariant(Bar), +} + +// An `Aggregate` abi enum where 0 is not a valid discriminant. +#[allow(dead_code)] +#[repr(i32)] +enum NoNullVariant { + Variant1(i32, i32) = 1, + Variant2(i32, i32) = 2, +} + +// An enum with ScalarPair layout +#[allow(dead_code)] +enum LR { + Left(i64), + Right(i64), +} +#[allow(dead_code, non_camel_case_types)] +enum LR_NonZero { + Left(num::NonZeroI64), + Right(num::NonZeroI64), +} + +struct ZeroSized; + +#[allow(dead_code)] +#[repr(i32)] +enum ZeroIsValid { + Zero(u8) = 0, + One(NonNull<()>) = 1, +} + +#[track_caller] +fn test_panic_msg<T, F: (FnOnce() -> T) + 'static>(op: F, msg: &str) { + use std::{panic, env, process}; + + // The tricky part is that we can't just run `op`, as that would *abort* the process. + // So instead, we reinvoke this process with the caller location as argument. + // For the purpose of this test, the line number is unique enough. + // If we are running in such a re-invocation, we skip all the tests *except* for the one with that type name. + let our_loc = panic::Location::caller().line().to_string(); + let mut args = env::args(); + let this = args.next().unwrap(); + if let Some(loc) = args.next() { + if loc == our_loc { + op(); + panic!("we did not abort"); + } else { + // Nothing, we are running another test. + } + } else { + // Invoke new process for actual test, and check result. + let mut cmd = process::Command::new(this); + cmd.arg(our_loc); + let res = cmd.output().unwrap(); + assert!(!res.status.success(), "test did not fail"); + let stderr = String::from_utf8_lossy(&res.stderr); + assert!(stderr.contains(msg), "test did not contain expected output: looking for {:?}, output:\n{}", msg, stderr); + } +} + +#[track_caller] +fn test_panic_msg_only_if_strict<T>(op: impl (FnOnce() -> T) + 'static, msg: &str) { + if !cfg!(strict) { + // Just run it. + op(); + } else { + test_panic_msg(op, msg); + } +} + +fn main() { + unsafe { + // Uninhabited types + test_panic_msg( + || mem::uninitialized::<!>(), + "attempted to instantiate uninhabited type `!`" + ); + test_panic_msg( + || mem::zeroed::<!>(), + "attempted to instantiate uninhabited type `!`" + ); + test_panic_msg( + || MaybeUninit::<!>::uninit().assume_init(), + "attempted to instantiate uninhabited type `!`" + ); + + test_panic_msg( + || mem::uninitialized::<Foo>(), + "attempted to instantiate uninhabited type `Foo`" + ); + test_panic_msg( + || mem::zeroed::<Foo>(), + "attempted to instantiate uninhabited type `Foo`" + ); + test_panic_msg( + || MaybeUninit::<Foo>::uninit().assume_init(), + "attempted to instantiate uninhabited type `Foo`" + ); + + test_panic_msg( + || mem::uninitialized::<Bar>(), + "attempted to instantiate uninhabited type `Bar`" + ); + test_panic_msg( + || mem::zeroed::<Bar>(), + "attempted to instantiate uninhabited type `Bar`" + ); + test_panic_msg( + || MaybeUninit::<Bar>::uninit().assume_init(), + "attempted to instantiate uninhabited type `Bar`" + ); + + test_panic_msg( + || mem::uninitialized::<[Foo; 2]>(), + "attempted to instantiate uninhabited type `[Foo; 2]`" + ); + test_panic_msg( + || mem::zeroed::<[Foo; 2]>(), + "attempted to instantiate uninhabited type `[Foo; 2]`" + ); + test_panic_msg( + || MaybeUninit::<[Foo; 2]>::uninit().assume_init(), + "attempted to instantiate uninhabited type `[Foo; 2]`" + ); + + test_panic_msg( + || mem::uninitialized::<[Bar; 2]>(), + "attempted to instantiate uninhabited type `[Bar; 2]`" + ); + test_panic_msg( + || mem::zeroed::<[Bar; 2]>(), + "attempted to instantiate uninhabited type `[Bar; 2]`" + ); + test_panic_msg( + || MaybeUninit::<[Bar; 2]>::uninit().assume_init(), + "attempted to instantiate uninhabited type `[Bar; 2]`" + ); + + // Types that don't allow either. + test_panic_msg( + || mem::zeroed::<&i32>(), + "attempted to zero-initialize type `&i32`, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<&i32>(), + "attempted to leave type `&i32` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<Box<[i32; 0]>>(), + "attempted to zero-initialize type `alloc::boxed::Box<[i32; 0]>`, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<Box<[i32; 0]>>(), + "attempted to leave type `alloc::boxed::Box<[i32; 0]>` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<Box<u8>>(), + "attempted to zero-initialize type `alloc::boxed::Box<u8>`, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<Box<u8>>(), + "attempted to leave type `alloc::boxed::Box<u8>` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<&[i32]>(), + "attempted to zero-initialize type `&[i32]`, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<&[i32]>(), + "attempted to leave type `&[i32]` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<&(u8, [u8])>(), + "attempted to zero-initialize type `&(u8, [u8])`, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<&(u8, [u8])>(), + "attempted to leave type `&(u8, [u8])` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<&dyn Send>(), + "attempted to zero-initialize type `&dyn core::marker::Send`, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<&dyn Send>(), + "attempted to leave type `&dyn core::marker::Send` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<*const dyn Send>(), + "attempted to zero-initialize type `*const dyn core::marker::Send`, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<*const dyn Send>(), + "attempted to leave type `*const dyn core::marker::Send` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::uninitialized::<NoNullVariant>(), + "attempted to leave type `NoNullVariant` uninitialized, \ + which is invalid" + ); + test_panic_msg( + || mem::zeroed::<NoNullVariant>(), + "attempted to zero-initialize type `NoNullVariant`, \ + which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<OneVariant_Ref>(), + "attempted to zero-initialize type `OneVariant_Ref`, \ + which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<OneVariant_Ref>(), + "attempted to leave type `OneVariant_Ref` uninitialized, which is invalid" + ); + + // Types where both are invalid, but we allow uninit since the 0x01-filling is not LLVM UB. + test_panic_msg( + || mem::zeroed::<fn()>(), + "attempted to zero-initialize type `fn()`, which is invalid" + ); + test_panic_msg_only_if_strict( + || mem::uninitialized::<fn()>(), + "attempted to leave type `fn()` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<&()>(), + "attempted to zero-initialize type `&()`, which is invalid" + ); + test_panic_msg_only_if_strict( + || mem::uninitialized::<&()>(), + "attempted to leave type `&()` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<&[u8]>(), + "attempted to zero-initialize type `&[u8]`, which is invalid" + ); + test_panic_msg_only_if_strict( + || mem::uninitialized::<&[u8]>(), + "attempted to leave type `&[u8]` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<&str>(), + "attempted to zero-initialize type `&str`, which is invalid" + ); + test_panic_msg_only_if_strict( + || mem::uninitialized::<&str>(), + "attempted to leave type `&str` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<(NonNull<u32>, u32, u32)>(), + "attempted to zero-initialize type `(core::ptr::non_null::NonNull<u32>, u32, u32)`, \ + which is invalid" + ); + test_panic_msg_only_if_strict( + || mem::uninitialized::<(NonNull<u32>, u32, u32)>(), + "attempted to leave type `(core::ptr::non_null::NonNull<u32>, u32, u32)` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<OneVariant_NonZero>(), + "attempted to zero-initialize type `OneVariant_NonZero`, \ + which is invalid" + ); + test_panic_msg_only_if_strict( + || mem::uninitialized::<OneVariant_NonZero>(), + "attempted to leave type `OneVariant_NonZero` uninitialized, which is invalid" + ); + + // Types where both are invalid but we allow the zeroed form since it is not LLVM UB. + test_panic_msg_only_if_strict( + || mem::zeroed::<LR_NonZero>(), + "attempted to zero-initialize type `LR_NonZero`, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<LR_NonZero>(), + "attempted to leave type `LR_NonZero` uninitialized, which is invalid" + ); + + test_panic_msg_only_if_strict( + || mem::zeroed::<ManuallyDrop<LR_NonZero>>(), + "attempted to zero-initialize type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>`, \ + which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<ManuallyDrop<LR_NonZero>>(), + "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>` uninitialized, \ + which is invalid" + ); + + // Some strict-only things + test_panic_msg_only_if_strict( + || mem::uninitialized::<i32>(), + "attempted to leave type `i32` uninitialized, which is invalid" + ); + + test_panic_msg_only_if_strict( + || mem::uninitialized::<*const ()>(), + "attempted to leave type `*const ()` uninitialized, which is invalid" + ); + + test_panic_msg_only_if_strict( + || mem::uninitialized::<[i32; 1]>(), + "attempted to leave type `[i32; 1]` uninitialized, which is invalid" + ); + + test_panic_msg_only_if_strict( + || mem::zeroed::<[NonNull<()>; 1]>(), + "attempted to zero-initialize type `[core::ptr::non_null::NonNull<()>; 1]`, which is invalid" + ); + + // Types that can be zero, but not uninit (though some are mitigated). + let _val = mem::zeroed::<LR>(); + test_panic_msg( + || mem::uninitialized::<LR>(), + "attempted to leave type `LR` uninitialized, which is invalid" + ); + + let _val = mem::zeroed::<ManuallyDrop<LR>>(); + test_panic_msg( + || mem::uninitialized::<ManuallyDrop<LR>>(), + "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR>` uninitialized, which is invalid" + ); + + let _val = mem::zeroed::<bool>(); + test_panic_msg_only_if_strict( + || mem::uninitialized::<bool>(), + "attempted to leave type `bool` uninitialized, which is invalid" + ); + + let _val = mem::zeroed::<OneVariant>(); + test_panic_msg_only_if_strict( + || mem::uninitialized::<OneVariant>(), + "attempted to leave type `OneVariant` uninitialized, which is invalid" + ); + + // Some things that are actually allowed. + let _val = mem::zeroed::<Option<&'static i32>>(); + let _val = mem::zeroed::<MaybeUninit<NonNull<u32>>>(); + let _val = mem::zeroed::<[!; 0]>(); + let _val = mem::zeroed::<ZeroIsValid>(); + let _val = mem::uninitialized::<MaybeUninit<bool>>(); + let _val = mem::uninitialized::<[!; 0]>(); + let _val = mem::uninitialized::<()>(); + let _val = mem::uninitialized::<ZeroSized>(); + } +} diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs new file mode 100644 index 000000000..50e12eaeb --- /dev/null +++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs @@ -0,0 +1,11 @@ +#![feature(intrinsics)] +#![feature(rustc_attrs)] + +extern "rust-intrinsic" { + fn size_of<T>() -> usize; //~ ERROR intrinsic safety mismatch + + #[rustc_safe_intrinsic] + fn assume(b: bool); //~ ERROR intrinsic safety mismatch +} + +fn main() {} diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr b/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr new file mode 100644 index 000000000..0c2f3be49 --- /dev/null +++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr @@ -0,0 +1,14 @@ +error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of` + --> $DIR/safe-intrinsic-mismatch.rs:5:5 + | +LL | fn size_of<T>() -> usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume` + --> $DIR/safe-intrinsic-mismatch.rs:8:5 + | +LL | fn assume(b: bool); + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/intrinsics/unchecked_math_unsafe.mir.stderr b/tests/ui/intrinsics/unchecked_math_unsafe.mir.stderr new file mode 100644 index 000000000..26b2f9f27 --- /dev/null +++ b/tests/ui/intrinsics/unchecked_math_unsafe.mir.stderr @@ -0,0 +1,27 @@ +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/unchecked_math_unsafe.rs:8:15 + | +LL | let add = std::intrinsics::unchecked_add(x, y); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/unchecked_math_unsafe.rs:9:15 + | +LL | let sub = std::intrinsics::unchecked_sub(x, y); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/unchecked_math_unsafe.rs:10:15 + | +LL | let mul = std::intrinsics::unchecked_mul(x, y); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/intrinsics/unchecked_math_unsafe.rs b/tests/ui/intrinsics/unchecked_math_unsafe.rs new file mode 100644 index 000000000..98d3a11ad --- /dev/null +++ b/tests/ui/intrinsics/unchecked_math_unsafe.rs @@ -0,0 +1,11 @@ +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck + +#![feature(core_intrinsics)] + +fn main() { + let (x, y) = (1u32, 2u32); + let add = std::intrinsics::unchecked_add(x, y); //~ ERROR call to unsafe function + let sub = std::intrinsics::unchecked_sub(x, y); //~ ERROR call to unsafe function + let mul = std::intrinsics::unchecked_mul(x, y); //~ ERROR call to unsafe function +} diff --git a/tests/ui/intrinsics/unchecked_math_unsafe.thir.stderr b/tests/ui/intrinsics/unchecked_math_unsafe.thir.stderr new file mode 100644 index 000000000..5c3728ccd --- /dev/null +++ b/tests/ui/intrinsics/unchecked_math_unsafe.thir.stderr @@ -0,0 +1,27 @@ +error[E0133]: call to unsafe function `unchecked_add` is unsafe and requires unsafe function or block + --> $DIR/unchecked_math_unsafe.rs:8:15 + | +LL | let add = std::intrinsics::unchecked_add(x, y); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function `unchecked_sub` is unsafe and requires unsafe function or block + --> $DIR/unchecked_math_unsafe.rs:9:15 + | +LL | let sub = std::intrinsics::unchecked_sub(x, y); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function `unchecked_mul` is unsafe and requires unsafe function or block + --> $DIR/unchecked_math_unsafe.rs:10:15 + | +LL | let mul = std::intrinsics::unchecked_mul(x, y); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/intrinsics/unchecked_math_unstable.rs b/tests/ui/intrinsics/unchecked_math_unstable.rs new file mode 100644 index 000000000..8869063d1 --- /dev/null +++ b/tests/ui/intrinsics/unchecked_math_unstable.rs @@ -0,0 +1,8 @@ +fn main() { + let (x, y) = (1u32, 2u32); + unsafe { + let add = std::intrinsics::unchecked_add(x, y); //~ ERROR use of unstable library feature + let sub = std::intrinsics::unchecked_sub(x, y); //~ ERROR use of unstable library feature + let mul = std::intrinsics::unchecked_mul(x, y); //~ ERROR use of unstable library feature + } +} diff --git a/tests/ui/intrinsics/unchecked_math_unstable.stderr b/tests/ui/intrinsics/unchecked_math_unstable.stderr new file mode 100644 index 000000000..a43aa16ae --- /dev/null +++ b/tests/ui/intrinsics/unchecked_math_unstable.stderr @@ -0,0 +1,27 @@ +error[E0658]: use of unstable library feature 'core_intrinsics': intrinsics are unlikely to ever be stabilized, instead they should be used through stabilized interfaces in the rest of the standard library + --> $DIR/unchecked_math_unstable.rs:4:19 + | +LL | let add = std::intrinsics::unchecked_add(x, y); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(core_intrinsics)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'core_intrinsics': intrinsics are unlikely to ever be stabilized, instead they should be used through stabilized interfaces in the rest of the standard library + --> $DIR/unchecked_math_unstable.rs:5:19 + | +LL | let sub = std::intrinsics::unchecked_sub(x, y); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(core_intrinsics)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'core_intrinsics': intrinsics are unlikely to ever be stabilized, instead they should be used through stabilized interfaces in the rest of the standard library + --> $DIR/unchecked_math_unstable.rs:6:19 + | +LL | let mul = std::intrinsics::unchecked_mul(x, y); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(core_intrinsics)]` to the crate attributes to enable + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. |