@@ -96,10 +96,14 @@ our %ERROR_ID = (
96
96
our $EXCL_START = " LCOV_EXCL_START" ;
97
97
our $EXCL_STOP = " LCOV_EXCL_STOP" ;
98
98
99
- # Marker to exclude branch coverage but keep function and line coveage
99
+ # Marker to exclude branch coverage but keep function and line coverage
100
100
our $EXCL_BR_START = " LCOV_EXCL_BR_START" ;
101
101
our $EXCL_BR_STOP = " LCOV_EXCL_BR_STOP" ;
102
102
103
+ # Marker to exclude exception branch coverage but keep function, line coverage and non-exception branch coverage
104
+ our $EXCL_EXCEPTION_BR_START = " LCOV_EXCL_EXCEPTION_BR_START" ;
105
+ our $EXCL_EXCEPTION_BR_STOP = " LCOV_EXCL_EXCEPTION_BR_STOP" ;
106
+
103
107
# Compatibility mode values
104
108
our $COMPAT_VALUE_OFF = 0;
105
109
our $COMPAT_VALUE_ON = 1;
@@ -268,11 +272,13 @@ our %compat_value;
268
272
our $gcno_split_crc ;
269
273
our $func_coverage = 1;
270
274
our $br_coverage = 0;
275
+ our $no_exception_br = 0;
271
276
our $rc_auto_base = 1;
272
277
our $rc_intermediate = " auto" ;
273
278
our $intermediate ;
274
279
our $excl_line = " LCOV_EXCL_LINE" ;
275
280
our $excl_br_line = " LCOV_EXCL_BR_LINE" ;
281
+ our $excl_exception_br_line = " LCOV_EXCL_EXCEPTION_BR_LINE" ;
276
282
277
283
our $cwd = ` pwd` ;
278
284
chomp ($cwd );
@@ -339,10 +345,12 @@ if ($config || %opt_rc)
339
345
" geninfo_adjust_src_path" => \$rc_adjust_src_path ,
340
346
" geninfo_auto_base" => \$rc_auto_base ,
341
347
" geninfo_intermediate" => \$rc_intermediate ,
348
+ " geninfo_no_exception_branch" => \$no_exception_br ,
342
349
" lcov_function_coverage" => \$func_coverage ,
343
350
" lcov_branch_coverage" => \$br_coverage ,
344
351
" lcov_excl_line" => \$excl_line ,
345
352
" lcov_excl_br_line" => \$excl_br_line ,
353
+ " lcov_excl_exception_br_line" => \$excl_exception_br_line ,
346
354
});
347
355
348
356
# Merge options
@@ -372,7 +380,7 @@ if ($config || %opt_rc)
372
380
$adjust_src_replace = $replace ;
373
381
}
374
382
}
375
- for my $regexp (($excl_line , $excl_br_line )) {
383
+ for my $regexp (($excl_line , $excl_br_line , $excl_exception_br_line )) {
376
384
eval ' qr/' .$regexp .' /' ;
377
385
my $error = $@ ;
378
386
chomp ($error );
@@ -476,8 +484,9 @@ if ($rc_intermediate eq "0") {
476
484
} elsif ($rc_intermediate eq " 1" ) {
477
485
$intermediate = 1;
478
486
} elsif (lc ($rc_intermediate ) eq " auto" ) {
479
- # Use intermediate format if supported by gcov
480
- $intermediate = ($gcov_caps -> {' intermediate-format' } ||
487
+ # Use intermediate format if supported by gcov and not conflicting with
488
+ # exception branch exclusion
489
+ $intermediate = (($gcov_caps -> {' intermediate-format' } && !$no_exception_br ) ||
481
490
$gcov_caps -> {' json-format' }) ? 1 : 0;
482
491
} else {
483
492
die (" ERROR: invalid value for geninfo_intermediate: " .
@@ -491,6 +500,15 @@ if ($intermediate) {
491
500
" intermediate format - ignoring\n " );
492
501
$opt_derive_func_data = 0;
493
502
}
503
+ if ($no_exception_br && !$gcov_caps -> {' json-format' }) {
504
+ die (" ERROR: excluding exception branches is not compatible with " .
505
+ " text intermediate format\n " );
506
+ }
507
+ }
508
+
509
+ if ($no_exception_br && ($gcov_version < $GCOV_VERSION_3_3_0 )) {
510
+ die (" ERROR: excluding exception branches is not compatible with " .
511
+ " gcov versions older than 3.3\n " );
494
512
}
495
513
496
514
# Determine gcov options
@@ -1843,7 +1861,9 @@ sub read_gcov_file($)
1843
1861
my $exclude_flag = 0;
1844
1862
my $exclude_line = 0;
1845
1863
my $exclude_br_flag = 0;
1864
+ my $exclude_exception_br_flag = 0;
1846
1865
my $exclude_branch = 0;
1866
+ my $exclude_exception_branch = 0;
1847
1867
my $last_block = $UNNAMED_BLOCK ;
1848
1868
my $last_line = 0;
1849
1869
local *INPUT;
@@ -1913,6 +1933,13 @@ sub read_gcov_file($)
1913
1933
$exclude_branch = 0;
1914
1934
}
1915
1935
}
1936
+ # Check for exclusion markers (exception branch exclude)
1937
+ if (!$no_markers &&
1938
+ / ($EXCL_EXCEPTION_BR_STOP |$EXCL_EXCEPTION_BR_START |$excl_exception_br_line )/ ) {
1939
+ warn (" WARNING: $1 found at $filename :$last_line but " .
1940
+ " branch exceptions exclusion is not supported with " .
1941
+ " gcov versions older than 3.3\n " );
1942
+ }
1916
1943
# Source code execution data
1917
1944
if (/ ^\t\t (.*)$ / )
1918
1945
{
@@ -1955,10 +1982,12 @@ sub read_gcov_file($)
1955
1982
# branches
1956
1983
$last_line = $2 ;
1957
1984
$last_block = $3 ;
1958
- } elsif (/ ^branch\s +(\d +)\s +taken\s +(\d +)/ ) {
1985
+ } elsif (/ ^branch\s +(\d +)\s +taken\s +(\d +)(?: \s + \( ([^)]*) \) )? / ) {
1959
1986
next if (!$br_coverage );
1960
1987
next if ($exclude_line );
1961
1988
next if ($exclude_branch );
1989
+ next if (($exclude_exception_branch || $no_exception_br ) &&
1990
+ defined ($3 ) && ($3 eq " throw" ));
1962
1991
$branches = br_gvec_push($branches , $last_line ,
1963
1992
$last_block , $1 , $2 );
1964
1993
} elsif (/ ^branch\s +(\d +)\s +never\s +executed/ ) {
@@ -2015,6 +2044,19 @@ sub read_gcov_file($)
2015
2044
$exclude_branch = 0;
2016
2045
}
2017
2046
}
2047
+ # Check for exclusion markers (exception branch exclude)
2048
+ if (!$no_markers ) {
2049
+ if (/ $EXCL_EXCEPTION_BR_STOP / ) {
2050
+ $exclude_exception_br_flag = 0;
2051
+ } elsif (/ $EXCL_EXCEPTION_BR_START / ) {
2052
+ $exclude_exception_br_flag = 1;
2053
+ }
2054
+ if (/ $excl_exception_br_line / || $exclude_exception_br_flag ) {
2055
+ $exclude_exception_branch = 1;
2056
+ } else {
2057
+ $exclude_exception_branch = 0;
2058
+ }
2059
+ }
2018
2060
2019
2061
# Strip unexecuted basic block marker
2020
2062
$count =~ s /\* $// ;
@@ -2051,7 +2093,7 @@ sub read_gcov_file($)
2051
2093
}
2052
2094
2053
2095
close (INPUT);
2054
- if ($exclude_flag || $exclude_br_flag ) {
2096
+ if ($exclude_flag || $exclude_br_flag || $exclude_exception_br_flag ) {
2055
2097
warn (" WARNING: unterminated exclusion section in $filename \n " );
2056
2098
}
2057
2099
return (\@result , $branches , \@functions );
@@ -2137,6 +2179,7 @@ sub read_intermediate_json($$$)
2137
2179
# srcdata: filename -> [ excl, brexcl, checksums ]
2138
2180
# excl: lineno -> 1 for all lines for which to exclude all data
2139
2181
# brexcl: lineno -> 1 for all lines for which to exclude branch data
2182
+ # 2 for all lines for which to exclude exception branch data
2140
2183
# checksums: lineno -> source code checksum
2141
2184
#
2142
2185
# Note: To simplify processing, gcov data is not combined here, that is counts
@@ -2211,7 +2254,7 @@ sub intermediate_text_to_info($$$)
2211
2254
$functions_hit ++ if ($2 > 0);
2212
2255
} elsif ($line =~ / ^branch:(\d +),(taken|nottaken|notexec)/ ) {
2213
2256
next if (!$br_coverage || $excl -> {$1 } ||
2214
- $brexcl -> {$1 });
2257
+ ( defined ( $brexcl -> {$1 }) && ( $brexcl -> { $1 } == 1)) );
2215
2258
2216
2259
# branch:<line>,taken|nottaken|notexec
2217
2260
if ($2 eq " taken" ) {
@@ -2255,6 +2298,7 @@ sub intermediate_text_to_info($$$)
2255
2298
# srcdata: filename -> [ excl, brexcl, checksums ]
2256
2299
# excl: lineno -> 1 for all lines for which to exclude all data
2257
2300
# brexcl: lineno -> 1 for all lines for which to exclude branch data
2301
+ # 2 for all lines for which to exclude exception branch data
2258
2302
# checksums: lineno -> source code checksum
2259
2303
#
2260
2304
# Note: To simplify processing, gcov data is not combined here, that is counts
@@ -2338,15 +2382,20 @@ sub intermediate_json_to_info($$$)
2338
2382
2339
2383
$branch_num = 0;
2340
2384
# Branch data
2341
- if ($br_coverage && !$brexcl -> {$line }) {
2385
+ if ($br_coverage && (!defined ($brexcl -> {$line }) ||
2386
+ ($brexcl -> {$line } != 1))) {
2342
2387
for my $b (@$branches ) {
2343
2388
my $brcount = $b -> {" count" };
2389
+ my $is_exception = $b -> {" throw" };
2344
2390
2345
- if (!defined ($brcount ) || $unexec ) {
2346
- $brcount = " -" ;
2391
+ if (!$is_exception || ((!defined ($brexcl -> {$line }) ||
2392
+ ($brexcl -> {$line } != 2)) && !$no_exception_br )) {
2393
+ if (!defined ($brcount ) || $unexec ) {
2394
+ $brcount = " -" ;
2395
+ }
2396
+ print ($fd " BRDA:$line ,0,$branch_num ," .
2397
+ " $brcount \n " );
2347
2398
}
2348
- print ($fd " BRDA:$line ,0,$branch_num ," .
2349
- " $brcount \n " );
2350
2399
2351
2400
$branches_found ++;
2352
2401
$branches_hit ++ if ($brcount > 0);
@@ -2844,6 +2893,7 @@ sub get_source_data($)
2844
2893
my $flag = 0;
2845
2894
my %brdata ;
2846
2895
my $brflag = 0;
2896
+ my $exceptionbrflag = 0;
2847
2897
my %checksums ;
2848
2898
local *HANDLE;
2849
2899
@@ -2865,13 +2915,26 @@ sub get_source_data($)
2865
2915
} elsif (/ $EXCL_BR_START / ) {
2866
2916
$brflag = 1;
2867
2917
}
2918
+ if (/ $EXCL_EXCEPTION_BR_STOP / ) {
2919
+ $exceptionbrflag = 0;
2920
+ } elsif (/ $EXCL_EXCEPTION_BR_START / ) {
2921
+ $exceptionbrflag = 1;
2922
+ }
2868
2923
if (/ $excl_br_line / || $brflag ) {
2869
2924
$brdata {$. } = 1;
2925
+ } elsif (/ $excl_exception_br_line / || $exceptionbrflag ) {
2926
+ $brdata {$. } = 2;
2870
2927
}
2871
2928
if ($checksum ) {
2872
2929
chomp ();
2873
2930
$checksums {$. } = md5_base64($_ );
2874
2931
}
2932
+ if ($intermediate && !$gcov_caps -> {' json-format' } &&
2933
+ / ($EXCL_EXCEPTION_BR_STOP |$EXCL_EXCEPTION_BR_START |$excl_exception_br_line )/ ) {
2934
+ warn (" WARNING: $1 found at $filename :$. but branch exceptions " .
2935
+ " exclusion is not supported when using text intermediate " .
2936
+ " format\n " );
2937
+ }
2875
2938
}
2876
2939
close (HANDLE);
2877
2940
0 commit comments