Skip to content

Commit

Permalink
Fix another circulare deps link args issue
Browse files Browse the repository at this point in the history
It turns out that the support in rust-lang#49316 wasn't enough to handle all cases
notably the example in rust-lang#48661. The underlying bug was connected to panic=abort
where lang items were listed in the `missing_lang_items` sets but didn't
actually exist anywhere.

This caused the linker backend to deduce that start-group/end-group wasn't
needed because not all items were defined. Instead the missing lang items that
don't actually need to have a definition are filtered out and not considered for
the start-group/end-group arguments

Closes rust-lang#48661
  • Loading branch information
alexcrichton committed Apr 4, 2018
1 parent 5758c2d commit 48ede3f
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 11 deletions.
29 changes: 19 additions & 10 deletions src/librustc/middle/weak_lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,24 @@ pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
})
}

/// Returns whether the specified `lang_item` doesn't actually need to be
/// present for this compilation.
///
/// Not all lang items are always required for each compilation, particularly in
/// the case of panic=abort. In these situations some lang items are injected by
/// crates and don't actually need to be defined in libstd.
pub fn whitelisted(tcx: TyCtxt, lang_item: lang_items::LangItem) -> bool {
// If we're not compiling with unwinding, we won't actually need these
// symbols. Other panic runtimes ensure that the relevant symbols are
// available to link things together, but they're never exercised.
if tcx.sess.panic_strategy() != PanicStrategy::Unwind {
return lang_item == lang_items::EhPersonalityLangItem ||
lang_item == lang_items::EhUnwindResumeLangItem
}

false
}

fn verify<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
items: &lang_items::LanguageItems) {
// We only need to check for the presence of weak lang items if we're
Expand All @@ -89,18 +107,9 @@ fn verify<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}

// If we're not compiling with unwinding, we won't actually need these
// symbols. Other panic runtimes ensure that the relevant symbols are
// available to link things together, but they're never exercised.
let mut whitelisted = HashSet::new();
if tcx.sess.panic_strategy() != PanicStrategy::Unwind {
whitelisted.insert(lang_items::EhPersonalityLangItem);
whitelisted.insert(lang_items::EhUnwindResumeLangItem);
}

$(
if missing.contains(&lang_items::$item) &&
!whitelisted.contains(&lang_items::$item) &&
!whitelisted(tcx, lang_items::$item) &&
items.$name().is_none() {
tcx.sess.err(&format!("language item required, but not found: `{}`",
stringify!($name)));
Expand Down
8 changes: 8 additions & 0 deletions src/librustc_trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use llvm;
use metadata;
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc::middle::lang_items::StartFnLangItem;
use rustc::middle::weak_lang_items;
use rustc::mir::mono::{Linkage, Visibility, Stats};
use rustc::middle::cstore::{EncodedMetadata};
use rustc::ty::{self, Ty, TyCtxt};
Expand Down Expand Up @@ -1137,6 +1138,13 @@ impl CrateInfo {
info.lang_item_to_crate.insert(item, id.krate);
}
}

// No need to look for lang items that are whitelisted and don't
// actually need to exist.
let missing = missing.iter()
.cloned()
.filter(|&l| !weak_lang_items::whitelisted(tcx, l))
.collect();
info.missing_lang_items.insert(cnum, missing);
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ struct CrateInfo {
wasm_custom_sections: BTreeMap<String, Vec<u8>>,
wasm_imports: FxHashMap<String, String>,
lang_item_to_crate: FxHashMap<LangItem, CrateNum>,
missing_lang_items: FxHashMap<CrateNum, Lrc<Vec<LangItem>>>,
missing_lang_items: FxHashMap<CrateNum, Vec<LangItem>>,
}

__build_diagnostic_array! { librustc_trans, DIAGNOSTICS }
1 change: 1 addition & 0 deletions src/test/run-make-fulldeps/std-core-cycle/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ endif
all:
$(RUSTC) bar.rs
$(RUSTC) foo.rs $(FLAGS)
$(RUSTC) foo.rs $(FLAGS) -C panic=abort

0 comments on commit 48ede3f

Please sign in to comment.