Auto merge of #49672 - alexcrichton:fix-another-std-core-cycle, r=michaelwoerister

Fix another circular deps link args issue

It turns out that the support in #49316 wasn't enough to handle all cases
notably the example in #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 #48661
This commit is contained in:
bors 2018-04-07 17:14:46 +00:00
commit 780707490f
4 changed files with 29 additions and 11 deletions

View file

@ -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
@ -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)));