From cdb07de7c67cf0d04607ee8e85a659d8bf7594f6 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 31 Oct 2017 12:57:43 +0100 Subject: [PATCH] GCOV: add support for lines with an unexecuted lines. 2017-10-31 Martin Liska * doc/gcov.texi: Document that. * gcov.c (add_line_counts): Mark lines with a non-executed statement. (output_line_beginning): Handle such lines. (output_lines): Pass new argument. (output_intermediate_file): Print it in intermediate format. 2017-10-31 Martin Liska * g++.dg/gcov/ternary.C: New test. * g++.dg/gcov/gcov-threads-1.C (main): Update expected line count. * lib/gcov.exp: Support new format for intermediate file format. From-SVN: r254259 --- gcc/ChangeLog | 9 ++++++ gcc/doc/gcov.texi | 13 +++++--- gcc/gcov.c | 50 ++++++++++++++---------------- gcc/testsuite/ChangeLog | 7 +++++ gcc/testsuite/g++.dg/gcov/gcov-threads-1.C | 4 +-- gcc/testsuite/g++.dg/gcov/ternary.C | 12 +++++++ gcc/testsuite/lib/gcov.exp | 2 +- 7 files changed, 62 insertions(+), 35 deletions(-) create mode 100644 gcc/testsuite/g++.dg/gcov/ternary.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b1d984a..0b26806 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2017-10-31 Martin Liska + * doc/gcov.texi: Document that. + * gcov.c (add_line_counts): Mark lines with a non-executed + statement. + (output_line_beginning): Handle such lines. + (output_lines): Pass new argument. + (output_intermediate_file): Print it in intermediate format. + +2017-10-31 Martin Liska + * color-macros.h: New file. * diagnostic-color.c: Factor out color related to macros to color-macros.h. diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi index 9abc603..e186ac6 100644 --- a/gcc/doc/gcov.texi +++ b/gcc/doc/gcov.texi @@ -189,7 +189,7 @@ one entry per line @smallexample file:@var{source_file_name} function:@var{line_number},@var{execution_count},@var{function_name} -lcount:@var{line number},@var{execution_count} +lcount:@var{line number},@var{execution_count},@var{has_unexecuted_block} branch:@var{line_number},@var{branch_coverage_type} Where the @var{branch_coverage_type} is @@ -208,11 +208,11 @@ Here is a sample when @option{-i} is used in conjunction with @option{-b} option file:array.cc function:11,1,_Z3sumRKSt6vectorIPiSaIS0_EE function:22,1,main -lcount:11,1 -lcount:12,1 -lcount:14,1 +lcount:11,1,0 +lcount:12,1,0 +lcount:14,1,0 branch:14,taken -lcount:26,1 +lcount:26,1,0 branch:28,nottaken @end smallexample @@ -336,6 +336,9 @@ non-exceptional paths or only exceptional paths such as C++ exception handlers, respectively. Given @samp{-a} option, unexecuted blocks are marked @samp{$$$$$} or @samp{%%%%%}, depending on whether a basic block is reachable via non-exceptional or exceptional paths. +Executed basic blocks having a statement with zero @var{execution_count} +end with @samp{*} character and are colored with magenta color with @option{-k} +option. Note that GCC can completely remove the bodies of functions that are not needed -- for instance if they are inlined everywhere. Such functions diff --git a/gcc/gcov.c b/gcc/gcov.c index e53bcf0..f9334f9 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -256,6 +256,7 @@ typedef struct line_info Used in all-blocks mode. */ unsigned exists : 1; unsigned unexceptional : 1; + unsigned has_unexecuted_block : 1; } line_t; bool @@ -850,28 +851,7 @@ process_args (int argc, char **argv) /* Output the result in intermediate format used by 'lcov'. The intermediate format contains a single file named 'foo.cc.gcov', -with no source code included. A sample output is - -file:foo.cc -function:5,1,_Z3foov -function:13,1,main -function:19,1,_GLOBAL__sub_I__Z3foov -function:19,1,_Z41__static_initialization_and_destruction_0ii -lcount:5,1 -lcount:7,9 -lcount:9,8 -lcount:11,1 -file:/.../iostream -lcount:74,1 -file:/.../basic_ios.h -file:/.../ostream -file:/.../ios_base.h -function:157,0,_ZStorSt12_Ios_IostateS_ -lcount:157,0 -file:/.../char_traits.h -function:258,0,_ZNSt11char_traitsIcE6lengthEPKc -lcount:258,0 -... +with no source code included. The default gcov outputs multiple files: 'foo.cc.gcov', 'iostream.gcov', 'ios_base.h.gcov', etc. with source code @@ -901,8 +881,8 @@ output_intermediate_file (FILE *gcov_file, source_t *src) { arc_t *arc; if (line->exists) - fprintf (gcov_file, "lcount:%u,%s\n", line_num, - format_gcov (line->count, 0, -1)); + fprintf (gcov_file, "lcount:%u,%s,%d\n", line_num, + format_gcov (line->count, 0, -1), line->has_unexecuted_block); if (flag_branches) for (arc = line->branches; arc; arc = arc->line_next) { @@ -2289,7 +2269,11 @@ add_line_counts (coverage_t *coverage, function_t *fn) } line->exists = 1; if (!block->exceptional) - line->unexceptional = 1; + { + line->unexceptional = 1; + if (block->count == 0) + line->has_unexecuted_block = 1; + } line->count += block->count; } } @@ -2496,6 +2480,7 @@ pad_count_string (string &s) static void output_line_beginning (FILE *f, bool exists, bool unexceptional, + bool has_unexecuted_block, gcov_type count, unsigned line_num, const char *exceptional_string, const char *unexceptional_string) @@ -2506,6 +2491,17 @@ output_line_beginning (FILE *f, bool exists, bool unexceptional, if (count > 0) { s = format_gcov (count, 0, -1); + if (has_unexecuted_block) + { + if (flag_use_colors) + { + pad_count_string (s); + s = SGR_SEQ (COLOR_BG_MAGENTA COLOR_SEPARATOR COLOR_FG_WHITE); + s += SGR_RESET; + } + else + s += "*"; + } pad_count_string (s); } else @@ -2610,7 +2606,7 @@ output_lines (FILE *gcov_file, const source_t *src) There are 16 spaces of indentation added before the source line so that tabs won't be messed up. */ output_line_beginning (gcov_file, line->exists, line->unexceptional, - line->count, line_num, + line->has_unexecuted_block, line->count, line_num, "=====", "#####"); fprintf (gcov_file, ":%s\n", retval ? retval : "/*EOF*/"); @@ -2626,7 +2622,7 @@ output_lines (FILE *gcov_file, const source_t *src) if (!block->is_call_return) { output_line_beginning (gcov_file, line->exists, - block->exceptional, + block->exceptional, false, block->count, line_num, "%%%%%", "$$$$$"); fprintf (gcov_file, "-block %2d", ix++); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c371350..a1adb14 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2017-10-31 Martin Liska + + * g++.dg/gcov/ternary.C: New test. + * g++.dg/gcov/gcov-threads-1.C (main): Update expected line + count. + * lib/gcov.exp: Support new format for intermediate file format. + 2017-11-01 Julia Koval * gcc.target/i386/avx-1.c: Handle new intrinsics. diff --git a/gcc/testsuite/g++.dg/gcov/gcov-threads-1.C b/gcc/testsuite/g++.dg/gcov/gcov-threads-1.C index cc9266a..cc912f9 100644 --- a/gcc/testsuite/g++.dg/gcov/gcov-threads-1.C +++ b/gcc/testsuite/g++.dg/gcov/gcov-threads-1.C @@ -31,14 +31,14 @@ int main(int argc, char **argv) { { ids[i] = i; int r = pthread_create (&t[i], NULL, ContentionNoDeadlock_thread, &ids[i]); - assert (r == 0); /* count(5) */ + assert (r == 0); /* count(5*) */ } int ret; for (int i = 0; i < NR; i++) { int r = pthread_join (t[i], (void**)&ret); - assert (r == 0); /* count(5) */ + assert (r == 0); /* count(5*) */ } return 0; /* count(1) */ diff --git a/gcc/testsuite/g++.dg/gcov/ternary.C b/gcc/testsuite/g++.dg/gcov/ternary.C new file mode 100644 index 0000000..d055928 --- /dev/null +++ b/gcc/testsuite/g++.dg/gcov/ternary.C @@ -0,0 +1,12 @@ +// { dg-options "-fprofile-arcs -ftest-coverage" } +// { dg-do run { target native } } + +int b, c, d, e; + +int main() +{ + int a = b < 1 ? (c < 3 ? d : c) : e; /* count(1*) */ + return a; +} + +// { dg-final { run-gcov remove-gcda ternary.C } } diff --git a/gcc/testsuite/lib/gcov.exp b/gcc/testsuite/lib/gcov.exp index 632d506..18adc71 100644 --- a/gcc/testsuite/lib/gcov.exp +++ b/gcc/testsuite/lib/gcov.exp @@ -108,7 +108,7 @@ proc verify-intermediate { testname testcase file } { if [regexp "^function:(\[0-9\]+),(\[0-9\]+),.*" $line] { incr function } - if [regexp "^lcount:(\[0-9\]+),(\[0-9\]+)" $line] { + if [regexp "^lcount:(\[0-9\]+),(\[0-9\]+),(\[01\])" $line] { incr lcount } if [regexp "^branch:(\[0-9\]+),(taken|nottaken|notexec)" $line] { -- 2.7.4