Commit cdb07de7 by Martin Liska Committed by Martin Liska

GCOV: add support for lines with an unexecuted lines.

2017-10-31  Martin Liska  <mliska@suse.cz>

	* 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  <mliska@suse.cz>

	* 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
parent 28f4a4a8
2017-10-31 Martin Liska <mliska@suse.cz> 2017-10-31 Martin Liska <mliska@suse.cz>
* 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 <mliska@suse.cz>
* color-macros.h: New file. * color-macros.h: New file.
* diagnostic-color.c: Factor out color related to macros to * diagnostic-color.c: Factor out color related to macros to
color-macros.h. color-macros.h.
...@@ -189,7 +189,7 @@ one entry per line ...@@ -189,7 +189,7 @@ one entry per line
@smallexample @smallexample
file:@var{source_file_name} file:@var{source_file_name}
function:@var{line_number},@var{execution_count},@var{function_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} branch:@var{line_number},@var{branch_coverage_type}
Where the @var{branch_coverage_type} is 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 ...@@ -208,11 +208,11 @@ Here is a sample when @option{-i} is used in conjunction with @option{-b} option
file:array.cc file:array.cc
function:11,1,_Z3sumRKSt6vectorIPiSaIS0_EE function:11,1,_Z3sumRKSt6vectorIPiSaIS0_EE
function:22,1,main function:22,1,main
lcount:11,1 lcount:11,1,0
lcount:12,1 lcount:12,1,0
lcount:14,1 lcount:14,1,0
branch:14,taken branch:14,taken
lcount:26,1 lcount:26,1,0
branch:28,nottaken branch:28,nottaken
@end smallexample @end smallexample
...@@ -336,6 +336,9 @@ non-exceptional paths or only exceptional paths such as C++ exception ...@@ -336,6 +336,9 @@ non-exceptional paths or only exceptional paths such as C++ exception
handlers, respectively. Given @samp{-a} option, unexecuted blocks are handlers, respectively. Given @samp{-a} option, unexecuted blocks are
marked @samp{$$$$$} or @samp{%%%%%}, depending on whether a basic block marked @samp{$$$$$} or @samp{%%%%%}, depending on whether a basic block
is reachable via non-exceptional or exceptional paths. 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 Note that GCC can completely remove the bodies of functions that are
not needed -- for instance if they are inlined everywhere. Such functions not needed -- for instance if they are inlined everywhere. Such functions
......
...@@ -256,6 +256,7 @@ typedef struct line_info ...@@ -256,6 +256,7 @@ typedef struct line_info
Used in all-blocks mode. */ Used in all-blocks mode. */
unsigned exists : 1; unsigned exists : 1;
unsigned unexceptional : 1; unsigned unexceptional : 1;
unsigned has_unexecuted_block : 1;
} line_t; } line_t;
bool bool
...@@ -850,28 +851,7 @@ process_args (int argc, char **argv) ...@@ -850,28 +851,7 @@ process_args (int argc, char **argv)
/* Output the result in intermediate format used by 'lcov'. /* Output the result in intermediate format used by 'lcov'.
The intermediate format contains a single file named 'foo.cc.gcov', The intermediate format contains a single file named 'foo.cc.gcov',
with no source code included. A sample output is with no source code included.
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
...
The default gcov outputs multiple files: 'foo.cc.gcov', The default gcov outputs multiple files: 'foo.cc.gcov',
'iostream.gcov', 'ios_base.h.gcov', etc. with source code 'iostream.gcov', 'ios_base.h.gcov', etc. with source code
...@@ -901,8 +881,8 @@ output_intermediate_file (FILE *gcov_file, source_t *src) ...@@ -901,8 +881,8 @@ output_intermediate_file (FILE *gcov_file, source_t *src)
{ {
arc_t *arc; arc_t *arc;
if (line->exists) if (line->exists)
fprintf (gcov_file, "lcount:%u,%s\n", line_num, fprintf (gcov_file, "lcount:%u,%s,%d\n", line_num,
format_gcov (line->count, 0, -1)); format_gcov (line->count, 0, -1), line->has_unexecuted_block);
if (flag_branches) if (flag_branches)
for (arc = line->branches; arc; arc = arc->line_next) for (arc = line->branches; arc; arc = arc->line_next)
{ {
...@@ -2289,7 +2269,11 @@ add_line_counts (coverage_t *coverage, function_t *fn) ...@@ -2289,7 +2269,11 @@ add_line_counts (coverage_t *coverage, function_t *fn)
} }
line->exists = 1; line->exists = 1;
if (!block->exceptional) if (!block->exceptional)
line->unexceptional = 1; {
line->unexceptional = 1;
if (block->count == 0)
line->has_unexecuted_block = 1;
}
line->count += block->count; line->count += block->count;
} }
} }
...@@ -2496,6 +2480,7 @@ pad_count_string (string &s) ...@@ -2496,6 +2480,7 @@ pad_count_string (string &s)
static void static void
output_line_beginning (FILE *f, bool exists, bool unexceptional, output_line_beginning (FILE *f, bool exists, bool unexceptional,
bool has_unexecuted_block,
gcov_type count, unsigned line_num, gcov_type count, unsigned line_num,
const char *exceptional_string, const char *exceptional_string,
const char *unexceptional_string) const char *unexceptional_string)
...@@ -2506,6 +2491,17 @@ output_line_beginning (FILE *f, bool exists, bool unexceptional, ...@@ -2506,6 +2491,17 @@ output_line_beginning (FILE *f, bool exists, bool unexceptional,
if (count > 0) if (count > 0)
{ {
s = format_gcov (count, 0, -1); 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); pad_count_string (s);
} }
else else
...@@ -2610,7 +2606,7 @@ output_lines (FILE *gcov_file, const source_t *src) ...@@ -2610,7 +2606,7 @@ output_lines (FILE *gcov_file, const source_t *src)
There are 16 spaces of indentation added before the source There are 16 spaces of indentation added before the source
line so that tabs won't be messed up. */ line so that tabs won't be messed up. */
output_line_beginning (gcov_file, line->exists, line->unexceptional, 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*/"); fprintf (gcov_file, ":%s\n", retval ? retval : "/*EOF*/");
...@@ -2626,7 +2622,7 @@ output_lines (FILE *gcov_file, const source_t *src) ...@@ -2626,7 +2622,7 @@ output_lines (FILE *gcov_file, const source_t *src)
if (!block->is_call_return) if (!block->is_call_return)
{ {
output_line_beginning (gcov_file, line->exists, output_line_beginning (gcov_file, line->exists,
block->exceptional, block->exceptional, false,
block->count, line_num, block->count, line_num,
"%%%%%", "$$$$$"); "%%%%%", "$$$$$");
fprintf (gcov_file, "-block %2d", ix++); fprintf (gcov_file, "-block %2d", ix++);
......
2017-10-31 Martin Liska <mliska@suse.cz>
* 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 <julia.koval@intel.com> 2017-11-01 Julia Koval <julia.koval@intel.com>
* gcc.target/i386/avx-1.c: Handle new intrinsics. * gcc.target/i386/avx-1.c: Handle new intrinsics.
......
...@@ -31,14 +31,14 @@ int main(int argc, char **argv) { ...@@ -31,14 +31,14 @@ int main(int argc, char **argv) {
{ {
ids[i] = i; ids[i] = i;
int r = pthread_create (&t[i], NULL, ContentionNoDeadlock_thread, &ids[i]); int r = pthread_create (&t[i], NULL, ContentionNoDeadlock_thread, &ids[i]);
assert (r == 0); /* count(5) */ assert (r == 0); /* count(5*) */
} }
int ret; int ret;
for (int i = 0; i < NR; i++) for (int i = 0; i < NR; i++)
{ {
int r = pthread_join (t[i], (void**)&ret); int r = pthread_join (t[i], (void**)&ret);
assert (r == 0); /* count(5) */ assert (r == 0); /* count(5*) */
} }
return 0; /* count(1) */ return 0; /* count(1) */
......
// { 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 } }
...@@ -108,7 +108,7 @@ proc verify-intermediate { testname testcase file } { ...@@ -108,7 +108,7 @@ proc verify-intermediate { testname testcase file } {
if [regexp "^function:(\[0-9\]+),(\[0-9\]+),.*" $line] { if [regexp "^function:(\[0-9\]+),(\[0-9\]+),.*" $line] {
incr function incr function
} }
if [regexp "^lcount:(\[0-9\]+),(\[0-9\]+)" $line] { if [regexp "^lcount:(\[0-9\]+),(\[0-9\]+),(\[01\])" $line] {
incr lcount incr lcount
} }
if [regexp "^branch:(\[0-9\]+),(taken|nottaken|notexec)" $line] { if [regexp "^branch:(\[0-9\]+),(taken|nottaken|notexec)" $line] {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment