Skip to content

Commit e2d192c

Browse files
committed
auto merge of #10777 : alexcrichton/rust/issue-10743, r=luqmana
Commit messages have the fun details, the focus of this is closing #10743 though
2 parents 6a9db40 + 0dc9f62 commit e2d192c

File tree

7 files changed

+121
-77
lines changed

7 files changed

+121
-77
lines changed

mk/tests.mk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -920,11 +920,11 @@ $$(call TEST_OK_FILE,$(1),$(2),$(3),rmake): \
920920

921921
$(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok: \
922922
$(S)src/test/run-make/%/Makefile \
923-
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3))
923+
$$(HSREQ$(1)_H_$(3))
924924
@rm -rf $(3)/test/run-make/$$*
925925
@mkdir -p $(3)/test/run-make/$$*
926926
@echo maketest: $$*
927-
$$(Q)python $(S)src/etc/maketest.py $$(dir $$<) \
927+
$$(Q)$$(CFG_PYTHON) $(S)src/etc/maketest.py $$(dir $$<) \
928928
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
929929
$(3)/test/run-make/$$* \
930930
"$$(CC_$(3)) $$(CFG_GCCISH_CFLAGS_$(3))"

src/librustc/back/link.rs

Lines changed: 73 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,8 +1127,9 @@ fn link_args(sess: Session,
11271127
}
11281128
}
11291129

1130-
add_upstream_rust_crates(&mut args, sess, dylib);
11311130
add_local_native_libraries(&mut args, sess);
1131+
add_upstream_rust_crates(&mut args, sess, dylib);
1132+
add_upstream_native_libraries(&mut args, sess);
11321133

11331134
// # Telling the linker what we're doing
11341135

@@ -1168,6 +1169,42 @@ fn link_args(sess: Session,
11681169
return args;
11691170
}
11701171

