Fix undefined function error

This commit is contained in:
Antoni Boucher 2024-12-12 17:39:12 -05:00
parent 3cb8b1b684
commit ae84d258c9
2 changed files with 59 additions and 80 deletions

View File

@ -72,6 +72,8 @@ 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);
#[cfg(feature = "master")]
{
let instance_def_id = instance.def_id(); let instance_def_id = instance.def_id();
// TODO(antoyo): set linkage and attributes. // TODO(antoyo): set linkage and attributes.
@ -100,67 +102,44 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
// 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.
if let Some(instance_def_id) = instance_def_id.as_local() {
// This is a definition from the current crate. If the
// definition is unreachable for downstream crates or
// the current crate does not re-export generics, the
// definition of the instance will have been declared
// as `hidden`.
if cx.tcx.is_unreachable_local_definition(instance_def_id)
|| !cx.tcx.local_crate_exports_generics()
{ {
#[cfg(feature = "master")] // When not sharing generics, all instances are in the same
func.add_attribute(FnAttribute::Visibility(Visibility::Hidden)); // crate and have hidden visibility.
} true
} else if let Some(instance_def_id) = instance_def_id.as_local() {
// This is a monomorphization of a generic function
// defined in the current crate. It is hidden if:
// - the definition is unreachable for downstream
// 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()
} 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