Add associated functions that have custom linkage to reachable_set

This commit is contained in:
hyd-dev 2021-06-20 21:49:08 +08:00
parent eb2226b1f1
commit c84beefd83
No known key found for this signature in database
GPG Key ID: 74FA7FD5B8DA14B8
3 changed files with 53 additions and 13 deletions

View File

@ -211,13 +211,15 @@ impl<'tcx> ReachableContext<'tcx> {
if !self.any_library {
// If we are building an executable, only explicitly extern
// types need to be exported.
if let Node::Item(item) = *node {
let reachable = if let hir::ItemKind::Fn(ref sig, ..) = item.kind {
sig.header.abi != Abi::Rust
} else {
false
};
let codegen_attrs = self.tcx.codegen_fn_attrs(item.def_id);
if let Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), def_id, .. })
| Node::ImplItem(hir::ImplItem {
kind: hir::ImplItemKind::Fn(sig, ..),
def_id,
..
}) = *node
{
let reachable = sig.header.abi != Abi::Rust;
let codegen_attrs = self.tcx.codegen_fn_attrs(*def_id);
let is_extern = codegen_attrs.contains_extern_indicator();
let std_internal =
codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
@ -335,17 +337,23 @@ struct CollectPrivateImplItemsVisitor<'a, 'tcx> {
worklist: &'a mut Vec<LocalDefId>,
}
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
impl CollectPrivateImplItemsVisitor<'_, '_> {
fn push_to_worklist_if_has_custom_linkage(&mut self, def_id: LocalDefId) {
// Anything which has custom linkage gets thrown on the worklist no
// matter where it is in the crate, along with "special std symbols"
// which are currently akin to allocator symbols.
let codegen_attrs = self.tcx.codegen_fn_attrs(item.def_id);
let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
if codegen_attrs.contains_extern_indicator()
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
{
self.worklist.push(item.def_id);
self.worklist.push(def_id);
}
}
}
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
self.push_to_worklist_if_has_custom_linkage(item.def_id);
// We need only trait impls here, not inherent impls, and only non-exported ones
if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) =
@ -375,8 +383,8 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {
// processed in visit_item above
fn visit_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) {
self.push_to_worklist_if_has_custom_linkage(impl_item.def_id);
}
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {

View File

@ -0,0 +1,10 @@
#![crate_type = "lib"]
struct Bar;
impl Bar {
#[no_mangle]
fn bar() -> u8 {
2
}
}

View File

@ -0,0 +1,22 @@
// aux-build: no-mangle-associated-fn.rs
// run-pass
extern crate no_mangle_associated_fn;
struct Foo;
impl Foo {
#[no_mangle]
fn foo() -> u8 {
1
}
}
fn main() {
extern "Rust" {
fn foo() -> u8;
fn bar() -> u8;
}
assert_eq!(unsafe { foo() }, 1);
assert_eq!(unsafe { bar() }, 2);
}