about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2018-03-23 14:33:22 -0700
committerAlex Crichton <alex@alexcrichton.com>2018-03-29 15:07:51 -0700
commit88114f61b44dba22c6fa180e17d7638f2cf7a9d7 (patch)
treec5e4446bfcc983fd1b7c3cb4bc615eee80cdf310 /src/test
parentae544ee1c90afc0f939753014dc5e884cb2749a0 (diff)
downloadrust-88114f61b44dba22c6fa180e17d7638f2cf7a9d7.tar.gz
rust-88114f61b44dba22c6fa180e17d7638f2cf7a9d7.zip
rustc: Group linked libraries where needed
This commit fixes a longstanding issue with the compiler with circular
dependencies between libcore and libstd. The `core` crate requires at least one
symbol, the ability to unwind. The `std` crate is the crate which actually
defines this symbol, but the `std` crate also depends on the `core` crate.

This circular dependency is in general disallowed in Rust as crates cannot have
cycles amongst them. A special exception is made just for core/std, but this is
also unfortunately incompatible with how GNU linkers work. GNU linkers will
process undefined symbols in a left-to-right fashion, only actually linking an
rlib like libstd if there are any symbols used from it. This strategy is
incompatible with circular dependencies because if we otherwise don't use
symbols from libstd we don't discover that we needed it until we're later
processing libcore's symbols!

To fix this GNU linkers support the `--start-group` and `--end-group` options
which indicate "libraries between these markers may have circular dependencies
amongst them. The linker invocation has been updated to automatically pass these
arguments when we're invoking a GNU linker and automatically calculate where the
arguments need to go (around libstd and libcore)

Closes #18807
Closes #47074
Diffstat (limited to 'src/test')
-rw-r--r--src/test/run-make-fulldeps/std-core-cycle/Makefile15
-rw-r--r--src/test/run-make-fulldeps/std-core-cycle/bar.rs26
-rw-r--r--src/test/run-make-fulldeps/std-core-cycle/foo.rs22
3 files changed, 63 insertions, 0 deletions
diff --git a/src/test/run-make-fulldeps/std-core-cycle/Makefile b/src/test/run-make-fulldeps/std-core-cycle/Makefile
new file mode 100644
index 00000000000..adc5be8016c
--- /dev/null
+++ b/src/test/run-make-fulldeps/std-core-cycle/Makefile
@@ -0,0 +1,15 @@
+-include ../tools.mk
+
+ifeq ($(UNAME),Darwin)
+FLAGS :=
+else
+ifdef IS_WINDOWS
+FLAGS :=
+else
+FLAGS := -C link-args=-Wl,--no-undefined
+endif
+endif
+
+all:
+	$(RUSTC) bar.rs
+	$(RUSTC) foo.rs $(FLAGS)
diff --git a/src/test/run-make-fulldeps/std-core-cycle/bar.rs b/src/test/run-make-fulldeps/std-core-cycle/bar.rs
new file mode 100644
index 00000000000..6def5b6f5e1
--- /dev/null
+++ b/src/test/run-make-fulldeps/std-core-cycle/bar.rs
@@ -0,0 +1,26 @@
+// Copyright 2018 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(allocator_api)]
+#![crate_type = "rlib"]
+
+use std::heap::*;
+
+pub struct A;
+
+unsafe impl<'a> Alloc for &'a A {
+    unsafe fn alloc(&mut self, _: Layout) -> Result<*mut u8, AllocErr> {
+        loop {}
+    }
+
+    unsafe fn dealloc(&mut self, _ptr: *mut u8, _: Layout) {
+        loop {}
+    }
+}
diff --git a/src/test/run-make-fulldeps/std-core-cycle/foo.rs b/src/test/run-make-fulldeps/std-core-cycle/foo.rs
new file mode 100644
index 00000000000..04742bba3c8
--- /dev/null
+++ b/src/test/run-make-fulldeps/std-core-cycle/foo.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(global_allocator)]
+#![crate_type = "cdylib"]
+
+extern crate bar;
+
+#[global_allocator]
+static A: bar::A = bar::A;
+
+#[no_mangle]
+pub extern fn a(a: u32, b: u32) -> u32 {
+    a / b
+}