about summary refs log tree commit diff
path: root/compiler/rustc_monomorphize
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2023-06-15 09:50:48 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2023-06-15 10:39:04 +1000
commit57a7c8f577abd12ef4bb404448c42d794a76c690 (patch)
treefdc6420e8ef844954cc082356aa0a4da7b4cab09 /compiler/rustc_monomorphize
parent9d7295f0be2c90a98b6a7ce5f24ddef96dea10b7 (diff)
downloadrust-57a7c8f577abd12ef4bb404448c42d794a76c690.tar.gz
rust-57a7c8f577abd12ef4bb404448c42d794a76c690.zip
Fix bug in `mark_code_coverage_dead_code_cgus`.
The comment says "Find the smallest CGU that has exported symbols and
put the dead function stubs in that CGU". But the code sorts the CGUs by
size (smallest first) and then searches them in reverse order, which
means it will find the *largest* CGU that has exported symbols.

The erroneous code was introduced in #92142.

This commit changes it to use a simpler search, avoiding the sort, and
fixes the bug in the process.
Diffstat (limited to 'compiler/rustc_monomorphize')
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs21
1 files changed, 8 insertions, 13 deletions
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index 2a314727744..de57992beac 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -529,20 +529,15 @@ fn mark_code_coverage_dead_code_cgu<'tcx>(codegen_units: &mut [CodegenUnit<'tcx>
     // the object file (CGU) containing the dead function stubs is included
     // in the final binary. This will probably require forcing these
     // function symbols to be included via `-u` or `/include` linker args.
-    let mut cgus: Vec<&mut CodegenUnit<'tcx>> = codegen_units.iter_mut().collect();
-    cgus.sort_by_key(|cgu| cgu.size_estimate());
+    let dead_code_cgu = codegen_units
+        .iter_mut()
+        .filter(|cgu| cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External))
+        .min_by_key(|cgu| cgu.size_estimate());
+
+    // If there are no CGUs that have externally linked items, then we just
+    // pick the first CGU as a fallback.
+    let dead_code_cgu = if let Some(cgu) = dead_code_cgu { cgu } else { &mut codegen_units[0] };
 
-    let dead_code_cgu = if let Some(cgu) = cgus
-        .into_iter()
-        .rev()
-        .find(|cgu| cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External))
-    {
-        cgu
-    } else {
-        // If there are no CGUs that have externally linked items,
-        // then we just pick the first CGU as a fallback.
-        &mut codegen_units[0]
-    };
     dead_code_cgu.make_code_coverage_dead_code_cgu();
 }