@@ -353,10 +353,11 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {
353
353
354
354
// To be eligible for "unused function" mappings, a definition must:
355
355
// - Be function-like
356
- // - Not participate directly in codegen
356
+ // - Not participate directly in codegen (or have lost all its coverage statements)
357
357
// - Not have any coverage statements inlined into codegenned functions
358
358
tcx. def_kind ( def_id) . is_fn_like ( )
359
- && !usage. all_mono_items . contains ( & def_id)
359
+ && ( !usage. all_mono_items . contains ( & def_id)
360
+ || usage. missing_own_coverage . contains ( & def_id) )
360
361
&& !usage. used_via_inlining . contains ( & def_id)
361
362
} ;
362
363
@@ -379,6 +380,7 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {
379
380
struct UsageSets < ' tcx > {
380
381
all_mono_items : & ' tcx DefIdSet ,
381
382
used_via_inlining : FxHashSet < DefId > ,
383
+ missing_own_coverage : FxHashSet < DefId > ,
382
384
}
383
385
384
386
/// Prepare sets of definitions that are relevant to deciding whether something
@@ -406,8 +408,13 @@ fn prepare_usage_sets<'tcx>(tcx: TyCtxt<'tcx>) -> UsageSets<'tcx> {
406
408
407
409
// Functions whose coverage statments were found inlined into other functions.
408
410
let mut used_via_inlining = FxHashSet :: default ( ) ;
411
+ // Functions that were instrumented, but had all of their coverage statements
412
+ // removed by later MIR transforms (e.g. UnreachablePropagation).
413
+ let mut missing_own_coverage = FxHashSet :: default ( ) ;
414
+
415
+ for ( def_id, body) in def_and_mir_for_all_mono_fns {
416
+ let mut saw_own_coverage = false ;
409
417
410
- for ( _def_id, body) in def_and_mir_for_all_mono_fns {
411
418
// Inspect every coverage statement in the function's MIR.
412
419
for stmt in body
413
420
. basic_blocks
@@ -418,11 +425,18 @@ fn prepare_usage_sets<'tcx>(tcx: TyCtxt<'tcx>) -> UsageSets<'tcx> {
418
425
if let Some ( inlined) = stmt. source_info . scope . inlined_instance ( & body. source_scopes ) {
419
426
// This coverage statement was inlined from another function.
420
427
used_via_inlining. insert ( inlined. def_id ( ) ) ;
428
+ } else {
429
+ // Non-inlined coverage statements belong to the enclosing function.
430
+ saw_own_coverage = true ;
421
431
}
422
432
}
433
+
434
+ if !saw_own_coverage && body. function_coverage_info . is_some ( ) {
435
+ missing_own_coverage. insert ( def_id) ;
436
+ }
423
437
}
424
438
425
- UsageSets { all_mono_items, used_via_inlining }
439
+ UsageSets { all_mono_items, used_via_inlining, missing_own_coverage }
426
440
}
427
441
428
442
fn add_unused_function_coverage < ' tcx > (
0 commit comments