mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-06 20:28:33 +00:00
Fix undefined function error
This commit is contained in:
parent
3cb8b1b684
commit
ae84d258c9
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -87,7 +87,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Clean
|
- name: Clean
|
||||||
run: |
|
run: |
|
||||||
./y.sh clean all
|
./y.sh clean all
|
||||||
|
|
||||||
- name: Prepare dependencies
|
- name: Prepare dependencies
|
||||||
run: |
|
run: |
|
||||||
|
137
src/callee.rs
137
src/callee.rs
@ -72,95 +72,74 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
|
|||||||
|
|
||||||
attributes::from_fn_attrs(cx, func, instance);
|
attributes::from_fn_attrs(cx, func, instance);
|
||||||
|
|
||||||
let instance_def_id = instance.def_id();
|
#[cfg(feature = "master")]
|
||||||
|
{
|
||||||
|
let instance_def_id = instance.def_id();
|
||||||
|
|
||||||
// TODO(antoyo): set linkage and attributes.
|
// TODO(antoyo): set linkage and attributes.
|
||||||
|
|
||||||
// Apply an appropriate linkage/visibility value to our item that we
|
// Apply an appropriate linkage/visibility value to our item that we
|
||||||
// just declared.
|
// just declared.
|
||||||
//
|
//
|
||||||
// This is sort of subtle. Inside our codegen unit we started off
|
// This is sort of subtle. Inside our codegen unit we started off
|
||||||
// compilation by predefining all our own `MonoItem` instances. That
|
// compilation by predefining all our own `MonoItem` instances. That
|
||||||
// is, everything we're codegenning ourselves is already defined. That
|
// is, everything we're codegenning ourselves is already defined. That
|
||||||
// means that anything we're actually codegenning in this codegen unit
|
// means that anything we're actually codegenning in this codegen unit
|
||||||
// will have hit the above branch in `get_declared_value`. As a result,
|
// will have hit the above branch in `get_declared_value`. As a result,
|
||||||
// we're guaranteed here that we're declaring a symbol that won't get
|
// we're guaranteed here that we're declaring a symbol that won't get
|
||||||
// defined, or in other words we're referencing a value from another
|
// defined, or in other words we're referencing a value from another
|
||||||
// codegen unit or even another crate.
|
// codegen unit or even another crate.
|
||||||
//
|
//
|
||||||
// So because this is a foreign value we blanket apply an external
|
// So because this is a foreign value we blanket apply an external
|
||||||
// linkage directive because it's coming from a different object file.
|
// linkage directive because it's coming from a different object file.
|
||||||
// The visibility here is where it gets tricky. This symbol could be
|
// The visibility here is where it gets tricky. This symbol could be
|
||||||
// referencing some foreign crate or foreign library (an `extern`
|
// referencing some foreign crate or foreign library (an `extern`
|
||||||
// block) in which case we want to leave the default visibility. We may
|
// block) in which case we want to leave the default visibility. We may
|
||||||
// also, though, have multiple codegen units. It could be a
|
// also, though, have multiple codegen units. It could be a
|
||||||
// monomorphization, in which case its expected visibility depends on
|
// monomorphization, in which case its expected visibility depends on
|
||||||
// whether we are sharing generics or not. The important thing here is
|
// whether we are sharing generics or not. The important thing here is
|
||||||
// that the visibility we apply to the declaration is the same one that
|
// that the visibility we apply to the declaration is the same one that
|
||||||
// has been applied to the definition (wherever that definition may be).
|
// has been applied to the definition (wherever that definition may be).
|
||||||
let is_generic = instance.args.non_erasable_generics().next().is_some();
|
let is_generic = instance.args.non_erasable_generics().next().is_some();
|
||||||
|
|
||||||
if is_generic {
|
let is_hidden = if is_generic {
|
||||||
// This is a monomorphization. Its expected visibility depends
|
// This is a monomorphization of a generic function.
|
||||||
// on whether we are in share-generics mode.
|
if !(cx.tcx.sess.opts.share_generics()
|
||||||
|
|| tcx.codegen_fn_attrs(instance_def_id).inline
|
||||||
if cx.tcx.sess.opts.share_generics() {
|
== rustc_attr::InlineAttr::Never)
|
||||||
// We are in share_generics mode.
|
{
|
||||||
|
// When not sharing generics, all instances are in the same
|
||||||
if let Some(instance_def_id) = instance_def_id.as_local() {
|
// crate and have hidden visibility.
|
||||||
// This is a definition from the current crate. If the
|
true
|
||||||
// definition is unreachable for downstream crates or
|
} else if let Some(instance_def_id) = instance_def_id.as_local() {
|
||||||
// the current crate does not re-export generics, the
|
// This is a monomorphization of a generic function
|
||||||
// definition of the instance will have been declared
|
// defined in the current crate. It is hidden if:
|
||||||
// as `hidden`.
|
// - the definition is unreachable for downstream
|
||||||
if cx.tcx.is_unreachable_local_definition(instance_def_id)
|
// crates, or
|
||||||
|
// - the current crate does not re-export generics
|
||||||
|
// (because the crate is a C library or executable)
|
||||||
|
cx.tcx.is_unreachable_local_definition(instance_def_id)
|
||||||
|| !cx.tcx.local_crate_exports_generics()
|
|| !cx.tcx.local_crate_exports_generics()
|
||||||
{
|
|
||||||
#[cfg(feature = "master")]
|
|
||||||
func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// This is a monomorphization of a generic function
|
// This is a monomorphization of a generic function
|
||||||
// defined in an upstream crate.
|
// defined in an upstream crate. It is hidden if:
|
||||||
if instance.upstream_monomorphization(tcx).is_some() {
|
// - it is instantiated in this crate, and
|
||||||
// This is instantiated in another crate. It cannot
|
// - the current crate does not re-export generics
|
||||||
// be `hidden`.
|
instance.upstream_monomorphization(tcx).is_none()
|
||||||
} else {
|
&& !cx.tcx.local_crate_exports_generics()
|
||||||
// This is a local instantiation of an upstream definition.
|
|
||||||
// If the current crate does not re-export it
|
|
||||||
// (because it is a C library or an executable), it
|
|
||||||
// will have been declared `hidden`.
|
|
||||||
if !cx.tcx.local_crate_exports_generics() {
|
|
||||||
#[cfg(feature = "master")]
|
|
||||||
func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// When not sharing generics, all instances are in the same
|
// This is a non-generic function. It is hidden if:
|
||||||
// crate and have hidden visibility
|
// - it is instantiated in the local crate, and
|
||||||
#[cfg(feature = "master")]
|
// - it is defined an upstream crate (non-local), or
|
||||||
|
// - it is not reachable
|
||||||
|
cx.tcx.is_codegened_item(instance_def_id)
|
||||||
|
&& (!instance_def_id.is_local()
|
||||||
|
|| !cx.tcx.is_reachable_non_generic(instance_def_id))
|
||||||
|
};
|
||||||
|
if is_hidden {
|
||||||
func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
|
func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// This is a non-generic function
|
|
||||||
if cx.tcx.is_codegened_item(instance_def_id) {
|
|
||||||
// This is a function that is instantiated in the local crate
|
|
||||||
|
|
||||||
if instance_def_id.is_local() {
|
|
||||||
// This is function that is defined in the local crate.
|
|
||||||
// If it is not reachable, it is hidden.
|
|
||||||
if !cx.tcx.is_reachable_non_generic(instance_def_id) {
|
|
||||||
#[cfg(feature = "master")]
|
|
||||||
func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// This is a function from an upstream crate that has
|
|
||||||
// been instantiated here. These are always hidden.
|
|
||||||
#[cfg(feature = "master")]
|
|
||||||
func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func
|
func
|
||||||
|
Loading…
Reference in New Issue
Block a user