From 2e1c4cd0f51c28b8cfc003fda67f6641bb4335f2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 11 Oct 2017 11:19:59 -0700 Subject: rustc: Fix some ThinLTO internalization First the `addPreservedGUID` function forgot to take care of "alias" summaries. I'm not 100% sure what this is but the current code now matches upstream. Next the `computeDeadSymbols` return value wasn't actually being used, but it needed to be used! Together these should... Closes #45195 --- src/test/run-pass/thinlto/auxiliary/dylib.rs | 16 +++++++++ .../thinlto/auxiliary/thin-lto-inlines-aux.rs | 17 ++++++++++ src/test/run-pass/thinlto/dylib-works.rs | 18 ++++++++++ src/test/run-pass/thinlto/thin-lto-inlines.rs | 39 ++++++++++++++++++++++ src/test/run-pass/thinlto/thin-lto-inlines2.rs | 38 +++++++++++++++++++++ 5 files changed, 128 insertions(+) create mode 100644 src/test/run-pass/thinlto/auxiliary/dylib.rs create mode 100644 src/test/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs create mode 100644 src/test/run-pass/thinlto/dylib-works.rs create mode 100644 src/test/run-pass/thinlto/thin-lto-inlines.rs create mode 100644 src/test/run-pass/thinlto/thin-lto-inlines2.rs (limited to 'src/test/run-pass/thinlto') diff --git a/src/test/run-pass/thinlto/auxiliary/dylib.rs b/src/test/run-pass/thinlto/auxiliary/dylib.rs new file mode 100644 index 00000000000..cdb3f49cae8 --- /dev/null +++ b/src/test/run-pass/thinlto/auxiliary/dylib.rs @@ -0,0 +1,16 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z thinlto -C codegen-units=8 + +#[inline] +pub fn foo(b: u8) { + b.to_string(); +} diff --git a/src/test/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs b/src/test/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs new file mode 100644 index 00000000000..ccbb0e7a718 --- /dev/null +++ b/src/test/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs @@ -0,0 +1,17 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn bar() -> u32 { + 3 +} diff --git a/src/test/run-pass/thinlto/dylib-works.rs b/src/test/run-pass/thinlto/dylib-works.rs new file mode 100644 index 00000000000..3f54519d0d8 --- /dev/null +++ b/src/test/run-pass/thinlto/dylib-works.rs @@ -0,0 +1,18 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:dylib.rs +// min-llvm-version 4.0 + +extern crate dylib; + +fn main() { + dylib::foo(1); +} diff --git a/src/test/run-pass/thinlto/thin-lto-inlines.rs b/src/test/run-pass/thinlto/thin-lto-inlines.rs new file mode 100644 index 00000000000..3135a682d86 --- /dev/null +++ b/src/test/run-pass/thinlto/thin-lto-inlines.rs @@ -0,0 +1,39 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z thinlto -C codegen-units=8 -O +// min-llvm-version 4.0 +// ignore-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/src/test/run-pass/thinlto/thin-lto-inlines2.rs b/src/test/run-pass/thinlto/thin-lto-inlines2.rs new file mode 100644 index 00000000000..ed899d2b115 --- /dev/null +++ b/src/test/run-pass/thinlto/thin-lto-inlines2.rs @@ -0,0 +1,38 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z thinlto -C codegen-units=8 -O -C lto +// aux-build:thin-lto-inlines-aux.rs +// min-llvm-version 4.0 +// no-prefer-dynamic +// ignore-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); + } +} + -- cgit 1.4.1-3-g733a5 From d9ecdfe3a7a579b9ec89355168f13760c670d4d4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 17 Oct 2017 18:45:42 -0700 Subject: test: Update Emscripten failures/passing All tests should now have annotation for *why* they're ignored on emscripten. A few tests no longer need such an annotation as well! Closes #41299 --- src/ci/docker/asmjs/Dockerfile | 8 ++++---- src/test/compile-fail/macro-expanded-include/test.rs | 2 +- src/test/run-pass/asm-concat-src.rs | 2 +- src/test/run-pass/command-before-exec.rs | 2 +- src/test/run-pass/command-exec.rs | 3 ++- src/test/run-pass/core-run-destroy.rs | 2 +- src/test/run-pass/env-args-reverse-iterator.rs | 2 +- src/test/run-pass/env-funky-keys.rs | 2 +- src/test/run-pass/env-home-dir.rs | 2 +- src/test/run-pass/extern-pass-empty.rs | 2 +- src/test/run-pass/fds-are-cloexec.rs | 2 +- src/test/run-pass/format-no-std.rs | 2 +- src/test/run-pass/generator/smoke.rs | 2 +- src/test/run-pass/i128.rs | 2 +- src/test/run-pass/issue-10626.rs | 2 +- src/test/run-pass/issue-13304.rs | 3 ++- src/test/run-pass/issue-14456.rs | 2 +- src/test/run-pass/issue-14940.rs | 2 +- src/test/run-pass/issue-16272.rs | 2 +- src/test/run-pass/issue-20091.rs | 3 ++- src/test/run-pass/issue-2190-1.rs | 2 +- src/test/run-pass/issue-24313.rs | 2 +- src/test/run-pass/issue-28950.rs | 2 +- src/test/run-pass/issue-29485.rs | 2 +- src/test/run-pass/issue-29663.rs | 2 -- src/test/run-pass/issue-30490.rs | 2 +- src/test/run-pass/issue-33770.rs | 2 +- src/test/run-pass/linkage1.rs | 2 +- src/test/run-pass/multi-panic.rs | 2 +- src/test/run-pass/no-stdio.rs | 2 +- src/test/run-pass/out-of-stack.rs | 2 +- src/test/run-pass/packed-struct-layout.rs | 2 -- src/test/run-pass/packed-tuple-struct-layout.rs | 2 -- src/test/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs | 2 +- src/test/run-pass/panic-runtime/abort.rs | 2 +- src/test/run-pass/panic-runtime/lto-abort.rs | 2 +- src/test/run-pass/panic-runtime/lto-unwind.rs | 2 +- src/test/run-pass/process-envs.rs | 2 +- src/test/run-pass/process-exit.rs | 2 +- src/test/run-pass/process-remove-from-env.rs | 2 +- src/test/run-pass/process-spawn-with-unicode-params.rs | 2 +- src/test/run-pass/process-status-inherits-stdin.rs | 3 ++- src/test/run-pass/running-with-no-runtime.rs | 2 +- src/test/run-pass/signal-exit-status.rs | 2 +- src/test/run-pass/sigpipe-should-be-ignored.rs | 2 +- src/test/run-pass/simd-intrinsic-generic-cast.rs | 3 ++- src/test/run-pass/stack-probes-lto.rs | 2 +- src/test/run-pass/stack-probes.rs | 2 +- src/test/run-pass/stdio-is-blocking.rs | 2 +- src/test/run-pass/thinlto/thin-lto-inlines.rs | 2 +- src/test/run-pass/thinlto/thin-lto-inlines2.rs | 2 +- src/test/run-pass/try-wait.rs | 2 +- src/test/run-pass/u128.rs | 2 +- src/test/run-pass/vec-macro-no-std.rs | 2 +- src/test/run-pass/wait-forked-but-failed-child.rs | 2 +- 55 files changed, 60 insertions(+), 61 deletions(-) (limited to 'src/test/run-pass/thinlto') diff --git a/src/ci/docker/asmjs/Dockerfile b/src/ci/docker/asmjs/Dockerfile index 28caf1fb57a..c0bf689e39d 100644 --- a/src/ci/docker/asmjs/Dockerfile +++ b/src/ci/docker/asmjs/Dockerfile @@ -16,6 +16,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ COPY scripts/emscripten.sh /scripts/ RUN bash /scripts/emscripten.sh +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + ENV PATH=$PATH:/emsdk-portable ENV PATH=$PATH:/emsdk-portable/clang/e1.37.13_64bit/ ENV PATH=$PATH:/emsdk-portable/emscripten/1.37.13/ @@ -28,7 +31,4 @@ ENV TARGETS=asmjs-unknown-emscripten ENV RUST_CONFIGURE_ARGS --target=$TARGETS -ENV SCRIPT python2.7 ../x.py test --target $TARGETS - -COPY scripts/sccache.sh /scripts/ -RUN sh /scripts/sccache.sh +ENV SCRIPT python2.7 ../x.py test --target $TARGETS src/test/run-pass diff --git a/src/test/compile-fail/macro-expanded-include/test.rs b/src/test/compile-fail/macro-expanded-include/test.rs index bcc2c10653f..4afb61ab76c 100644 --- a/src/test/compile-fail/macro-expanded-include/test.rs +++ b/src/test/compile-fail/macro-expanded-include/test.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no asm! support #![feature(asm, rustc_attrs)] #![allow(unused)] diff --git a/src/test/run-pass/asm-concat-src.rs b/src/test/run-pass/asm-concat-src.rs index fb257bf7b50..0380ccbdea4 100644 --- a/src/test/run-pass/asm-concat-src.rs +++ b/src/test/run-pass/asm-concat-src.rs @@ -9,7 +9,7 @@ // except according to those terms. // pretty-expanded FIXME #23616 -// ignore-emscripten +// ignore-emscripten no asm #![feature(asm)] diff --git a/src/test/run-pass/command-before-exec.rs b/src/test/run-pass/command-before-exec.rs index 5b83ce48e5d..9e782cca218 100644 --- a/src/test/run-pass/command-before-exec.rs +++ b/src/test/run-pass/command-before-exec.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-windows - this is a unix-specific test -// ignore-emscripten +// ignore-emscripten no processes #![feature(process_exec, libc)] diff --git a/src/test/run-pass/command-exec.rs b/src/test/run-pass/command-exec.rs index 5be9b97aac7..e378f55dffa 100644 --- a/src/test/run-pass/command-exec.rs +++ b/src/test/run-pass/command-exec.rs @@ -10,7 +10,8 @@ // ignore-windows - this is a unix-specific test // ignore-pretty issue #37199 -// ignore-emscripten +// ignore-emscripten no processes + #![feature(process_exec)] use std::env; diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs index 22fbeb2d5d0..863f3cf30e9 100644 --- a/src/test/run-pass/core-run-destroy.rs +++ b/src/test/run-pass/core-run-destroy.rs @@ -9,7 +9,7 @@ // except according to those terms. // compile-flags:--test -// ignore-emscripten +// ignore-emscripten no processes // NB: These tests kill child processes. Valgrind sees these children as leaking // memory, which makes for some *confusing* logs. That's why these are here diff --git a/src/test/run-pass/env-args-reverse-iterator.rs b/src/test/run-pass/env-args-reverse-iterator.rs index 89af1db7c78..dddf1ae0546 100644 --- a/src/test/run-pass/env-args-reverse-iterator.rs +++ b/src/test/run-pass/env-args-reverse-iterator.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes use std::env::args; use std::process::Command; diff --git a/src/test/run-pass/env-funky-keys.rs b/src/test/run-pass/env-funky-keys.rs index 8b4a633d613..86ffaf1e24f 100644 --- a/src/test/run-pass/env-funky-keys.rs +++ b/src/test/run-pass/env-funky-keys.rs @@ -12,7 +12,7 @@ // ignore-android // ignore-windows -// ignore-emscripten +// ignore-emscripten no execve // no-prefer-dynamic #![feature(libc)] diff --git a/src/test/run-pass/env-home-dir.rs b/src/test/run-pass/env-home-dir.rs index bcb0c62d9fe..3693e86ba24 100644 --- a/src/test/run-pass/env-home-dir.rs +++ b/src/test/run-pass/env-home-dir.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten env vars don't work? #![feature(path)] diff --git a/src/test/run-pass/extern-pass-empty.rs b/src/test/run-pass/extern-pass-empty.rs index 2606c928680..f4ee3b6e9e8 100644 --- a/src/test/run-pass/extern-pass-empty.rs +++ b/src/test/run-pass/extern-pass-empty.rs @@ -12,7 +12,7 @@ // pretty-expanded FIXME #23616 // ignore-msvc -// ignore-emscripten +// ignore-emscripten emcc asserts on an empty struct as an argument #[repr(C)] struct TwoU8s { diff --git a/src/test/run-pass/fds-are-cloexec.rs b/src/test/run-pass/fds-are-cloexec.rs index a1b7d42a196..f55876115c0 100644 --- a/src/test/run-pass/fds-are-cloexec.rs +++ b/src/test/run-pass/fds-are-cloexec.rs @@ -10,7 +10,7 @@ // ignore-windows // ignore-android -// ignore-emscripten +// ignore-emscripten no processes // ignore-haiku #![feature(libc)] diff --git a/src/test/run-pass/format-no-std.rs b/src/test/run-pass/format-no-std.rs index 9e8a3218518..e23accfcc23 100644 --- a/src/test/run-pass/format-no-std.rs +++ b/src/test/run-pass/format-no-std.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten missing rust_begin_unwind +// ignore-emscripten no no_std executables #![feature(lang_items, start, alloc)] #![no_std] diff --git a/src/test/run-pass/generator/smoke.rs b/src/test/run-pass/generator/smoke.rs index e9bdfbf28ea..8693964665d 100644 --- a/src/test/run-pass/generator/smoke.rs +++ b/src/test/run-pass/generator/smoke.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no threads support // compile-flags: --test #![feature(generators, generator_trait)] diff --git a/src/test/run-pass/i128.rs b/src/test/run-pass/i128.rs index 7c14d34b0ee..5369b138b0d 100644 --- a/src/test/run-pass/i128.rs +++ b/src/test/run-pass/i128.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten i128 doesn't work #![feature(i128_type, test)] diff --git a/src/test/run-pass/issue-10626.rs b/src/test/run-pass/issue-10626.rs index b350bd1a4cc..e9d37817ee2 100644 --- a/src/test/run-pass/issue-10626.rs +++ b/src/test/run-pass/issue-10626.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes // Make sure that if a process doesn't have its stdio/stderr descriptors set up // that we don't die in a large ball of fire diff --git a/src/test/run-pass/issue-13304.rs b/src/test/run-pass/issue-13304.rs index 5a743d7b547..9214d6b04bd 100644 --- a/src/test/run-pass/issue-13304.rs +++ b/src/test/run-pass/issue-13304.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes + #![feature(io, process_capture)] use std::env; diff --git a/src/test/run-pass/issue-14456.rs b/src/test/run-pass/issue-14456.rs index 513ab91489c..2edb45cc1c4 100644 --- a/src/test/run-pass/issue-14456.rs +++ b/src/test/run-pass/issue-14456.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes #![feature(io, process_capture)] diff --git a/src/test/run-pass/issue-14940.rs b/src/test/run-pass/issue-14940.rs index ffe6b646794..588fa63cfdf 100644 --- a/src/test/run-pass/issue-14940.rs +++ b/src/test/run-pass/issue-14940.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes use std::env; use std::process::Command; diff --git a/src/test/run-pass/issue-16272.rs b/src/test/run-pass/issue-16272.rs index f86be2d7c99..cd02cbf3dad 100644 --- a/src/test/run-pass/issue-16272.rs +++ b/src/test/run-pass/issue-16272.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes use std::process::Command; use std::env; diff --git a/src/test/run-pass/issue-20091.rs b/src/test/run-pass/issue-20091.rs index 1ee47a69d0c..c8ba5dbd84c 100644 --- a/src/test/run-pass/issue-20091.rs +++ b/src/test/run-pass/issue-20091.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes + #![feature(std_misc, os)] #[cfg(unix)] diff --git a/src/test/run-pass/issue-2190-1.rs b/src/test/run-pass/issue-2190-1.rs index 39375703514..8cc23c883ed 100644 --- a/src/test/run-pass/issue-2190-1.rs +++ b/src/test/run-pass/issue-2190-1.rs @@ -9,7 +9,7 @@ // except according to those terms. // pretty-expanded FIXME #23616 -// ignore-emscripten +// ignore-emscripten no threads use std::thread::Builder; diff --git a/src/test/run-pass/issue-24313.rs b/src/test/run-pass/issue-24313.rs index 9b2b474351d..ad385ee78e0 100644 --- a/src/test/run-pass/issue-24313.rs +++ b/src/test/run-pass/issue-24313.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no threads use std::thread; use std::env; diff --git a/src/test/run-pass/issue-28950.rs b/src/test/run-pass/issue-28950.rs index a70c2b3ae1b..4e4530789c8 100644 --- a/src/test/run-pass/issue-28950.rs +++ b/src/test/run-pass/issue-28950.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no threads // compile-flags: -O // Tests that the `vec!` macro does not overflow the stack when it is diff --git a/src/test/run-pass/issue-29485.rs b/src/test/run-pass/issue-29485.rs index 9252762d1bd..828b495d408 100644 --- a/src/test/run-pass/issue-29485.rs +++ b/src/test/run-pass/issue-29485.rs @@ -9,7 +9,7 @@ // except according to those terms. // aux-build:issue-29485.rs -// ignore-emscripten +// ignore-emscripten no threads #[feature(recover)] diff --git a/src/test/run-pass/issue-29663.rs b/src/test/run-pass/issue-29663.rs index cf925662fc3..9a77be049fe 100644 --- a/src/test/run-pass/issue-29663.rs +++ b/src/test/run-pass/issue-29663.rs @@ -10,8 +10,6 @@ // write_volatile causes an LLVM assert with composite types -// ignore-emscripten See #41299: probably a bad optimization - #![feature(volatile)] use std::ptr::{read_volatile, write_volatile}; diff --git a/src/test/run-pass/issue-30490.rs b/src/test/run-pass/issue-30490.rs index 7658abc00c5..4296107dd45 100644 --- a/src/test/run-pass/issue-30490.rs +++ b/src/test/run-pass/issue-30490.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes // Previously libstd would set stdio descriptors of a child process // by `dup`ing the requested descriptors to inherit directly into the diff --git a/src/test/run-pass/issue-33770.rs b/src/test/run-pass/issue-33770.rs index 76728a0d354..38062700707 100644 --- a/src/test/run-pass/issue-33770.rs +++ b/src/test/run-pass/issue-33770.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes use std::process::{Command, Stdio}; use std::env; diff --git a/src/test/run-pass/linkage1.rs b/src/test/run-pass/linkage1.rs index 591610e88b1..f12a233f493 100644 --- a/src/test/run-pass/linkage1.rs +++ b/src/test/run-pass/linkage1.rs @@ -10,7 +10,7 @@ // ignore-windows // ignore-macos -// ignore-emscripten +// ignore-emscripten doesn't support this linkage // aux-build:linkage1.rs #![feature(linkage)] diff --git a/src/test/run-pass/multi-panic.rs b/src/test/run-pass/multi-panic.rs index 86fe06b1765..c15b40d4dda 100644 --- a/src/test/run-pass/multi-panic.rs +++ b/src/test/run-pass/multi-panic.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes fn check_for_no_backtrace(test: std::process::Output) { assert!(!test.status.success()); diff --git a/src/test/run-pass/no-stdio.rs b/src/test/run-pass/no-stdio.rs index 85c63e184fe..7b6b711315a 100644 --- a/src/test/run-pass/no-stdio.rs +++ b/src/test/run-pass/no-stdio.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes // ignore-android #![feature(libc)] diff --git a/src/test/run-pass/out-of-stack.rs b/src/test/run-pass/out-of-stack.rs index 7e70c4a7ab3..485335a2d80 100644 --- a/src/test/run-pass/out-of-stack.rs +++ b/src/test/run-pass/out-of-stack.rs @@ -10,7 +10,7 @@ // ignore-android: FIXME (#20004) // ignore-musl -// ignore-emscripten +// ignore-emscripten no processes #![feature(asm)] #![feature(libc)] diff --git a/src/test/run-pass/packed-struct-layout.rs b/src/test/run-pass/packed-struct-layout.rs index d1e05e5a018..a4a0055785f 100644 --- a/src/test/run-pass/packed-struct-layout.rs +++ b/src/test/run-pass/packed-struct-layout.rs @@ -7,8 +7,6 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten Not sure what's happening here. - use std::mem; diff --git a/src/test/run-pass/packed-tuple-struct-layout.rs b/src/test/run-pass/packed-tuple-struct-layout.rs index ee4eb86ed0d..18f7eff280a 100644 --- a/src/test/run-pass/packed-tuple-struct-layout.rs +++ b/src/test/run-pass/packed-tuple-struct-layout.rs @@ -7,8 +7,6 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten - use std::mem; diff --git a/src/test/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs b/src/test/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs index ebbb00a4a9f..d1fdc8afa65 100644 --- a/src/test/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs +++ b/src/test/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs @@ -11,7 +11,7 @@ // compile-flags:-C panic=abort // aux-build:exit-success-if-unwind.rs // no-prefer-dynamic -// ignore-emscripten Function not implemented +// ignore-emscripten no processes extern crate exit_success_if_unwind; diff --git a/src/test/run-pass/panic-runtime/abort.rs b/src/test/run-pass/panic-runtime/abort.rs index 3ba3bd61c2e..bb541b29d7c 100644 --- a/src/test/run-pass/panic-runtime/abort.rs +++ b/src/test/run-pass/panic-runtime/abort.rs @@ -10,7 +10,7 @@ // compile-flags:-C panic=abort // no-prefer-dynamic -// ignore-emscripten Function not implemented. +// ignore-emscripten no processes use std::process::Command; use std::env; diff --git a/src/test/run-pass/panic-runtime/lto-abort.rs b/src/test/run-pass/panic-runtime/lto-abort.rs index e4cd4e809a4..59e9474aab2 100644 --- a/src/test/run-pass/panic-runtime/lto-abort.rs +++ b/src/test/run-pass/panic-runtime/lto-abort.rs @@ -10,7 +10,7 @@ // compile-flags:-C lto -C panic=abort // no-prefer-dynamic -// ignore-emscripten Function not implemented. +// ignore-emscripten no processes use std::process::Command; use std::env; diff --git a/src/test/run-pass/panic-runtime/lto-unwind.rs b/src/test/run-pass/panic-runtime/lto-unwind.rs index 768b88fd09e..6d28b8d12f6 100644 --- a/src/test/run-pass/panic-runtime/lto-unwind.rs +++ b/src/test/run-pass/panic-runtime/lto-unwind.rs @@ -10,7 +10,7 @@ // compile-flags:-C lto -C panic=unwind // no-prefer-dynamic -// ignore-emscripten Function not implemented. +// ignore-emscripten no processes use std::process::Command; use std::env; diff --git a/src/test/run-pass/process-envs.rs b/src/test/run-pass/process-envs.rs index b3785d898ba..1622517198a 100644 --- a/src/test/run-pass/process-envs.rs +++ b/src/test/run-pass/process-envs.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes use std::process::Command; use std::env; diff --git a/src/test/run-pass/process-exit.rs b/src/test/run-pass/process-exit.rs index a5d408448a0..5abc06b75e1 100644 --- a/src/test/run-pass/process-exit.rs +++ b/src/test/run-pass/process-exit.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes use std::env; use std::process::{self, Command, Stdio}; diff --git a/src/test/run-pass/process-remove-from-env.rs b/src/test/run-pass/process-remove-from-env.rs index b7f296a65c2..7a9b431d570 100644 --- a/src/test/run-pass/process-remove-from-env.rs +++ b/src/test/run-pass/process-remove-from-env.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes use std::process::Command; use std::env; diff --git a/src/test/run-pass/process-spawn-with-unicode-params.rs b/src/test/run-pass/process-spawn-with-unicode-params.rs index 550c6d6ab67..7b854207263 100644 --- a/src/test/run-pass/process-spawn-with-unicode-params.rs +++ b/src/test/run-pass/process-spawn-with-unicode-params.rs @@ -16,7 +16,7 @@ // non-ASCII characters. The child process ensures all the strings are // intact. -// ignore-emscripten +// ignore-emscripten no processes use std::io::prelude::*; use std::io; diff --git a/src/test/run-pass/process-status-inherits-stdin.rs b/src/test/run-pass/process-status-inherits-stdin.rs index ff389bec899..5ea48a4ff33 100644 --- a/src/test/run-pass/process-status-inherits-stdin.rs +++ b/src/test/run-pass/process-status-inherits-stdin.rs @@ -7,7 +7,8 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten Function not implemented. + +// ignore-emscripten no processes use std::env; use std::io; diff --git a/src/test/run-pass/running-with-no-runtime.rs b/src/test/run-pass/running-with-no-runtime.rs index f81c3f2e99d..6f696c1c9ce 100644 --- a/src/test/run-pass/running-with-no-runtime.rs +++ b/src/test/run-pass/running-with-no-runtime.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten spawning processes is not supported #![feature(start)] diff --git a/src/test/run-pass/signal-exit-status.rs b/src/test/run-pass/signal-exit-status.rs index 8a2bbc83c42..0f6832acec8 100644 --- a/src/test/run-pass/signal-exit-status.rs +++ b/src/test/run-pass/signal-exit-status.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-windows -// ignore-emscripten +// ignore-emscripten no processes use std::env; use std::process::Command; diff --git a/src/test/run-pass/sigpipe-should-be-ignored.rs b/src/test/run-pass/sigpipe-should-be-ignored.rs index 5aa4faa1365..465feb4b779 100644 --- a/src/test/run-pass/sigpipe-should-be-ignored.rs +++ b/src/test/run-pass/sigpipe-should-be-ignored.rs @@ -11,7 +11,7 @@ // Be sure that when a SIGPIPE would have been received that the entire process // doesn't die in a ball of fire, but rather it's gracefully handled. -// ignore-emscripten +// ignore-emscripten no processes use std::env; use std::io::prelude::*; diff --git a/src/test/run-pass/simd-intrinsic-generic-cast.rs b/src/test/run-pass/simd-intrinsic-generic-cast.rs index ede2325b51c..ed2786edf3a 100644 --- a/src/test/run-pass/simd-intrinsic-generic-cast.rs +++ b/src/test/run-pass/simd-intrinsic-generic-cast.rs @@ -7,7 +7,8 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten linking with emcc failed + +// ignore-emscripten FIXME(#45351) hits an LLVM assert #![feature(repr_simd, platform_intrinsics, concat_idents, test)] #![allow(non_camel_case_types)] diff --git a/src/test/run-pass/stack-probes-lto.rs b/src/test/run-pass/stack-probes-lto.rs index f49320e4da4..78a1019578e 100644 --- a/src/test/run-pass/stack-probes-lto.rs +++ b/src/test/run-pass/stack-probes-lto.rs @@ -11,7 +11,7 @@ // ignore-arm // ignore-aarch64 // ignore-wasm -// ignore-emscripten +// ignore-emscripten no processes // ignore-musl FIXME #31506 // ignore-pretty // no-system-llvm diff --git a/src/test/run-pass/stack-probes.rs b/src/test/run-pass/stack-probes.rs index 1d66cb60207..bb9471e1b48 100644 --- a/src/test/run-pass/stack-probes.rs +++ b/src/test/run-pass/stack-probes.rs @@ -11,7 +11,7 @@ // ignore-arm // ignore-aarch64 // ignore-wasm -// ignore-emscripten +// ignore-emscripten no processes // ignore-musl FIXME #31506 // no-system-llvm diff --git a/src/test/run-pass/stdio-is-blocking.rs b/src/test/run-pass/stdio-is-blocking.rs index 448bb7de772..cce1077202c 100644 --- a/src/test/run-pass/stdio-is-blocking.rs +++ b/src/test/run-pass/stdio-is-blocking.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes use std::env; use std::io::prelude::*; diff --git a/src/test/run-pass/thinlto/thin-lto-inlines.rs b/src/test/run-pass/thinlto/thin-lto-inlines.rs index 3135a682d86..7a71dd2bc51 100644 --- a/src/test/run-pass/thinlto/thin-lto-inlines.rs +++ b/src/test/run-pass/thinlto/thin-lto-inlines.rs @@ -10,7 +10,7 @@ // compile-flags: -Z thinlto -C codegen-units=8 -O // min-llvm-version 4.0 -// ignore-emscripten +// 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 diff --git a/src/test/run-pass/thinlto/thin-lto-inlines2.rs b/src/test/run-pass/thinlto/thin-lto-inlines2.rs index ed899d2b115..0e8ad08a5f6 100644 --- a/src/test/run-pass/thinlto/thin-lto-inlines2.rs +++ b/src/test/run-pass/thinlto/thin-lto-inlines2.rs @@ -12,7 +12,7 @@ // aux-build:thin-lto-inlines-aux.rs // min-llvm-version 4.0 // no-prefer-dynamic -// ignore-emscripten +// 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 diff --git a/src/test/run-pass/try-wait.rs b/src/test/run-pass/try-wait.rs index be87b7b3c87..0ee2cb9238c 100644 --- a/src/test/run-pass/try-wait.rs +++ b/src/test/run-pass/try-wait.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes #![feature(process_try_wait)] diff --git a/src/test/run-pass/u128.rs b/src/test/run-pass/u128.rs index b16f6c7b6af..bf506a71250 100644 --- a/src/test/run-pass/u128.rs +++ b/src/test/run-pass/u128.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten u128 not supported #![feature(i128_type, test)] diff --git a/src/test/run-pass/vec-macro-no-std.rs b/src/test/run-pass/vec-macro-no-std.rs index f21027afac3..56ff9cb2477 100644 --- a/src/test/run-pass/vec-macro-no-std.rs +++ b/src/test/run-pass/vec-macro-no-std.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten missing rust_begin_unwind +// ignore-emscripten no no_std executables #![feature(lang_items, start, libc, alloc)] #![no_std] diff --git a/src/test/run-pass/wait-forked-but-failed-child.rs b/src/test/run-pass/wait-forked-but-failed-child.rs index 1d1c83cf12a..744f2989bcf 100644 --- a/src/test/run-pass/wait-forked-but-failed-child.rs +++ b/src/test/run-pass/wait-forked-but-failed-child.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-emscripten +// ignore-emscripten no processes #![feature(libc)] -- cgit 1.4.1-3-g733a5 From 3541ffb668c3b908aa5e3b6ba8a890d56a8360a7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 17 Oct 2017 13:08:13 -0700 Subject: rustc: Add `_imp_` symbols later in compilation On MSVC targets rustc will add symbols prefixed with `_imp_` to LLVM modules to "emulate" dllexported statics as that workaround is still in place after #27438 hasn't been solved otherwise. These statics, however, were getting gc'd by ThinLTO accidentally which later would cause linking failures. This commit updates the location we add such symbols to happen just before codegen to ensure that (a) they're not eliminated by the optimizer and (b) the optimizer doesn't even worry about them. Closes #45347 --- src/librustc_trans/back/write.rs | 61 +++++++++++++++++++++- src/librustc_trans/base.rs | 52 ++---------------- .../run-pass/thinlto/auxiliary/msvc-imp-present.rs | 21 ++++++++ src/test/run-pass/thinlto/msvc-imp-present.rs | 31 +++++++++++ 4 files changed, 115 insertions(+), 50 deletions(-) create mode 100644 src/test/run-pass/thinlto/auxiliary/msvc-imp-present.rs create mode 100644 src/test/run-pass/thinlto/msvc-imp-present.rs (limited to 'src/test/run-pass/thinlto') diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index f7e0ad029af..f8dbe68dba9 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -12,6 +12,8 @@ use back::lto; use back::link::{self, get_linker, remove}; use back::linker::LinkerInfo; use back::symbol_export::ExportedSymbols; +use base; +use consts; use rustc_incremental::{save_trans_partition, in_incr_comp_dir}; use rustc::dep_graph::DepGraph; use rustc::middle::cstore::{LinkMeta, EncodedMetadata}; @@ -35,12 +37,13 @@ use syntax::attr; use syntax::ext::hygiene::Mark; use syntax_pos::MultiSpan; use syntax_pos::symbol::Symbol; +use type_::Type; use context::{is_pie_binary, get_reloc_model}; use jobserver::{Client, Acquired}; use rustc_demangle; use std::any::Any; -use std::ffi::CString; +use std::ffi::{CString, CStr}; use std::fs; use std::io; use std::io::Write; @@ -315,6 +318,8 @@ pub struct CodegenContext { metadata_module_config: Arc, allocator_module_config: Arc, pub tm_factory: Arc Result + Send + Sync>, + pub msvc_imps_needed: bool, + pub target_pointer_width: String, // Number of cgus excluding the allocator/metadata modules pub total_cgus: usize, @@ -586,6 +591,10 @@ unsafe fn codegen(cgcx: &CodegenContext, let module_name = Some(&module_name[..]); let handlers = DiagnosticHandlers::new(cgcx, diag_handler, llcx); + if cgcx.msvc_imps_needed { + create_msvc_imps(cgcx, llcx, llmod); + } + // A codegen-specific pass manager is used to generate object // files for an LLVM module. // @@ -1300,6 +1309,8 @@ fn start_executing_work(tcx: TyCtxt, allocator_module_config: allocator_config, tm_factory: target_machine_factory(tcx.sess), total_cgus, + msvc_imps_needed: msvc_imps_needed(tcx), + target_pointer_width: tcx.sess.target.target.target_pointer_width.clone(), }; // This is the "main loop" of parallel work happening for parallel codegen. @@ -2133,3 +2144,51 @@ pub fn submit_translated_module_to_llvm(tcx: TyCtxt, cost, }))); } + +fn msvc_imps_needed(tcx: TyCtxt) -> bool { + tcx.sess.target.target.options.is_like_msvc && + tcx.sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateTypeRlib) +} + +// Create a `__imp_ = &symbol` global for every public static `symbol`. +// This is required to satisfy `dllimport` references to static data in .rlibs +// when using MSVC linker. We do this only for data, as linker can fix up +// code references on its own. +// See #26591, #27438 +fn create_msvc_imps(cgcx: &CodegenContext, llcx: ContextRef, llmod: ModuleRef) { + if !cgcx.msvc_imps_needed { + return + } + // The x86 ABI seems to require that leading underscores are added to symbol + // names, so we need an extra underscore on 32-bit. There's also a leading + // '\x01' here which disables LLVM's symbol mangling (e.g. no extra + // underscores added in front). + let prefix = if cgcx.target_pointer_width == "32" { + "\x01__imp__" + } else { + "\x01__imp_" + }; + unsafe { + let i8p_ty = Type::i8p_llcx(llcx); + let globals = base::iter_globals(llmod) + .filter(|&val| { + llvm::LLVMRustGetLinkage(val) == llvm::Linkage::ExternalLinkage && + llvm::LLVMIsDeclaration(val) == 0 + }) + .map(move |val| { + let name = CStr::from_ptr(llvm::LLVMGetValueName(val)); + let mut imp_name = prefix.as_bytes().to_vec(); + imp_name.extend(name.to_bytes()); + let imp_name = CString::new(imp_name).unwrap(); + (imp_name, val) + }) + .collect::>(); + for (imp_name, val) in globals { + let imp = llvm::LLVMAddGlobal(llmod, + i8p_ty.to_ref(), + imp_name.as_ptr() as *const _); + llvm::LLVMSetInitializer(imp, consts::ptrcast(val, i8p_ty)); + llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage); + } + } +} diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 6b53b5b6411..7bc33a88956 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -78,7 +78,7 @@ use rustc::util::nodemap::{NodeSet, FxHashMap, FxHashSet, DefIdSet}; use CrateInfo; use std::any::Any; -use std::ffi::{CStr, CString}; +use std::ffi::CString; use std::str; use std::sync::Arc; use std::time::{Instant, Duration}; @@ -812,47 +812,7 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, return (metadata_llcx, metadata_llmod, metadata, hashes); } -// Create a `__imp_ = &symbol` global for every public static `symbol`. -// This is required to satisfy `dllimport` references to static data in .rlibs -// when using MSVC linker. We do this only for data, as linker can fix up -// code references on its own. -// See #26591, #27438 -fn create_imps(sess: &Session, - llvm_module: &ModuleLlvm) { - // The x86 ABI seems to require that leading underscores are added to symbol - // names, so we need an extra underscore on 32-bit. There's also a leading - // '\x01' here which disables LLVM's symbol mangling (e.g. no extra - // underscores added in front). - let prefix = if sess.target.target.target_pointer_width == "32" { - "\x01__imp__" - } else { - "\x01__imp_" - }; - unsafe { - let exported: Vec<_> = iter_globals(llvm_module.llmod) - .filter(|&val| { - llvm::LLVMRustGetLinkage(val) == - llvm::Linkage::ExternalLinkage && - llvm::LLVMIsDeclaration(val) == 0 - }) - .collect(); - - let i8p_ty = Type::i8p_llcx(llvm_module.llcx); - for val in exported { - let name = CStr::from_ptr(llvm::LLVMGetValueName(val)); - let mut imp_name = prefix.as_bytes().to_vec(); - imp_name.extend(name.to_bytes()); - let imp_name = CString::new(imp_name).unwrap(); - let imp = llvm::LLVMAddGlobal(llvm_module.llmod, - i8p_ty.to_ref(), - imp_name.as_ptr() as *const _); - llvm::LLVMSetInitializer(imp, consts::ptrcast(val, i8p_ty)); - llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage); - } - } -} - -struct ValueIter { +pub struct ValueIter { cur: ValueRef, step: unsafe extern "C" fn(ValueRef) -> ValueRef, } @@ -871,7 +831,7 @@ impl Iterator for ValueIter { } } -fn iter_globals(llmod: llvm::ModuleRef) -> ValueIter { +pub fn iter_globals(llmod: llvm::ModuleRef) -> ValueIter { unsafe { ValueIter { cur: llvm::LLVMGetFirstGlobal(llmod), @@ -1437,12 +1397,6 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tm: create_target_machine(ccx.sess()), }; - // Adjust exported symbols for MSVC dllimport - if ccx.sess().target.target.options.is_like_msvc && - ccx.sess().crate_types.borrow().iter().any(|ct| *ct == config::CrateTypeRlib) { - create_imps(ccx.sess(), &llvm_module); - } - ModuleTranslation { name: cgu_name, source: ModuleSource::Translated(llvm_module), diff --git a/src/test/run-pass/thinlto/auxiliary/msvc-imp-present.rs b/src/test/run-pass/thinlto/auxiliary/msvc-imp-present.rs new file mode 100644 index 00000000000..eff7802a245 --- /dev/null +++ b/src/test/run-pass/thinlto/auxiliary/msvc-imp-present.rs @@ -0,0 +1,21 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// 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/src/test/run-pass/thinlto/msvc-imp-present.rs b/src/test/run-pass/thinlto/msvc-imp-present.rs new file mode 100644 index 00000000000..8329c7032f1 --- /dev/null +++ b/src/test/run-pass/thinlto/msvc-imp-present.rs @@ -0,0 +1,31 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:msvc-imp-present.rs +// compile-flags: -Z thinlto -C codegen-units=8 +// min-llvm-version: 4.0 +// 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); +} -- cgit 1.4.1-3-g733a5