@@ -1244,12 +1244,6 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
12441244 } else {
12451245 bug ! ( "Every BasicCoverageBlock should have a Counter or Expression" ) ;
12461246 } ;
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- ) ;
12531247 if let Some ( bcb_to_coverage_spans_with_counters) =
12541248 debug_bcb_to_coverage_spans_with_counters. as_mut ( )
12551249 {
@@ -1258,25 +1252,12 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
12581252 . or_insert_with ( || Vec :: new ( ) )
12591253 . push ( ( covspan. clone ( ) , counter_kind. clone ( ) ) ) ;
12601254 }
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) )
12781259 } ;
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 ) ;
12801261 }
12811262
12821263 // The previous step looped through the `CoverageSpan`s and injected the counter from the
@@ -1423,18 +1404,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
14231404 target_bb
14241405 } ;
14251406
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 ) ;
14381408 }
14391409 CoverageKind :: Expression { .. } => {
14401410 self . inject_intermediate_expression ( counter_kind)
@@ -1583,6 +1553,28 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
15831553 }
15841554 }
15851555
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+
15861578 /// Traverse the BCB CFG and add either a `Counter` or `Expression` to ever BCB, to be
15871579 /// injected with `CoverageSpan`s. `Expressions` have no runtime overhead, so if a viable
15881580 /// expression (adding or subtracting two other counters or expressions) can compute the same
@@ -2139,16 +2131,19 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
21392131 & mut self ,
21402132 counter_kind : CoverageKind ,
21412133 bb : BasicBlock ,
2142- code_region : CodeRegion ,
2134+ some_code_region : Option < CodeRegion > ,
21432135 ) {
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+ ) ;
21452140 let data = & mut self . mir_body [ bb] ;
21462141 let source_info = data. terminator ( ) . source_info ;
21472142 let statement = Statement {
21482143 source_info,
21492144 kind : StatementKind :: Coverage ( box Coverage {
21502145 kind : counter_kind,
2151- code_region : Some ( code_region ) ,
2146+ code_region : some_code_region ,
21522147 } ) ,
21532148 } ;
21542149 data. statements . push ( statement) ;
@@ -2762,8 +2757,8 @@ fn filtered_terminator_span(terminator: &'a Terminator<'tcx>, body_span: Span) -
27622757 //
27632758 // However, in other cases, a visible `CoverageSpan` is not wanted, but the `Goto`
27642759 // 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 `.
27672762 TerminatorKind :: Goto { .. } => {
27682763 Some ( function_source_span ( terminator. source_info . span . shrink_to_hi ( ) , body_span) )
27692764 }
@@ -2788,35 +2783,6 @@ fn function_source_span(span: Span, body_span: Span) -> Span {
27882783 if body_span. contains ( span) { span } else { body_span }
27892784}
27902785
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-
28202786/// Convert the Span into its file name, start line and column, and end line and column
28212787fn make_code_region (
28222788 file_name : Symbol ,
0 commit comments