Fix inlining with -Zalways-encode-mir

Only inline functions that are considered eligible for inlining
by the reachability pass.

This constraint was previously indirectly enforced by only exporting MIR
of eligible functions, but that approach doesn't work with
-Zalways-encode-mir enabled.
This commit is contained in:
Tomasz Miąsko 2023-08-27 00:00:00 +00:00
parent 8550f15e14
commit fe3cd2d194
3 changed files with 24 additions and 8 deletions

View File

@ -388,14 +388,11 @@ fn check_codegen_attributes(
return Err("never inline hint");
}
// Only inline local functions if they would be eligible for cross-crate
// inlining. This is to ensure that the final crate doesn't have MIR that
// reference unexported symbols
if callsite.callee.def_id().is_local() {
let is_generic = callsite.callee.args.non_erasable_generics().next().is_some();
if !is_generic && !callee_attrs.requests_inline() {
return Err("not exported");
}
// Reachability pass defines which functions are eligible for inlining. Generally inlining
// other functions is incorrect because they could reference symbols that aren't exported.
let is_generic = callsite.callee.args.non_erasable_generics().next().is_some();
if !is_generic && !callee_attrs.requests_inline() {
return Err("not exported");
}
if callsite.fn_sig.c_variadic() {

View File

@ -0,0 +1,12 @@
// Regression test for MIR inlining with -Zalways-encode-mir enabled in the auxiliary crate.
// Previously we inlined function not eligible for inlining which lead to linking error:
// undefined reference to `internal::S'
//
// aux-build:internal.rs
// build-pass
// compile-flags: -O
extern crate internal;
fn main() {
println!("{}", internal::f());
}

View File

@ -0,0 +1,7 @@
// compile-flags: -Zalways-encode-mir
static S: usize = 42;
pub fn f() -> &'static usize {
&S
}