It's possible to have a line of code that has a non-zero coverage.
However, it can contain unexecuted blocks and I hope adding a
notification can be usefull. LLVM also does that:
-: 0:Source:ternary.c
-: 0:Graph:ternary.gcno
-: 0:Data:ternary.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:int b, c, d, e;
-: 2:
1: 3:int main()
-: 4:{
1*: 5: int a = b < 1 ? (c < 3 ? d : c) : e;
1: 6: return a;
-: 7:}
It's also implemented for intermediate format, as well as color output
supports that.
gcc/ChangeLog:
2017-10-23 Martin Liska <[email protected]>
* 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.
gcc/testsuite/ChangeLog:
2017-10-23 Martin Liska <[email protected]>
* 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.
---
gcc/doc/gcov.texi | 13 +++++---
gcc/gcov.c | 50 ++++++++++++++----------------
gcc/testsuite/g++.dg/gcov/gcov-threads-1.C | 4 +--
gcc/testsuite/g++.dg/gcov/ternary.C | 12 +++++++
gcc/testsuite/lib/gcov.exp | 2 +-
5 files changed, 46 insertions(+), 35 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/gcov/ternary.C
diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi
index 2aa7166e35d..4029ccb0a93 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_statement}
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
@@ -341,6 +341,9 @@ used in a compilation unit. Such functions are marked with
@samp{-}
even though they contain a code. Use @option{-fkeep-inline-functions} and
@option{-fkeep-static-functions} in order to properly
record @var{execution_count} of such functions.
+Executed lines having a statement with zero @var{execution_count} end with
+@samp{*} character and are colored with magenta color with @option{-k}
+option.
Some lines of information at the start have @var{line_number} of zero.
These preamble lines are of the form
diff --git a/gcc/gcov.c b/gcc/gcov.c
index e53bcf0fd88..f9334f96eb3 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/g++.dg/gcov/gcov-threads-1.C
b/gcc/testsuite/g++.dg/gcov/gcov-threads-1.C
index cc9266ab8ea..cc912f9ddf4 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 00000000000..d055928c295
--- /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 632d50667a7..18adc71351a 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.14.2