@@ -1244,12 +1244,6 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
1244
1244
} else {
1245
1245
bug ! ( "Every BasicCoverageBlock should have a Counter or Expression" ) ;
1246
1246
} ;
1247
- debug ! (
1248
- "Injecting {} at: {:?}:\n {}\n ==========" ,
1249
- self . format_counter( & counter_kind) ,
1250
- span,
1251
- source_map. span_to_snippet( span) . expect( "Error getting source for span" ) ,
1252
- ) ;
1253
1247
if let Some ( bcb_to_coverage_spans_with_counters) =
1254
1248
debug_bcb_to_coverage_spans_with_counters. as_mut ( )
1255
1249
{
@@ -1258,25 +1252,12 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
1258
1252
. or_insert_with ( || Vec :: new ( ) )
1259
1253
. push ( ( covspan. clone ( ) , counter_kind. clone ( ) ) ) ;
1260
1254
}
1261
- let mut code_region = None ;
1262
- if span. hi ( ) == body_span. hi ( ) {
1263
- // All functions execute a `Return`-terminated `BasicBlock`, regardless of how the
1264
- // function returns; but only some functions also _can_ return after a `Goto` block
1265
- // that ends on the closing brace of the function (with the `Return`). When this
1266
- // happens, the last character is counted 2 (or possibly more) times, when we know
1267
- // the function returned only once (of course). By giving all `Goto` terminators at
1268
- // the end of a function a `non-reportable` code region, they are still counted
1269
- // if appropriate, but they don't increment the line counter, as long as their is
1270
- // also a `Return` on that last line.
1271
- if let TerminatorKind :: Goto { .. } = self . bcb_terminator ( bcb) . kind {
1272
- code_region =
1273
- Some ( make_non_reportable_code_region ( file_name, & source_file, span) ) ;
1274
- }
1275
- }
1276
- if code_region. is_none ( ) {
1277
- code_region = Some ( make_code_region ( file_name, & source_file, span, body_span) ) ;
1255
+ let some_code_region = if self . is_code_region_redundant ( bcb, span, body_span) {
1256
+ None
1257
+ } else {
1258
+ Some ( make_code_region ( file_name, & source_file, span, body_span) )
1278
1259
} ;
1279
- self . inject_statement ( counter_kind, self . bcb_last_bb ( bcb) , code_region . unwrap ( ) ) ;
1260
+ self . inject_statement ( counter_kind, self . bcb_last_bb ( bcb) , some_code_region ) ;
1280
1261
}
1281
1262
1282
1263
// The previous step looped through the `CoverageSpan`s and injected the counter from the
@@ -1423,18 +1404,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
1423
1404
target_bb
1424
1405
} ;
1425
1406
1426
- let span = self . mir_body [ inject_to_bb] . terminator ( ) . source_info . span ;
1427
- debug ! (
1428
- "make_non_reportable_code_region for {:?} at span={:?}, counter={}" ,
1429
- inject_to_bb,
1430
- span,
1431
- self . format_counter( & counter_kind)
1432
- ) ;
1433
- self . inject_statement (
1434
- counter_kind,
1435
- inject_to_bb,
1436
- make_non_reportable_code_region ( file_name, & source_file, span) ,
1437
- ) ;
1407
+ self . inject_statement ( counter_kind, inject_to_bb, None ) ;
1438
1408
}
1439
1409
CoverageKind :: Expression { .. } => {
1440
1410
self . inject_intermediate_expression ( counter_kind)
@@ -1583,6 +1553,28 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
1583
1553
}
1584
1554
}
1585
1555
1556
+ fn is_code_region_redundant (
1557
+ & self ,
1558
+ bcb : BasicCoverageBlock ,
1559
+ span : Span ,
1560
+ body_span : Span ,
1561
+ ) -> bool {
1562
+ if span. hi ( ) == body_span. hi ( ) {
1563
+ // All functions execute a `Return`-terminated `BasicBlock`, regardless of how the
1564
+ // function returns; but only some functions also _can_ return after a `Goto` block
1565
+ // that ends on the closing brace of the function (with the `Return`). When this
1566
+ // happens, the last character is counted 2 (or possibly more) times, when we know
1567
+ // the function returned only once (of course). By giving all `Goto` terminators at
1568
+ // the end of a function a `non-reportable` code region, they are still counted
1569
+ // if appropriate, but they don't increment the line counter, as long as their is
1570
+ // also a `Return` on that last line.
1571
+ if let TerminatorKind :: Goto { .. } = self . bcb_terminator ( bcb) . kind {
1572
+ return true ;
1573
+ }
1574
+ }
1575
+ false
1576
+ }
1577
+
1586
1578
/// Traverse the BCB CFG and add either a `Counter` or `Expression` to ever BCB, to be
1587
1579
/// injected with `CoverageSpan`s. `Expressions` have no runtime overhead, so if a viable
1588
1580
/// expression (adding or subtracting two other counters or expressions) can compute the same
@@ -2139,16 +2131,19 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
2139
2131
& mut self ,
2140
2132
counter_kind : CoverageKind ,
2141
2133
bb : BasicBlock ,
2142
- code_region : CodeRegion ,
2134
+ some_code_region : Option < CodeRegion > ,
2143
2135
) {
2144
- debug ! ( " injecting statement {:?} covering {:?}" , counter_kind, code_region) ;
2136
+ debug ! (
2137
+ " injecting statement {:?} for {:?} at code region: {:?}" ,
2138
+ counter_kind, bb, some_code_region
2139
+ ) ;
2145
2140
let data = & mut self . mir_body [ bb] ;
2146
2141
let source_info = data. terminator ( ) . source_info ;
2147
2142
let statement = Statement {
2148
2143
source_info,
2149
2144
kind : StatementKind :: Coverage ( box Coverage {
2150
2145
kind : counter_kind,
2151
- code_region : Some ( code_region ) ,
2146
+ code_region : some_code_region ,
2152
2147
} ) ,
2153
2148
} ;
2154
2149
data. statements . push ( statement) ;
@@ -2762,8 +2757,8 @@ fn filtered_terminator_span(terminator: &'a Terminator<'tcx>, body_span: Span) -
2762
2757
//
2763
2758
// However, in other cases, a visible `CoverageSpan` is not wanted, but the `Goto`
2764
2759
// block must still be counted (for example, to contribute its count to an `Expression`
2765
- // that reports the execution count for some other block). The code region for the `Goto`
2766
- // counters, in these cases, is created using `make_non_reportable_code_region() `.
2760
+ // that reports the execution count for some other block). In these cases, the code region
2761
+ // is set to `None `.
2767
2762
TerminatorKind :: Goto { .. } => {
2768
2763
Some ( function_source_span ( terminator. source_info . span . shrink_to_hi ( ) , body_span) )
2769
2764
}
@@ -2788,35 +2783,6 @@ fn function_source_span(span: Span, body_span: Span) -> Span {
2788
2783
if body_span. contains ( span) { span } else { body_span }
2789
2784
}
2790
2785
2791
- /// Make a non-reportable code region. (Used coverage-generated "edge counters", and for some
2792
- /// `Goto`-terminated blocks.)
2793
- ///
2794
- /// Only the `Span`s `hi()` position is used, and an empty `Span` at that location is generated,
2795
- /// for coverage counting.
2796
- ///
2797
- /// The coverage map generation phase (part of codegen) knows to report any `Counter` or
2798
- /// `Expression` with an empty span as what LLVM's Coverage Mapping Specification calls a
2799
- /// `GapRegion`, rather than a `CodeRegion` (used in all other cases). Counters associated with a
2800
- /// `GapRegion` still contribute their counter values to other expressions, but if the `GapRegion`s
2801
- /// line has any other `CodeRegion` covering the same line, the `GapRegion` will not be counted
2802
- /// toward the line execution count. This prevents double-counting line execution, which would
2803
- /// otherwise occur.
2804
- fn make_non_reportable_code_region (
2805
- file_name : Symbol ,
2806
- source_file : & Lrc < SourceFile > ,
2807
- span : Span ,
2808
- ) -> CodeRegion {
2809
- let ( start_line, start_col) = source_file. lookup_file_pos ( span. hi ( ) ) ;
2810
- let ( end_line, end_col) = ( start_line, start_col) ;
2811
- CodeRegion {
2812
- file_name,
2813
- start_line : start_line as u32 ,
2814
- start_col : start_col. to_u32 ( ) + 1 ,
2815
- end_line : end_line as u32 ,
2816
- end_col : end_col. to_u32 ( ) + 1 ,
2817
- }
2818
- }
2819
-
2820
2786
/// Convert the Span into its file name, start line and column, and end line and column
2821
2787
fn make_code_region (
2822
2788
file_name : Symbol ,
0 commit comments