From 977667e6b74a56db3747caaed8ba776f6cae8cdf Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Thu, 26 Jul 2018 10:50:21 +0200 Subject: [PATCH] gcov: Fix wrong usage of NAN in statistics (PR gcov-profile/86536). 2018-07-26 Martin Liska PR gcov-profile/86536 * gcov.c (format_gcov): Use printf format %.*f directly and do not handle special values. 2018-07-26 Martin Liska PR gcov-profile/86536 * gcc.misc-tests/gcov-pr86536.c: New test. From-SVN: r262991 --- gcc/ChangeLog | 6 +++ gcc/gcov.c | 46 +++++---------------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.misc-tests/gcov-pr86536.c | 25 +++++++++++ 4 files changed, 46 insertions(+), 36 deletions(-) create mode 100644 gcc/testsuite/gcc.misc-tests/gcov-pr86536.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8118bf68915..7a66a6329f7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-07-26 Martin Liska + + PR gcov-profile/86536 + * gcov.c (format_gcov): Use printf format %.*f directly + and do not handle special values. + 2018-07-25 Claudiu Zissulescu * common/config/arc/arc-common.c (arc_option_optimization_table): diff --git a/gcc/gcov.c b/gcc/gcov.c index ad2de4d5b22..78a3e0e19e9 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -2203,50 +2203,24 @@ format_count (gcov_type count) } /* Format a GCOV_TYPE integer as either a percent ratio, or absolute - count. If dp >= 0, format TOP/BOTTOM * 100 to DP decimal places. - If DP is zero, no decimal point is printed. Only print 100% when - TOP==BOTTOM and only print 0% when TOP=0. If dp < 0, then simply + count. If DECIMAL_PLACES >= 0, format TOP/BOTTOM * 100 to DECIMAL_PLACES. + If DECIMAL_PLACES is zero, no decimal point is printed. Only print 100% when + TOP==BOTTOM and only print 0% when TOP=0. If DECIMAL_PLACES < 0, then simply format TOP. Return pointer to a static string. */ static char const * -format_gcov (gcov_type top, gcov_type bottom, int dp) +format_gcov (gcov_type top, gcov_type bottom, int decimal_places) { static char buffer[20]; - /* Handle invalid values that would result in a misleading value. */ - if (bottom != 0 && top > bottom && dp >= 0) + if (decimal_places >= 0) { - sprintf (buffer, "NAN %%"); - return buffer; - } + float ratio = bottom ? 100.0f * top / bottom: 0; - if (dp >= 0) - { - float ratio = bottom ? (float)top / bottom : 0; - int ix; - unsigned limit = 100; - unsigned percent; - - for (ix = dp; ix--; ) - limit *= 10; - - percent = (unsigned) (ratio * limit + (float)0.5); - if (percent <= 0 && top) - percent = 1; - else if (percent >= limit && top != bottom) - percent = limit - 1; - ix = sprintf (buffer, "%.*u%%", dp + 1, percent); - if (dp) - { - dp++; - do - { - buffer[ix+1] = buffer[ix]; - ix--; - } - while (dp--); - buffer[ix + 1] = '.'; - } + /* Round up to 1% if there's a small non-zero value. */ + if (ratio > 0.0f && ratio < 0.5f && decimal_places == 0) + ratio = 1.0f; + sprintf (buffer, "%.*f%%", decimal_places, ratio); } else return format_count (top); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 722efecfb91..7642560f276 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-07-26 Martin Liska + + PR gcov-profile/86536 + * gcc.misc-tests/gcov-pr86536.c: New test. + 2018-07-25 Martin Sebor * gcc.c-torture/execute/builtins/strnlen.c: Remove DejaGnu directives diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr86536.c b/gcc/testsuite/gcc.misc-tests/gcov-pr86536.c new file mode 100644 index 00000000000..48177735999 --- /dev/null +++ b/gcc/testsuite/gcc.misc-tests/gcov-pr86536.c @@ -0,0 +1,25 @@ +// PR gcov-profile/86536 +// { dg-options "-fprofile-arcs -ftest-coverage" } +// { dg-do run { target native } } +// { dg-require-fork "" } + +#include +#include +#include +#include + +int +main (void) +{ + + int j = 22; /* count(1) */ + + /* returns(200) */ + fork (); /* count(1) */ + /* returns(end) */ + + int i = 7; /* count(2) */ + return 0; /* count(2) */ +} + +// { dg-final { run-gcov branches calls { -b gcov-pr86536.c } } } -- 2.30.2