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