GCOV: add support for lines with an unexecuted lines.
authorMartin Liska <mliska@suse.cz>
Tue, 31 Oct 2017 11:57:43 +0000 (12:57 +0100)
committerMartin Liska <marxin@gcc.gnu.org>
Tue, 31 Oct 2017 11:57:43 +0000 (11:57 +0000)
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

gcc/ChangeLog
gcc/doc/gcov.texi
gcc/gcov.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/gcov/gcov-threads-1.C
gcc/testsuite/g++.dg/gcov/ternary.C [new file with mode: 0644]
gcc/testsuite/lib/gcov.exp

index b1d984a..0b26806 100644 (file)
@@ -1,5 +1,14 @@
 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.
        * diagnostic-color.c: Factor out color related to macros to
        color-macros.h.
index 9abc603..e186ac6 100644 (file)
@@ -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
index e53bcf0..f9334f9 100644 (file)
@@ -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++);
index c371350..a1adb14 100644 (file)
@@ -1,3 +1,10 @@
+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>
 
        * gcc.target/i386/avx-1.c: Handle new intrinsics.
index cc9266a..cc912f9 100644 (file)
@@ -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 (file)
index 0000000..d055928
--- /dev/null
@@ -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 } }
index 632d506..18adc71 100644 (file)
@@ -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] {