diff options
Diffstat (limited to 'tests/ui/lto')
32 files changed, 416 insertions, 0 deletions
diff --git a/tests/ui/lto/all-crates.rs b/tests/ui/lto/all-crates.rs new file mode 100644 index 000000000..e910b2a9f --- /dev/null +++ b/tests/ui/lto/all-crates.rs @@ -0,0 +1,8 @@ +// run-pass + +// compile-flags: -Clto=thin +// no-prefer-dynamic + +fn main() { + println!("hello!"); +} diff --git a/tests/ui/lto/auxiliary/debuginfo-lto-aux.rs b/tests/ui/lto/auxiliary/debuginfo-lto-aux.rs new file mode 100644 index 000000000..dd471154b --- /dev/null +++ b/tests/ui/lto/auxiliary/debuginfo-lto-aux.rs @@ -0,0 +1,29 @@ +// compile-flags: -g --crate-type=rlib + +pub struct StructWithLifetime<'a>(&'a i32); +pub fn mk_struct_with_lt<'a>(x: &'a i32) -> StructWithLifetime<'a> { + StructWithLifetime(x) +} + +pub struct RegularStruct(u32); +pub fn mk_regular_struct(x: u32) -> RegularStruct { + RegularStruct(x) +} + +pub fn take_fn(f: fn(i32) -> i32, x: i32) -> i32 { + f(x) +} + +pub fn with_closure(x: i32) -> i32 { + let closure = |i| { x + i }; + + closure(1) + closure(2) +} + +pub fn generic_fn<T>(x: T) -> (T, u32) { + (x, 1) +} + +pub fn user_of_generic_fn(x: f32) -> (f32, u32) { + generic_fn(x) +} diff --git a/tests/ui/lto/auxiliary/dylib.rs b/tests/ui/lto/auxiliary/dylib.rs new file mode 100644 index 000000000..e8b7f8f9f --- /dev/null +++ b/tests/ui/lto/auxiliary/dylib.rs @@ -0,0 +1,6 @@ +// compile-flags: -Z thinlto -C codegen-units=8 + +#[inline] +pub fn foo(b: u8) { + b.to_string(); +} diff --git a/tests/ui/lto/auxiliary/lto-duplicate-symbols1.rs b/tests/ui/lto/auxiliary/lto-duplicate-symbols1.rs new file mode 100644 index 000000000..ec6d05603 --- /dev/null +++ b/tests/ui/lto/auxiliary/lto-duplicate-symbols1.rs @@ -0,0 +1,6 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +#[no_mangle] +pub extern "C" fn foo() {} diff --git a/tests/ui/lto/auxiliary/lto-duplicate-symbols2.rs b/tests/ui/lto/auxiliary/lto-duplicate-symbols2.rs new file mode 100644 index 000000000..ec6d05603 --- /dev/null +++ b/tests/ui/lto/auxiliary/lto-duplicate-symbols2.rs @@ -0,0 +1,6 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +#[no_mangle] +pub extern "C" fn foo() {} diff --git a/tests/ui/lto/auxiliary/lto-rustc-loads-linker-plugin.rs b/tests/ui/lto/auxiliary/lto-rustc-loads-linker-plugin.rs new file mode 100644 index 000000000..d24375b2d --- /dev/null +++ b/tests/ui/lto/auxiliary/lto-rustc-loads-linker-plugin.rs @@ -0,0 +1,6 @@ +// compile-flags: -Clinker-plugin-lto +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn foo() {} diff --git a/tests/ui/lto/auxiliary/msvc-imp-present.rs b/tests/ui/lto/auxiliary/msvc-imp-present.rs new file mode 100644 index 000000000..933af050a --- /dev/null +++ b/tests/ui/lto/auxiliary/msvc-imp-present.rs @@ -0,0 +1,11 @@ +// no-prefer-dynamic +// compile-flags: -Z thinlto -C codegen-units=8 -C prefer-dynamic + +#![crate_type = "rlib"] +#![crate_type = "dylib"] + +pub static A: u32 = 43; + +pub mod a { + pub static A: u32 = 43; +} diff --git a/tests/ui/lto/auxiliary/thin-lto-inlines-aux.rs b/tests/ui/lto/auxiliary/thin-lto-inlines-aux.rs new file mode 100644 index 000000000..5fd3f1996 --- /dev/null +++ b/tests/ui/lto/auxiliary/thin-lto-inlines-aux.rs @@ -0,0 +1,7 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn bar() -> u32 { + 3 +} diff --git a/tests/ui/lto/auxiliary/thinlto-dylib.rs b/tests/ui/lto/auxiliary/thinlto-dylib.rs new file mode 100644 index 000000000..9d17c35da --- /dev/null +++ b/tests/ui/lto/auxiliary/thinlto-dylib.rs @@ -0,0 +1,23 @@ +// Auxiliary crate for test issue-105637: the LTOed dylib which had duplicate symbols from libstd, +// breaking the panic hook feature. +// +// This simulates the `rustc_driver` crate, and the main crate simulates rustc's main binary hooking +// into this driver. + +// compile-flags: -Zdylib-lto -C lto=thin + +use std::panic; + +pub fn main() { + // Install the hook we want to see executed + panic::set_hook(Box::new(|_| { + eprintln!("LTOed auxiliary crate panic hook"); + })); + + // Trigger the panic hook with an ICE + run_compiler(); +} + +fn run_compiler() { + panic!("ICEing"); +} diff --git a/tests/ui/lto/debuginfo-lto.rs b/tests/ui/lto/debuginfo-lto.rs new file mode 100644 index 000000000..43f75b034 --- /dev/null +++ b/tests/ui/lto/debuginfo-lto.rs @@ -0,0 +1,25 @@ +// run-pass +// This test case makes sure that we don't run into LLVM's dreaded +// "possible ODR violation" assertion when compiling with LTO + Debuginfo. +// It covers cases that have traditionally been prone to cause this error. +// If new cases emerge, add them to this file. + +// aux-build:debuginfo-lto-aux.rs +// compile-flags: -C lto -g +// no-prefer-dynamic +// ignore-asmjs wasm2js does not support source maps yet + +extern crate debuginfo_lto_aux; + +fn some_fn(x: i32) -> i32 { + x + 1 +} + +fn main() { + let i = 0; + let _ = debuginfo_lto_aux::mk_struct_with_lt(&i); + let _ = debuginfo_lto_aux::mk_regular_struct(1); + let _ = debuginfo_lto_aux::take_fn(some_fn, 1); + let _ = debuginfo_lto_aux::with_closure(22); + let _ = debuginfo_lto_aux::generic_fn(0f32); +} diff --git a/tests/ui/lto/dylib-works.rs b/tests/ui/lto/dylib-works.rs new file mode 100644 index 000000000..9e0782b59 --- /dev/null +++ b/tests/ui/lto/dylib-works.rs @@ -0,0 +1,9 @@ +// run-pass + +// aux-build:dylib.rs + +extern crate dylib; + +fn main() { + dylib::foo(1); +} diff --git a/tests/ui/lto/fat-lto.rs b/tests/ui/lto/fat-lto.rs new file mode 100644 index 000000000..c8d8095a2 --- /dev/null +++ b/tests/ui/lto/fat-lto.rs @@ -0,0 +1,7 @@ +// run-pass +// compile-flags: -Clto=fat +// no-prefer-dynamic + +fn main() { + println!("hello!"); +} diff --git a/tests/ui/lto/issue-100772.rs b/tests/ui/lto/issue-100772.rs new file mode 100644 index 000000000..d6b067192 --- /dev/null +++ b/tests/ui/lto/issue-100772.rs @@ -0,0 +1,11 @@ +// run-pass +// needs-sanitizer-cfi +// compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi +// no-prefer-dynamic +// only-x86_64-unknown-linux-gnu + +#![feature(allocator_api)] + +fn main() { + let _ = Box::new_in(&[0, 1], &std::alloc::Global); +} diff --git a/tests/ui/lto/issue-105637.rs b/tests/ui/lto/issue-105637.rs new file mode 100644 index 000000000..0d9f0bec0 --- /dev/null +++ b/tests/ui/lto/issue-105637.rs @@ -0,0 +1,28 @@ +// Regression test for issue #105637: `-Zdylib-lto` with LTO duplicated symbols from other dylibs, +// in this case from libstd. +// +// That manifested as both `rustc_driver` and rustc's "main" (`compiler/rustc`) having their own +// `std::panicking::HOOK` static, and the hook in rustc's main (the default stdlib's) being executed +// when rustc ICEs, instead of the overriden hook from `rustc_driver` (which also displays the query +// stack and information on how to open a GH issue for the encountered ICE). +// +// In this test, we reproduce this setup by installing a panic hook in both the main and an LTOed +// dylib: the last hook set should be the one being executed, the dylib's. + +// aux-build: thinlto-dylib.rs +// run-fail +// check-run-results + +extern crate thinlto_dylib; + +use std::panic; + +fn main() { + // We don't want to see this panic hook executed + std::panic::set_hook(Box::new(|_| { + eprintln!("main crate panic hook"); + })); + + // Have the LTOed dylib install its own hook and panic, we want to see its hook executed. + thinlto_dylib::main(); +} diff --git a/tests/ui/lto/issue-105637.run.stderr b/tests/ui/lto/issue-105637.run.stderr new file mode 100644 index 000000000..43388e776 --- /dev/null +++ b/tests/ui/lto/issue-105637.run.stderr @@ -0,0 +1 @@ +LTOed auxiliary crate panic hook diff --git a/tests/ui/lto/issue-11154.rs b/tests/ui/lto/issue-11154.rs new file mode 100644 index 000000000..e11cdc82f --- /dev/null +++ b/tests/ui/lto/issue-11154.rs @@ -0,0 +1,6 @@ +// build-fail +// compile-flags: -C lto -C prefer-dynamic + +// error-pattern: cannot prefer dynamic linking + +fn main() {} diff --git a/tests/ui/lto/issue-11154.stderr b/tests/ui/lto/issue-11154.stderr new file mode 100644 index 000000000..8eec8b37c --- /dev/null +++ b/tests/ui/lto/issue-11154.stderr @@ -0,0 +1,6 @@ +error: cannot prefer dynamic linking when performing LTO + +note: only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO + +error: aborting due to previous error + diff --git a/tests/ui/lto/lto-and-no-bitcode-in-rlib.rs b/tests/ui/lto/lto-and-no-bitcode-in-rlib.rs new file mode 100644 index 000000000..f381240e7 --- /dev/null +++ b/tests/ui/lto/lto-and-no-bitcode-in-rlib.rs @@ -0,0 +1,3 @@ +// compile-flags: -C lto -C embed-bitcode=no + +fn main() {} diff --git a/tests/ui/lto/lto-and-no-bitcode-in-rlib.stderr b/tests/ui/lto/lto-and-no-bitcode-in-rlib.stderr new file mode 100644 index 000000000..11e370e91 --- /dev/null +++ b/tests/ui/lto/lto-and-no-bitcode-in-rlib.stderr @@ -0,0 +1,2 @@ +error: options `-C embed-bitcode=no` and `-C lto` are incompatible + diff --git a/tests/ui/lto/lto-duplicate-symbols.rs b/tests/ui/lto/lto-duplicate-symbols.rs new file mode 100644 index 000000000..e540094a3 --- /dev/null +++ b/tests/ui/lto/lto-duplicate-symbols.rs @@ -0,0 +1,11 @@ +// build-fail +// aux-build:lto-duplicate-symbols1.rs +// aux-build:lto-duplicate-symbols2.rs +// error-pattern:Linking globals named 'foo': symbol multiply defined! +// compile-flags: -C lto +// no-prefer-dynamic +// normalize-stderr-test: "lto-duplicate-symbols2\.lto_duplicate_symbols2\.[0-9a-zA-Z]+-cgu" -> "lto-duplicate-symbols2.lto_duplicate_symbols2.HASH-cgu" +extern crate lto_duplicate_symbols1; +extern crate lto_duplicate_symbols2; + +fn main() {} diff --git a/tests/ui/lto/lto-duplicate-symbols.stderr b/tests/ui/lto/lto-duplicate-symbols.stderr new file mode 100644 index 000000000..f66afa94f --- /dev/null +++ b/tests/ui/lto/lto-duplicate-symbols.stderr @@ -0,0 +1,6 @@ +warning: Linking globals named 'foo': symbol multiply defined! + +error: failed to load bitcode of module "lto-duplicate-symbols2.lto_duplicate_symbols2.HASH-cgu.0.rcgu.o": + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/ui/lto/lto-many-codegen-units.rs b/tests/ui/lto/lto-many-codegen-units.rs new file mode 100644 index 000000000..f0f461ffe --- /dev/null +++ b/tests/ui/lto/lto-many-codegen-units.rs @@ -0,0 +1,6 @@ +// run-pass +// compile-flags: -C lto -C codegen-units=8 +// no-prefer-dynamic + +fn main() { +} diff --git a/tests/ui/lto/lto-opt-level-s.rs b/tests/ui/lto/lto-opt-level-s.rs new file mode 100644 index 000000000..a7d9d5024 --- /dev/null +++ b/tests/ui/lto/lto-opt-level-s.rs @@ -0,0 +1,7 @@ +// compile-flags: -Clinker-plugin-lto -Copt-level=s +// build-pass +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn foo() {} diff --git a/tests/ui/lto/lto-opt-level-z.rs b/tests/ui/lto/lto-opt-level-z.rs new file mode 100644 index 000000000..bf1f5e2b2 --- /dev/null +++ b/tests/ui/lto/lto-opt-level-z.rs @@ -0,0 +1,7 @@ +// compile-flags: -Clinker-plugin-lto -Copt-level=z +// build-pass +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn foo() {} diff --git a/tests/ui/lto/lto-rustc-loads-linker-plugin.rs b/tests/ui/lto/lto-rustc-loads-linker-plugin.rs new file mode 100644 index 000000000..6ef1d4540 --- /dev/null +++ b/tests/ui/lto/lto-rustc-loads-linker-plugin.rs @@ -0,0 +1,17 @@ +// compile-flags: -C lto +// aux-build:lto-rustc-loads-linker-plugin.rs +// run-pass +// no-prefer-dynamic + +// This test ensures that if a dependency was compiled with +// `-Clinker-plugin-lto` then we can compile with `-Clto` and still link against +// that upstream rlib. This should work because LTO implies we're not actually +// linking against upstream rlibs since we're generating the object code +// locally. This test will fail if rustc can't find bytecode in rlibs compiled +// with `-Clinker-plugin-lto`. + +extern crate lto_rustc_loads_linker_plugin; + +fn main() { + lto_rustc_loads_linker_plugin::foo(); +} diff --git a/tests/ui/lto/lto-still-runs-thread-dtors.rs b/tests/ui/lto/lto-still-runs-thread-dtors.rs new file mode 100644 index 000000000..1c7368b36 --- /dev/null +++ b/tests/ui/lto/lto-still-runs-thread-dtors.rs @@ -0,0 +1,34 @@ +// run-pass +// compile-flags: -C lto +// no-prefer-dynamic +// ignore-emscripten no threads support +// revisions: mir thir +// [thir]compile-flags: -Zthir-unsafeck + +use std::thread; + +static mut HIT: usize = 0; + +thread_local!(static A: Foo = Foo); + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) { + unsafe { + HIT += 1; + } + } +} + +fn main() { + unsafe { + assert_eq!(HIT, 0); + thread::spawn(|| { + assert_eq!(HIT, 0); + A.with(|_| ()); + assert_eq!(HIT, 0); + }).join().unwrap(); + assert_eq!(HIT, 1); + } +} diff --git a/tests/ui/lto/lto-thin-rustc-loads-linker-plugin.rs b/tests/ui/lto/lto-thin-rustc-loads-linker-plugin.rs new file mode 100644 index 000000000..4d54ce32f --- /dev/null +++ b/tests/ui/lto/lto-thin-rustc-loads-linker-plugin.rs @@ -0,0 +1,13 @@ +// compile-flags: -C lto=thin +// aux-build:lto-rustc-loads-linker-plugin.rs +// run-pass +// no-prefer-dynamic + +// Same as the adjacent `lto-thin-rustc-loads-linker-plugin.rs` test, only with +// ThinLTO. + +extern crate lto_rustc_loads_linker_plugin; + +fn main() { + lto_rustc_loads_linker_plugin::foo(); +} diff --git a/tests/ui/lto/msvc-imp-present.rs b/tests/ui/lto/msvc-imp-present.rs new file mode 100644 index 000000000..5498afb29 --- /dev/null +++ b/tests/ui/lto/msvc-imp-present.rs @@ -0,0 +1,22 @@ +// run-pass + +// aux-build:msvc-imp-present.rs +// compile-flags: -Z thinlto -C codegen-units=8 +// no-prefer-dynamic + +// On MSVC we have a "hack" where we emit symbols that look like `_imp_$name` +// for all exported statics. This is done because we apply `dllimport` to all +// imported constants and this allows everything to actually link correctly. +// +// The ThinLTO passes aggressively remove symbols if they can, and this test +// asserts that the ThinLTO passes don't remove these compiler-generated +// `_imp_*` symbols. The external library that we link in here is compiled with +// ThinLTO and multiple codegen units and has a few exported constants. Note +// that we also namely compile the library as both a dylib and an rlib, but we +// link the rlib to ensure that we assert those generated symbols exist. + +extern crate msvc_imp_present as bar; + +fn main() { + println!("{}", bar::A); +} diff --git a/tests/ui/lto/thin-lto-global-allocator.rs b/tests/ui/lto/thin-lto-global-allocator.rs new file mode 100644 index 000000000..e00c5caf9 --- /dev/null +++ b/tests/ui/lto/thin-lto-global-allocator.rs @@ -0,0 +1,7 @@ +// run-pass +// compile-flags: -Z thinlto -C codegen-units=2 + +#[global_allocator] +static A: std::alloc::System = std::alloc::System; + +fn main() {} diff --git a/tests/ui/lto/thin-lto-inlines.rs b/tests/ui/lto/thin-lto-inlines.rs new file mode 100644 index 000000000..dca791807 --- /dev/null +++ b/tests/ui/lto/thin-lto-inlines.rs @@ -0,0 +1,30 @@ +// run-pass + +// compile-flags: -Z thinlto -C codegen-units=8 -O +// ignore-emscripten can't inspect instructions on emscripten + +// We want to assert here that ThinLTO will inline across codegen units. There's +// not really a great way to do that in general so we sort of hack around it by +// praying two functions go into separate codegen units and then assuming that +// if inlining *doesn't* happen the first byte of the functions will differ. + +pub fn foo() -> u32 { + bar::bar() +} + +mod bar { + pub fn bar() -> u32 { + 3 + } +} + +fn main() { + println!("{} {}", foo(), bar::bar()); + + unsafe { + let foo = foo as usize as *const u8; + let bar = bar::bar as usize as *const u8; + + assert_eq!(*foo, *bar); + } +} diff --git a/tests/ui/lto/thin-lto-inlines2.rs b/tests/ui/lto/thin-lto-inlines2.rs new file mode 100644 index 000000000..1eb29657c --- /dev/null +++ b/tests/ui/lto/thin-lto-inlines2.rs @@ -0,0 +1,28 @@ +// run-pass + +// compile-flags: -C codegen-units=8 -O -C lto=thin +// aux-build:thin-lto-inlines-aux.rs +// no-prefer-dynamic +// ignore-emscripten can't inspect instructions on emscripten + +// We want to assert here that ThinLTO will inline across codegen units. There's +// not really a great way to do that in general so we sort of hack around it by +// praying two functions go into separate codegen units and then assuming that +// if inlining *doesn't* happen the first byte of the functions will differ. + +extern crate thin_lto_inlines_aux as bar; + +pub fn foo() -> u32 { + bar::bar() +} + +fn main() { + println!("{} {}", foo(), bar::bar()); + + unsafe { + let foo = foo as usize as *const u8; + let bar = bar::bar as usize as *const u8; + + assert_eq!(*foo, *bar); + } +} diff --git a/tests/ui/lto/weak-works.rs b/tests/ui/lto/weak-works.rs new file mode 100644 index 000000000..163a38702 --- /dev/null +++ b/tests/ui/lto/weak-works.rs @@ -0,0 +1,28 @@ +// run-pass + +// compile-flags: -C codegen-units=8 -Z thinlto +// ignore-windows + +#![feature(linkage)] + +pub mod foo { + #[linkage = "weak"] + #[no_mangle] + pub extern "C" fn FOO() -> i32 { + 0 + } +} + +mod bar { + extern "C" { + fn FOO() -> i32; + } + + pub fn bar() -> i32 { + unsafe { FOO() } + } +} + +fn main() { + bar::bar(); +} |