public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: marxin <mliska@suse.cz>
To: gcc-patches@gcc.gnu.org
Subject: [PATCH 3/7] GCOV: add support for lines with an unexecuted lines.
Date: Thu, 26 Oct 2017 08:12:00 -0000	[thread overview]
Message-ID: <ecafaef9e04fb86737829b099bd2d63d3d8ae4cb.1509005504.git.mliska@suse.cz> (raw)
In-Reply-To: <cover.1509005504.git.mliska@suse.cz>

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  <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.

gcc/testsuite/ChangeLog:

2017-10-23  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.
---
 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


  parent reply	other threads:[~2017-10-26  8:12 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-26  8:12 [PATCH 0/7] GCOV: another set of improvements marxin
2017-10-26  8:12 ` [PATCH 4/7] GCOV: add -j argument (human readable format) marxin
2017-10-30 12:44   ` Nathan Sidwell
2017-10-31 11:54     ` Martin Liška
2017-10-31 12:10       ` Nathan Sidwell
2017-10-31 14:04         ` Martin Liška
2017-10-31 14:39           ` Nathan Sidwell
2017-10-31 15:33             ` Martin Liška
2017-10-26  8:12 ` [PATCH 1/7] GCOV: document behavior of -fkeep-{static,inline}-functions (PR gcov-profile/82633) marxin
2017-10-30 12:17   ` Nathan Sidwell
2017-10-31 11:12     ` Martin Liška
2017-10-26  8:12 ` [PATCH 5/7] GCOV: std::vector refactoring marxin
2017-10-30 14:17   ` Nathan Sidwell
2017-10-26  8:12 ` [PATCH 2/7] GCOV: introduce usage of terminal colors marxin
2017-10-30 12:20   ` Nathan Sidwell
2017-10-30 14:53     ` David Malcolm
2017-10-31 11:14       ` Martin Liška
2017-10-26  8:12 ` marxin [this message]
2017-10-30 12:27   ` [PATCH 3/7] GCOV: add support for lines with an unexecuted lines Nathan Sidwell
2017-10-31 11:29     ` Martin Liška
2017-11-02 15:33   ` Eric Botcazou
2017-10-26  8:12 ` [PATCH 7/7] GCOV: std::vector refactoring III marxin
2017-10-30 14:23   ` Nathan Sidwell
2017-10-26  8:19 ` [PATCH 6/7] GCOV: Vector refactoring II marxin
2017-10-30 14:19   ` Nathan Sidwell
2017-10-26  8:47 ` [PATCH 8/N][RFC] GCOV: support multiple functions per a line Martin Liška
2017-10-26 12:06   ` Nathan Sidwell
2017-11-01  8:00     ` [PATCH 8/N][RFC] v2 " Martin Liška
2017-11-07 10:53       ` [PATCH 8/N][RFC][v3]: " Martin Liška
2017-11-07 15:09         ` Nathan Sidwell
2017-11-08 11:42           ` Martin Liška
2017-11-08 15:12             ` Nathan Sidwell
2017-11-09  9:47               ` Martin Liška

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ecafaef9e04fb86737829b099bd2d63d3d8ae4cb.1509005504.git.mliska@suse.cz \
    --to=mliska@suse.cz \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).