Skip to content

Commit ae84d25

Browse files
committed
Fix undefined function error
1 parent 3cb8b1b commit ae84d25

File tree

2 files changed

+62
-83
lines changed

2 files changed

+62
-83
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ jobs:
8787
8888
- name: Clean
8989
run: |
90-
./y.sh clean all
90+
./y.sh clean all
9191
9292
- name: Prepare dependencies
9393
run: |

src/callee.rs

Lines changed: 61 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -72,95 +72,74 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
7272

7373
attributes::from_fn_attrs(cx, func, instance);
7474

75-
let instance_def_id = instance.def_id();
76-
77-
// TODO(antoyo): set linkage and attributes.
78-
79-
// Apply an appropriate linkage/visibility value to our item that we
80-
// just declared.
81-
//
82-
// This is sort of subtle. Inside our codegen unit we started off
83-
// compilation by predefining all our own `MonoItem` instances. That
84-
// is, everything we're codegenning ourselves is already defined. That
85-
// means that anything we're actually codegenning in this codegen unit
86-
// will have hit the above branch in `get_declared_value`. As a result,
87-
// we're guaranteed here that we're declaring a symbol that won't get
88-
// defined, or in other words we're referencing a value from another
89-
// codegen unit or even another crate.
90-
//
91-
// So because this is a foreign value we blanket apply an external
92-
// linkage directive because it's coming from a different object file.
93-
// The visibility here is where it gets tricky. This symbol could be
94-
// referencing some foreign crate or foreign library (an `extern`
95-
// block) in which case we want to leave the default visibility. We may
96-
// also, though, have multiple codegen units. It could be a
97-
// monomorphization, in which case its expected visibility depends on
98-
// whether we are sharing generics or not. The important thing here is
99-
// that the visibility we apply to the declaration is the same one that
100-
// has been applied to the definition (wherever that definition may be).
101-
let is_generic = instance.args.non_erasable_generics().next().is_some();
102-
103-
if is_generic {
104-
// This is a monomorphization. Its expected visibility depends
105-
// on whether we are in share-generics mode.
106-
107-
if cx.tcx.sess.opts.share_generics() {
108-
// We are in share_generics mode.
109-
110-
if let Some(instance_def_id) = instance_def_id.as_local() {
111-
// This is a definition from the current crate. If the
112-
// definition is unreachable for downstream crates or
113-
// the current crate does not re-export generics, the
114-
// definition of the instance will have been declared
115-
// as `hidden`.
116-
if cx.tcx.is_unreachable_local_definition(instance_def_id)
75+
#[cfg(feature = "master")]
76+
{
77+
let instance_def_id = instance.def_id();
78+
79+
// TODO(antoyo): set linkage and attributes.
80+
81+
// Apply an appropriate linkage/visibility value to our item that we
82+
// just declared.
83+
//
84+
// This is sort of subtle. Inside our codegen unit we started off
85+
// compilation by predefining all our own `MonoItem` instances. That
86+
// is, everything we're codegenning ourselves is already defined. That
87+
// means that anything we're actually codegenning in this codegen unit
88+
// will have hit the above branch in `get_declared_value`. As a result,
89+
// we're guaranteed here that we're declaring a symbol that won't get
90+
// defined, or in other words we're referencing a value from another
91+
// codegen unit or even another crate.
92+
//
93+
// So because this is a foreign value we blanket apply an external
94+
// linkage directive because it's coming from a different object file.
95+
// The visibility here is where it gets tricky. This symbol could be
96+
// referencing some foreign crate or foreign library (an `extern`
97+
// block) in which case we want to leave the default visibility. We may
98+
// also, though, have multiple codegen units. It could be a
99+
// monomorphization, in which case its expected visibility depends on
100+
// whether we are sharing generics or not. The important thing here is
101+
// that the visibility we apply to the declaration is the same one that
102+
// has been applied to the definition (wherever that definition may be).
103+
let is_generic = instance.args.non_erasable_generics().next().is_some();
104+
105+
let is_hidden = if is_generic {
106+
// This is a monomorphization of a generic function.
107+
if !(cx.tcx.sess.opts.share_generics()
108+
|| tcx.codegen_fn_attrs(instance_def_id).inline
109+
== rustc_attr::InlineAttr::Never)
110+
{
111+
// When not sharing generics, all instances are in the same
112+
// crate and have hidden visibility.
113+
true
114+
} else if let Some(instance_def_id) = instance_def_id.as_local() {
115+
// This is a monomorphization of a generic function
116+
// defined in the current crate. It is hidden if:
117+
// - the definition is unreachable for downstream
118+
// crates, or
119+
// - the current crate does not re-export generics
120+
// (because the crate is a C library or executable)
121+
cx.tcx.is_unreachable_local_definition(instance_def_id)
117122
|| !cx.tcx.local_crate_exports_generics()
118-
{
119-
#[cfg(feature = "master")]
120-
func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
121-
}
122123
} else {
123124
// This is a monomorphization of a generic function
124-
// defined in an upstream crate.
125-
if instance.upstream_monomorphization(tcx).is_some() {
126-
// This is instantiated in another crate. It cannot
127-
// be `hidden`.
128-
} else {
129-
// This is a local instantiation of an upstream definition.
130-
// If the current crate does not re-export it
131-
// (because it is a C library or an executable), it
132-
// will have been declared `hidden`.
133-
if !cx.tcx.local_crate_exports_generics() {
134-
#[cfg(feature = "master")]
135-
func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
136-
}
137-
}
125+
// defined in an upstream crate. It is hidden if:
126+
// - it is instantiated in this crate, and
127+
// - the current crate does not re-export generics
128+
instance.upstream_monomorphization(tcx).is_none()
129+
&& !cx.tcx.local_crate_exports_generics()
138130
}
139131
} else {
140-
// When not sharing generics, all instances are in the same
141-
// crate and have hidden visibility
142-
#[cfg(feature = "master")]
132+
// This is a non-generic function. It is hidden if:
133+
// - it is instantiated in the local crate, and
134+
// - it is defined an upstream crate (non-local), or
135+
// - it is not reachable
136+
cx.tcx.is_codegened_item(instance_def_id)
137+
&& (!instance_def_id.is_local()
138+
|| !cx.tcx.is_reachable_non_generic(instance_def_id))
139+
};
140+
if is_hidden {
143141
func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
144142
}
145-
} else {
146-
// This is a non-generic function
147-
if cx.tcx.is_codegened_item(instance_def_id) {
148-
// This is a function that is instantiated in the local crate
149-
150-
if instance_def_id.is_local() {
151-
// This is function that is defined in the local crate.
152-
// If it is not reachable, it is hidden.
153-
if !cx.tcx.is_reachable_non_generic(instance_def_id) {
154-
#[cfg(feature = "master")]
155-
func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
156-
}
157-
} else {
158-
// This is a function from an upstream crate that has
159-
// been instantiated here. These are always hidden.
160-
#[cfg(feature = "master")]
161-
func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
162-
}
163-
}
164143
}
165144

166145
func

0 commit comments

Comments
 (0)