From 575f845cbfc15b250f3debf2e2c99f95584e7afa Mon Sep 17 00:00:00 2001 From: Xionghu Luo Date: Tue, 28 Feb 2023 17:46:18 +0800 Subject: [PATCH v2] gcov: Fix "do-while" structure in case statement leads to incorrect code coverage [PR93680] Start a new basic block if two labels have different location when test-coverage. Regression tested pass on x86_64-linux-gnu and aarch64-linux-gnu, OK for master? gcc/ChangeLog: PR gcov/93680 * tree-cfg.cc (build_gimple_cfg): Don't delete labels if !optimize. (stmt_starts_bb_p): Check whether two labels are on same line. gcc/testsuite/ChangeLog: PR gcov/93680 * g++.dg/gcov/gcov-1.C: Correct counts. * gcc.misc-tests/gcov-4.c: Likewise. * gcc.misc-tests/gcov-pr85332.c: Likewise. * lib/gcov.exp: Also clean gcda if fail. * gcc.misc-tests/gcov-pr93680.c: New test. Signed-off-by: Xionghu Luo --- gcc/testsuite/g++.dg/gcov/gcov-1.C | 2 +- gcc/testsuite/gcc.misc-tests/gcov-4.c | 2 +- gcc/testsuite/gcc.misc-tests/gcov-pr85332.c | 2 +- gcc/testsuite/gcc.misc-tests/gcov-pr93680.c | 24 +++++++++++++++++++++ gcc/testsuite/lib/gcov.exp | 4 +--- gcc/tree-cfg.cc | 10 ++++++++- 6 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.misc-tests/gcov-pr93680.c diff --git a/gcc/testsuite/g++.dg/gcov/gcov-1.C b/gcc/testsuite/g++.dg/gcov/gcov-1.C index ee383b480a8..01e7084fb03 100644 --- a/gcc/testsuite/g++.dg/gcov/gcov-1.C +++ b/gcc/testsuite/g++.dg/gcov/gcov-1.C @@ -263,7 +263,7 @@ test_switch (int i, int j) case 2: result = do_something (1024); break; - case 3: /* count(3) */ + case 3: /* count(2) */ case 4: /* branch(67) */ if (j == 2) /* count(3) */ diff --git a/gcc/testsuite/gcc.misc-tests/gcov-4.c b/gcc/testsuite/gcc.misc-tests/gcov-4.c index da7929ef7fc..792cda8cfce 100644 --- a/gcc/testsuite/gcc.misc-tests/gcov-4.c +++ b/gcc/testsuite/gcc.misc-tests/gcov-4.c @@ -122,7 +122,7 @@ top: } else { -else_: /* count(1) */ +else_: /* count(2) */ j = do_something (j); /* count(2) */ if (j) /* count(2) */ { diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr85332.c b/gcc/testsuite/gcc.misc-tests/gcov-pr85332.c index 73e50b19fc7..b37e760910c 100644 --- a/gcc/testsuite/gcc.misc-tests/gcov-pr85332.c +++ b/gcc/testsuite/gcc.misc-tests/gcov-pr85332.c @@ -7,7 +7,7 @@ int doit(int sel, int n, void *p) switch (sel) { - case 0: /* count(3) */ + case 0: /* count(1) */ do {*p0 += *p0;} while (--n); /* count(3) */ return *p0 == 0; /* count(1) */ diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr93680.c b/gcc/testsuite/gcc.misc-tests/gcov-pr93680.c new file mode 100644 index 00000000000..2fe340c4011 --- /dev/null +++ b/gcc/testsuite/gcc.misc-tests/gcov-pr93680.c @@ -0,0 +1,24 @@ +/* { dg-options "-fprofile-arcs -ftest-coverage" } */ +/* { dg-do run { target native } } */ + +int f(int s, int n) +{ + int p = 0; + + switch (s) + { + case 0: /* count(1) */ + do { p++; } while (--n); /* count(5) */ + return p; /* count(1) */ + + case 1: /* count(1) */ + do { p++; } while (--n); /* count(5) */ + return p; /* count(1) */ + } + + return 0; +} + +int main() { f(0, 5); f(1, 5); return 0; } + +/* { dg-final { run-gcov gcov-pr93680.c } } */ diff --git a/gcc/testsuite/lib/gcov.exp b/gcc/testsuite/lib/gcov.exp index 80e74aeb220..07e1978d25d 100644 --- a/gcc/testsuite/lib/gcov.exp +++ b/gcc/testsuite/lib/gcov.exp @@ -424,9 +424,7 @@ proc run-gcov { args } { } if { $tfailed > 0 } { fail "$testname gcov: $lfailed failures in line counts, $bfailed in branch percentages, $cfailed in return percentages, $ifailed in intermediate format" - if { $xfailed } { - clean-gcov $testcase - } + clean-gcov $testcase } else { pass "$testname gcov" clean-gcov $testcase diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index a9fcc7fd050..41a269b5fe2 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -238,7 +238,8 @@ build_gimple_cfg (gimple_seq seq) n_basic_blocks_for_fn (cfun)); /* To speed up statement iterator walks, we first purge dead labels. */ - cleanup_dead_labels (); + if (optimize) + cleanup_dead_labels (); /* Group case nodes to reduce the number of edges. We do this after cleaning up dead labels because otherwise we miss @@ -2860,6 +2861,13 @@ stmt_starts_bb_p (gimple *stmt, gimple *prev_stmt) || !DECL_ARTIFICIAL (gimple_label_label (plabel))) return true; + location_t loc_prev = gimple_location (plabel); + location_t locus = gimple_location (label_stmt); + expanded_location locus_e = expand_location (locus); + + if (!optimize && !same_line_p (locus, &locus_e, loc_prev)) + return true; + cfg_stats.num_merged_labels++; return false; } -- 2.27.0