diff options
Diffstat (limited to 'tests/ui/codegen')
-rw-r--r-- | tests/ui/codegen/auxiliary/issue-97708-aux.rs | 41 | ||||
-rw-r--r-- | tests/ui/codegen/auxiliary/llvm_pr32379.rs | 5 | ||||
-rw-r--r-- | tests/ui/codegen/init-large-type.rs | 23 | ||||
-rw-r--r-- | tests/ui/codegen/issue-101585-128bit-repeat.rs | 14 | ||||
-rw-r--r-- | tests/ui/codegen/issue-16602-1.rs | 6 | ||||
-rw-r--r-- | tests/ui/codegen/issue-16602-2.rs | 12 | ||||
-rw-r--r-- | tests/ui/codegen/issue-16602-3.rs | 28 | ||||
-rw-r--r-- | tests/ui/codegen/issue-28950.rs | 22 | ||||
-rw-r--r-- | tests/ui/codegen/issue-55976.rs | 13 | ||||
-rw-r--r-- | tests/ui/codegen/issue-63787.rs | 36 | ||||
-rw-r--r-- | tests/ui/codegen/issue-64401.rs | 51 | ||||
-rw-r--r-- | tests/ui/codegen/issue-82859-slice-miscompile.rs | 19 | ||||
-rw-r--r-- | tests/ui/codegen/issue-88043-bb-does-not-have-terminator.rs | 35 | ||||
-rw-r--r-- | tests/ui/codegen/issue-97708.rs | 9 | ||||
-rw-r--r-- | tests/ui/codegen/issue-99551.rs | 20 | ||||
-rw-r--r-- | tests/ui/codegen/llvm-pr32379.rs | 14 |
16 files changed, 348 insertions, 0 deletions
diff --git a/tests/ui/codegen/auxiliary/issue-97708-aux.rs b/tests/ui/codegen/auxiliary/issue-97708-aux.rs new file mode 100644 index 000000000..e296bd391 --- /dev/null +++ b/tests/ui/codegen/auxiliary/issue-97708-aux.rs @@ -0,0 +1,41 @@ +use std::{ptr::NonNull, task::Poll}; + +struct TaskRef; + +struct Header { + vtable: &'static Vtable, +} + +struct Vtable { + poll: unsafe fn(TaskRef) -> Poll<()>, + deallocate: unsafe fn(NonNull<Header>), +} + +// in the "Header" type, which is a private type in maitake +impl Header { + pub(crate) const fn new_stub() -> Self { + unsafe fn nop(_ptr: TaskRef) -> Poll<()> { + Poll::Pending + } + + unsafe fn nop_deallocate(ptr: NonNull<Header>) { + unreachable!("stub task ({ptr:p}) should never be deallocated!"); + } + + Self { vtable: &Vtable { poll: nop, deallocate: nop_deallocate } } + } +} + +// This is a public type in `maitake` +#[repr(transparent)] +#[cfg_attr(loom, allow(dead_code))] +pub struct TaskStub { + hdr: Header, +} + +impl TaskStub { + /// Create a new unique stub [`Task`]. + pub const fn new() -> Self { + Self { hdr: Header::new_stub() } + } +} diff --git a/tests/ui/codegen/auxiliary/llvm_pr32379.rs b/tests/ui/codegen/auxiliary/llvm_pr32379.rs new file mode 100644 index 000000000..8e4297670 --- /dev/null +++ b/tests/ui/codegen/auxiliary/llvm_pr32379.rs @@ -0,0 +1,5 @@ +pub fn pr32379(mut data: u64, f1: bool, f2: bool) -> u64 { + if f1 { data &= !2; } + if f2 { data |= 2; } + data +} diff --git a/tests/ui/codegen/init-large-type.rs b/tests/ui/codegen/init-large-type.rs new file mode 100644 index 000000000..ce905572f --- /dev/null +++ b/tests/ui/codegen/init-large-type.rs @@ -0,0 +1,23 @@ +// compile-flags: -O +// run-pass + +#![allow(unused_must_use)] +// Makes sure that zero-initializing large types is reasonably fast, +// Doing it incorrectly causes massive slowdown in LLVM during +// optimisation. + +// pretty-expanded FIXME #23616 +// ignore-emscripten no threads support + +#![feature(intrinsics)] + +use std::{mem, thread}; + +const SIZE: usize = 1024 * 1024; + +fn main() { + // do the test in a new thread to avoid (spurious?) stack overflows + thread::spawn(|| { + let _memory: [u8; SIZE] = unsafe { mem::zeroed() }; + }).join(); +} diff --git a/tests/ui/codegen/issue-101585-128bit-repeat.rs b/tests/ui/codegen/issue-101585-128bit-repeat.rs new file mode 100644 index 000000000..c6a686597 --- /dev/null +++ b/tests/ui/codegen/issue-101585-128bit-repeat.rs @@ -0,0 +1,14 @@ +// Regression test for issue 101585. +// run-pass + +fn main() { + fn min_array_ok() -> [i128; 1] { + [i128::MIN] + } + assert_eq!(min_array_ok(), [-170141183460469231731687303715884105728i128]); + + fn min_array_nok() -> [i128; 1] { + [i128::MIN; 1] + } + assert_eq!(min_array_nok(), [-170141183460469231731687303715884105728i128]); +} diff --git a/tests/ui/codegen/issue-16602-1.rs b/tests/ui/codegen/issue-16602-1.rs new file mode 100644 index 000000000..dd64ee75b --- /dev/null +++ b/tests/ui/codegen/issue-16602-1.rs @@ -0,0 +1,6 @@ +// run-pass +fn main() { + let mut t = [1; 2]; + t = [t[1] * 2, t[0] * 2]; + assert_eq!(&t[..], &[2, 2]); +} diff --git a/tests/ui/codegen/issue-16602-2.rs b/tests/ui/codegen/issue-16602-2.rs new file mode 100644 index 000000000..6364630ff --- /dev/null +++ b/tests/ui/codegen/issue-16602-2.rs @@ -0,0 +1,12 @@ +// run-pass +struct A { + pub x: u32, + pub y: u32, +} + +fn main() { + let mut a = A { x: 1, y: 1 }; + a = A { x: a.y * 2, y: a.x * 2 }; + assert_eq!(a.x, 2); + assert_eq!(a.y, 2); +} diff --git a/tests/ui/codegen/issue-16602-3.rs b/tests/ui/codegen/issue-16602-3.rs new file mode 100644 index 000000000..ca1ab3cc7 --- /dev/null +++ b/tests/ui/codegen/issue-16602-3.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(unused_variables)] +#![allow(unused_assignments)] +#[derive(Debug)] +#[allow(unused_tuple_struct_fields)] +enum Foo { + Bar(u32, u32), + Baz(&'static u32, &'static u32) +} + +static NUM: u32 = 100; + +fn main () { + let mut b = Foo::Baz(&NUM, &NUM); + b = Foo::Bar(f(&b), g(&b)); +} + +static FNUM: u32 = 1; + +fn f (b: &Foo) -> u32 { + FNUM +} + +static GNUM: u32 = 2; + +fn g (b: &Foo) -> u32 { + GNUM +} diff --git a/tests/ui/codegen/issue-28950.rs b/tests/ui/codegen/issue-28950.rs new file mode 100644 index 000000000..8b55f42f3 --- /dev/null +++ b/tests/ui/codegen/issue-28950.rs @@ -0,0 +1,22 @@ +// run-pass +// ignore-emscripten no threads +// compile-flags: -O + +// Tests that the `vec!` macro does not overflow the stack when it is +// given data larger than the stack. + +// FIXME(eddyb) Improve unoptimized codegen to avoid the temporary, +// and thus run successfully even when compiled at -C opt-level=0. + +const LEN: usize = 1 << 15; + +use std::thread::Builder; + +fn main() { + assert!(Builder::new().stack_size(LEN / 2).spawn(|| { + // FIXME(eddyb) this can be vec![[0: LEN]] pending + // https://llvm.org/bugs/show_bug.cgi?id=28987 + let vec = vec![unsafe { std::mem::zeroed::<[u8; LEN]>() }]; + assert_eq!(vec.len(), 1); + }).unwrap().join().is_ok()); +} diff --git a/tests/ui/codegen/issue-55976.rs b/tests/ui/codegen/issue-55976.rs new file mode 100644 index 000000000..3142704b7 --- /dev/null +++ b/tests/ui/codegen/issue-55976.rs @@ -0,0 +1,13 @@ +// run-pass +// ^-- The above is needed as this issue is related to LLVM/codegen. +// min-llvm-version:15.0.0 +// ^-- The above is needed as this issue is fixed by the opaque pointers. + +fn main() { + type_error(|x| &x); +} + +fn type_error<T>( + _selector: for<'a> fn(&'a Vec<Box<dyn for<'b> Fn(&'b u8)>>) -> &'a Vec<Box<dyn Fn(T)>>, +) { +} diff --git a/tests/ui/codegen/issue-63787.rs b/tests/ui/codegen/issue-63787.rs new file mode 100644 index 000000000..cba079b23 --- /dev/null +++ b/tests/ui/codegen/issue-63787.rs @@ -0,0 +1,36 @@ +// run-pass +// compile-flags: -O + +// Make sure that `Ref` and `RefMut` do not make false promises about aliasing, +// because once they drop, their reference/pointer can alias other writes. + +// Adapted from comex's proof of concept: +// https://github.com/rust-lang/rust/issues/63787#issuecomment-523588164 + +use std::cell::RefCell; +use std::ops::Deref; + +pub fn break_if_r_is_noalias(rc: &RefCell<i32>, r: impl Deref<Target = i32>) -> i32 { + let ptr1 = &*r as *const i32; + let a = *r; + drop(r); + *rc.borrow_mut() = 2; + let r2 = rc.borrow(); + let ptr2 = &*r2 as *const i32; + if ptr2 != ptr1 { + panic!(); + } + // If LLVM knows the pointers are the same, and if `r` was `noalias`, + // then it may replace this with `a + a`, ignoring the earlier write. + a + *r2 +} + +fn main() { + let mut rc = RefCell::new(1); + let res = break_if_r_is_noalias(&rc, rc.borrow()); + assert_eq!(res, 3); + + *rc.get_mut() = 1; + let res = break_if_r_is_noalias(&rc, rc.borrow_mut()); + assert_eq!(res, 3); +} diff --git a/tests/ui/codegen/issue-64401.rs b/tests/ui/codegen/issue-64401.rs new file mode 100644 index 000000000..53f85c63b --- /dev/null +++ b/tests/ui/codegen/issue-64401.rs @@ -0,0 +1,51 @@ +// build-pass +// The ICE didn't happen with `cargo check` but `cargo build`. + +use std::marker::PhantomData; + +trait Owned<'a> { + type Reader; +} + +impl<'a> Owned<'a> for () { + type Reader = (); +} + +trait Handler { + fn handle(&self); +} + +struct CtxHandlerWithoutState<M, F> { + message_type: PhantomData<M>, + _function: F, +} + +impl<M, F> CtxHandlerWithoutState<M, F> { + pub fn new(_function: F) -> Self { + Self { + message_type: PhantomData, + _function, + } + } +} + +impl<'a, M, F> Handler for CtxHandlerWithoutState<M, F> +where + F: Fn(<M as Owned<'a>>::Reader), + M: Owned<'a>, +{ + fn handle(&self) {} +} + +fn e_to_i<M: for<'a> Owned<'a>>(_: <M as Owned<'_>>::Reader) {} + +fn send_external_to_internal<M>() +where + M: for<'a> Owned<'a>, +{ + let _: Box<dyn Handler> = Box::new(CtxHandlerWithoutState::<M, _>::new(e_to_i::<M>)); +} + +fn main() { + send_external_to_internal::<()>() +} diff --git a/tests/ui/codegen/issue-82859-slice-miscompile.rs b/tests/ui/codegen/issue-82859-slice-miscompile.rs new file mode 100644 index 000000000..b64eb4990 --- /dev/null +++ b/tests/ui/codegen/issue-82859-slice-miscompile.rs @@ -0,0 +1,19 @@ +// run-pass +// compile-flags: -Copt-level=0 -Cdebuginfo=2 + +// Make sure LLVM does not miscompile this. + +fn indirect_get_slice() -> &'static [usize] { + &[] +} + +#[inline(always)] +fn get_slice() -> &'static [usize] { + let ret = indirect_get_slice(); + ret +} + +fn main() { + let output = get_slice().len(); + assert_eq!(output, 0); +} diff --git a/tests/ui/codegen/issue-88043-bb-does-not-have-terminator.rs b/tests/ui/codegen/issue-88043-bb-does-not-have-terminator.rs new file mode 100644 index 000000000..38dfca347 --- /dev/null +++ b/tests/ui/codegen/issue-88043-bb-does-not-have-terminator.rs @@ -0,0 +1,35 @@ +// build-pass +// compile-flags: -Copt-level=0 + +// Regression test for #88043: LLVM crash when the RemoveZsts mir-opt pass is enabled. +// We should not see the error: +// `Basic Block in function '_ZN4main10take_until17h0067b8a660429bc9E' does not have terminator!` + +fn bump() -> Option<usize> { + unreachable!() +} + +fn take_until(terminate: impl Fn() -> bool) { + loop { + if terminate() { + return; + } else { + bump(); + } + } +} + +// CHECK-LABEL: @main +fn main() { + take_until(|| true); + f(None); +} + +fn f(_a: Option<String>) -> Option<u32> { + loop { + g(); + () + } +} + +fn g() -> Option<u32> { None } diff --git a/tests/ui/codegen/issue-97708.rs b/tests/ui/codegen/issue-97708.rs new file mode 100644 index 000000000..8cb28e9f1 --- /dev/null +++ b/tests/ui/codegen/issue-97708.rs @@ -0,0 +1,9 @@ +// build-pass +// aux-build:issue-97708-aux.rs + +extern crate issue_97708_aux; +use issue_97708_aux::TaskStub; + +static TASK_STUB: TaskStub = TaskStub::new(); + +fn main() {} diff --git a/tests/ui/codegen/issue-99551.rs b/tests/ui/codegen/issue-99551.rs new file mode 100644 index 000000000..b223aff4e --- /dev/null +++ b/tests/ui/codegen/issue-99551.rs @@ -0,0 +1,20 @@ +// build-pass +#![feature(trait_upcasting)] + +pub trait A {} +pub trait B {} + +pub trait C: A + B {} +impl<X: A + B> C for X {} + +pub fn test<'a, T>(view: T) -> Option<&'a mut dyn B> +where + T: IntoIterator<Item = &'a mut dyn B>, +{ + return Some(view.into_iter().next().unwrap()); +} + +fn main() { + let mut a: Vec<Box<dyn C>> = Vec::new(); + test(a.iter_mut().map(|c| c.as_mut() as &mut dyn B)); +} diff --git a/tests/ui/codegen/llvm-pr32379.rs b/tests/ui/codegen/llvm-pr32379.rs new file mode 100644 index 000000000..8a1f03241 --- /dev/null +++ b/tests/ui/codegen/llvm-pr32379.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:llvm_pr32379.rs + +// LLVM PR #32379 (https://bugs.llvm.org/show_bug.cgi?id=32379), which +// applies to upstream LLVM 3.9.1, is known to cause rustc itself to be +// miscompiled on ARM (Rust issue #40593). Because cross builds don't test +// our *compiler* on ARM, have a test for the miscompilation directly. + +extern crate llvm_pr32379; + +pub fn main() { + let val = llvm_pr32379::pr32379(2, false, false); + assert_eq!(val, 2); +} |