1172+
// # Native library linking
1173+
//
1174+
// User-supplied library search paths (-L on the cammand line) These are
1175+
// the same paths used to find Rust crates, so some of them may have been
1176+
// added already by the previous crate linking code. This only allows them
1177+
// to be found at compile time so it is still entirely up to outside
1178+
// forces to make sure that library can be found at runtime.
1179+
//
1180+
// Also note that the native libraries linked here are only the ones located
1181+
// in the current crate. Upstream crates with native library dependencies
1182+
// may have their native library pulled in above.
1183+
fn add_local_native_libraries(args: &mut ~[~str], sess: Session) {
1184+
for path in sess.opts.addl_lib_search_paths.iter() {
1185+
// FIXME (#9639): This needs to handle non-utf8 paths
1186+
args.push("-L" + path.as_str().unwrap().to_owned());
1187+
}
1188+
1189+
let rustpath = filesearch::rust_path();
1190+
for path in rustpath.iter() {
1191+
// FIXME (#9639): This needs to handle non-utf8 paths
1192+
args.push("-L" + path.as_str().unwrap().to_owned());
1193+
}
1194+
1195+
for &(ref l, kind) in cstore::get_used_libraries(sess.cstore).iter() {
1196+
match kind {
1197+
cstore::NativeUnknown | cstore::NativeStatic => {
1198+
args.push("-l" + *l);
1199+
}
1200+
cstore::NativeFramework => {
1201+
args.push(~"-framework");
1202+
args.push(l.to_owned());
1203+
}
1204+
}
1205+
}
1206+
}
1207+
11711208
// # Rust Crate linking
11721209
//
11731210
// Rust crates are not considered at all when creating an rlib output. All
@@ -1197,30 +1234,11 @@ fn add_upstream_rust_crates(args: &mut ~[~str], sess: Session,
11971234
// all dynamic libaries require dynamic dependencies (see above), so
11981235
// it's satisfactory to include either all static libraries or all
11991236
// dynamic libraries.
1200-
let crates = cstore::get_used_crates(cstore,
1201-
cstore::RequireStatic);
1237+
let crates = cstore::get_used_crates(cstore, cstore::RequireStatic);
12021238
if crates.iter().all(|&(_, ref p)| p.is_some()) {
1203-
for &(cnum, ref path) in crates.iter() {
1204-
let cratepath = path.clone().unwrap();
1205-
1206-
// If we're linking to the static version of the crate, then
1207-
// we're mostly good to go. The caveat here is that we need to
1208-
// pull in the static crate's native dependencies.
1209-
args.push(cratepath.as_str().unwrap().to_owned());
1210-
1211-
let libs = csearch::get_native_libraries(sess.cstore, cnum);
1212-
for &(kind, ref lib) in libs.iter() {
1213-
match kind {
1214-
cstore::NativeUnknown => args.push("-l" + *lib),
1215-
cstore::NativeFramework => {
1216-
args.push(~"-framework");
1217-
args.push(lib.to_owned());
1218-
}
1219-
cstore::NativeStatic => {
1220-
sess.bug("statics shouldn't be propagated");
1221-
}
1222-
}
1223-
}
1239+
for (_, path) in crates.move_iter() {
1240+
let path = path.unwrap();
1241+
args.push(path.as_str().unwrap().to_owned());
12241242
}
12251243
return;
12261244
}
@@ -1253,38 +1271,39 @@ fn add_upstream_rust_crates(args: &mut ~[~str], sess: Session,
12531271
}
12541272
}
12551273

1256-
// # Native library linking
1274+
// Link in all of our upstream crates' native dependencies. Remember that
1275+
// all of these upstream native depenencies are all non-static
1276+
// dependencies. We've got two cases then:
12571277
//
1258-
// User-supplied library search paths (-L on the cammand line) These are
1259-
// the same paths used to find Rust crates, so some of them may have been
1260-
// added already by the previous crate linking code. This only allows them
1261-
// to be found at compile time so it is still entirely up to outside
1262-
// forces to make sure that library can be found at runtime.
1278+
// 1. The upstream crate is an rlib. In this case we *must* link in the
1279+
// native dependency because the rlib is just an archive.
12631280
//
1264-
// Also note that the native libraries linked here are only the ones located
1265-
// in the current crate. Upstream crates with native library dependencies
1266-
// may have their native library pulled in above.
1267-
fn add_local_native_libraries(args: &mut ~[~str], sess: Session) {
1268-
for path in sess.opts.addl_lib_search_paths.iter() {
1269-
// FIXME (#9639): This needs to handle non-utf8 paths
1270-
args.push("-L" + path.as_str().unwrap().to_owned());
1271-
}
1272-
1273-
let rustpath = filesearch::rust_path();
1274-
for path in rustpath.iter() {
1275-
// FIXME (#9639): This needs to handle non-utf8 paths
1276-
args.push("-L" + path.as_str().unwrap().to_owned());
1277-
}
1278-
1279-
for &(ref l, kind) in cstore::get_used_libraries(sess.cstore).iter() {
1280-
match kind {
1281-
cstore::NativeUnknown | cstore::NativeStatic => {
1282-
args.push("-l" + *l);
1283-
}
1284-
cstore::NativeFramework => {
1285-
args.push(~"-framework");
1286-
args.push(l.to_owned());
1281+
// 2. The upstream crate is a dylib. In order to use the dylib, we have to
1282+
// have the dependency present on the system somewhere. Thus, we don't
1283+
// gain a whole lot from not linking in the dynamic dependency to this
1284+
// crate as well.
1285+
//
1286+
// The use case for this is a little subtle. In theory the native
1287+
// dependencies of a crate a purely an implementation detail of the crate
1288+
// itself, but the problem arises with generic and inlined functions. If a
1289+
// generic function calls a native function, then the generic function must
1290+
// be instantiated in the target crate, meaning that the native symbol must
1291+
// also be resolved in the target crate.
1292+
fn add_upstream_native_libraries(args: &mut ~[~str], sess: Session) {
1293+
let cstore = sess.cstore;
1294+
cstore::iter_crate_data(cstore, |cnum, _| {
1295+
let libs = csearch::get_native_libraries(cstore, cnum);
1296+
for &(kind, ref lib) in libs.iter() {
1297+
match kind {
1298+
cstore::NativeUnknown => args.push("-l" + *lib),
1299+
cstore::NativeFramework => {
1300+
args.push(~"-framework");
1301+
args.push(lib.to_owned());
1302+
}
1303+
cstore::NativeStatic => {
1304+
sess.bug("statics shouldn't be propagated");
1305+
}
12871306
}
12881307
}
1289-
}
1308+
});
12901309
}

src/librustc/middle/reachable.rs

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,25 +128,44 @@ impl Visitor<()> for MarkSymbolVisitor {
128128
};
129129

130130
let def_id = def_id_of_def(def);
131-
if ReachableContext::
132-
def_id_represents_local_inlined_item(self.tcx, def_id) {
133-
self.worklist.push(def_id.node)
131+
if is_local(def_id) {
132+
if ReachableContext::
133+
def_id_represents_local_inlined_item(self.tcx, def_id) {
134+
self.worklist.push(def_id.node)
135+
} else {
136+
match def {
137+
// If this path leads to a static, then we may have
138+
// to do some work to figure out whether the static
139+
// is indeed reachable (address_insignificant
140+
// statics are *never* reachable).
141+
ast::DefStatic(..) => {
142+
self.worklist.push(def_id.node);
143+
}
144+
145+
// If this wasn't a static, then this destination is
146+
// surely reachable.
147+
_ => {
148+
self.reachable_symbols.insert(def_id.node);
149+
}
150+
}
134151
}
135-
self.reachable_symbols.insert(def_id.node);
152+
}
136153
}
137154
ast::ExprMethodCall(..) => {
138155
match self.method_map.find(&expr.id) {
139156
Some(&typeck::method_map_entry {
140157
origin: typeck::method_static(def_id),
141158
..
142159
}) => {
143-
if ReachableContext::
144-
def_id_represents_local_inlined_item(
145-
self.tcx,
146-
def_id) {
147-
self.worklist.push(def_id.node)
148-
}
149-
self.reachable_symbols.insert(def_id.node);
160+
if is_local(def_id) {
161+
if ReachableContext::
162+
def_id_represents_local_inlined_item(
163+
self.tcx,
164+
def_id) {
165+
self.worklist.push(def_id.node)
166+
}
167+
self.reachable_symbols.insert(def_id.node);
168+
}
150169
}
151170
Some(_) => {}
152171
None => {
@@ -310,10 +329,19 @@ impl ReachableContext {
310329
}
311330
}
312331

332+
// Statics with insignificant addresses are not reachable
333+
// because they're inlined specially into all other crates.
334+
ast::item_static(..) => {
335+
if attr::contains_name(item.attrs,
336+
"address_insignificant") {
337+
self.reachable_symbols.remove(&search_item);
338+
}
339+
}
340+
313341
// These are normal, nothing reachable about these
314342
// inherently and their children are already in the
315343
// worklist, as determined by the privacy pass
316-
ast::item_static(..) | ast::item_ty(..) |
344+
ast::item_ty(..) |
317345
ast::item_mod(..) | ast::item_foreign_mod(..) |
318346
ast::item_impl(..) | ast::item_trait(..) |
319347
ast::item_struct(..) | ast::item_enum(..) => {}

src/librustc/middle/trans/base.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2521,9 +2521,12 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
25212521
// requested
25222522
if attr::contains_name(i.attrs,
25232523
"address_insignificant"){
2524+
if ccx.reachable.contains(&id) {
2525+
ccx.sess.span_bug(i.span,
2526+
"insignificant static is \
2527+
reachable");
2528+
}
25242529
lib::llvm::SetUnnamedAddr(g, true);
2525-
lib::llvm::SetLinkage(g,
2526-
lib::llvm::InternalLinkage);
25272530

25282531
// This is a curious case where we must make
25292532
// all of these statics inlineable. If a

src/test/auxiliary/anon-extern-mod-cross-crate-1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
use std::libc;
1616

17+
#[link(name = "rustrt")]
1718
extern {
18-
#[link(name = "rustrt")]
1919
pub fn rust_get_test_int() -> libc::intptr_t;
2020
}

src/test/run-pass/anon-extern-mod-cross-crate-2.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@ extern mod anonexternmod;
1515

1616
use anonexternmod::rust_get_test_int;
1717

18-
#[link(name = "rustrt")] // we have explicitly chosen to require this
19-
extern {}
20-
2118
pub fn main() {
2219
unsafe {
2320
rust_get_test_int();

src/test/run-pass/invoke-external-foreign.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818

1919
extern mod foreign_lib;
2020

21-
#[link(name = "rustrt")] // we have explicitly chosen to require this
22-
extern {}
23-
2421
pub fn main() {
2522
unsafe {
2623
let _foo = foreign_lib::rustrt::rust_get_test_int();

0 commit comments

Comments
 (0)