public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Fix coverage inaccuracy with return in C/C++
@ 2014-11-10  8:53 Eric Botcazou
  0 siblings, 0 replies; only message in thread
From: Eric Botcazou @ 2014-11-10  8:53 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1428 bytes --]

We just remarked that there is a coverage inaccuracy in C/C++ for something as 
simple as:

void
foo (int i)
{
  if (i > 1)
    return;

  bar ();
}

The return line is always reported as covered, even at -O0.  That's because 
the return is used as the "representative return" for the entire function 
and then reused for the fallthru as-is.   The interesting thing is that this 
doesn't happen in Ada for an equivalent code, because the Ada compiler always 
adds a final return to functions:

void
foo (int i)
{
  if (i > 1)
    return;

  bar ();
  return;
}

In this case of 2 or more returns, the machinery in gimple-low.c properly 
clears the location on the representative return:

	  /* Remove the line number from the representative return statement.
	     It now fills in for many such returns.  Failure to remove this
	     will result in incorrect results for coverage analysis.  */
	  gimple_set_location (tmp_rs.stmt, UNKNOWN_LOCATION);

Hence the attached patch, which does the same when a representative return is 
reused for the fallthru.

Tested on x86_64-suse-linux, applied on the mainline as obvious.


2014-11-10  Eric Botcazou  <ebotcazou@adacore.com>

	* gimple-low.c (lower_function_body): Clear the location of the first
	inserted representative return if it also fills in for the fallthru.


2014-11-10  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.misc-tests/gcov-15.c: New test.


-- 
Eric Botcazou

[-- Attachment #2: p.diff --]
[-- Type: text/x-patch, Size: 1607 bytes --]

Index: gimple-low.c
===================================================================
--- gimple-low.c	(revision 217259)
+++ gimple-low.c	(working copy)
@@ -129,7 +129,8 @@ lower_function_body (void)
   /* If the function falls off the end, we need a null return statement.
      If we've already got one in the return_statements vector, we don't
      need to do anything special.  Otherwise build one by hand.  */
-  if (gimple_seq_may_fallthru (lowered_body)
+  bool may_fallthru = gimple_seq_may_fallthru (lowered_body);
+  if (may_fallthru
       && (data.return_statements.is_empty ()
 	  || (gimple_return_retval (data.return_statements.last().stmt)
 	      != NULL)))
@@ -138,6 +139,7 @@ lower_function_body (void)
       gimple_set_location (x, cfun->function_end_locus);
       gimple_set_block (x, DECL_INITIAL (current_function_decl));
       gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
+      may_fallthru = false;
     }
 
   /* If we lowered any return statements, emit the representative
@@ -148,6 +150,14 @@ lower_function_body (void)
       x = gimple_build_label (t.label);
       gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
       gsi_insert_after (&i, t.stmt, GSI_CONTINUE_LINKING);
+      if (may_fallthru)
+	{
+	  /* Remove the line number from the representative return statement.
+	     It now fills in for the fallthru too.  Failure to remove this
+	     will result in incorrect results for coverage analysis.  */
+	  gimple_set_location (t.stmt, UNKNOWN_LOCATION);
+	  may_fallthru = false;
+	}
     }
 
   /* Once the old body has been lowered, replace it with the new

[-- Attachment #3: gcov-15.c --]
[-- Type: text/x-csrc, Size: 313 bytes --]

/* { dg-options "-fprofile-arcs -ftest-coverage" } */
/* { dg-do run { target native } } */

void
bar (void)
{}

void
foo (int i)
{
  if (i > 1)  /* count(1) */
    return;   /* count(#####) */

  bar ();      /* count(1) */
}

int
main (void)
{
  foo (0);
  return 0;
}

/* { dg-final { run-gcov gcov-15.c } } */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-11-10  8:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-10  8:53 Fix coverage inaccuracy with return in C/C++ Eric Botcazou

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