gcov: Fix wrong usage of NAN in statistics (PR gcov-profile/86536).
authorMartin Liska <mliska@suse.cz>
Thu, 26 Jul 2018 08:50:21 +0000 (10:50 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Thu, 26 Jul 2018 08:50:21 +0000 (08:50 +0000)
2018-07-26  Martin Liska  <mliska@suse.cz>

        PR gcov-profile/86536
* gcov.c (format_gcov): Use printf format %.*f directly
        and do not handle special values.
2018-07-26  Martin Liska  <mliska@suse.cz>

        PR gcov-profile/86536
* gcc.misc-tests/gcov-pr86536.c: New test.

From-SVN: r262991

gcc/ChangeLog
gcc/gcov.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.misc-tests/gcov-pr86536.c [new file with mode: 0644]

index 8118bf68915c89cecb14cb437432fec43fe6cbdb..7a66a6329f7bed8c965d08b55610114c50e04440 100644 (file)
@@ -1,3 +1,9 @@
+2018-07-26  Martin Liska  <mliska@suse.cz>
+
+        PR gcov-profile/86536
+       * gcov.c (format_gcov): Use printf format %.*f directly
+        and do not handle special values.
+
 2018-07-25  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * common/config/arc/arc-common.c (arc_option_optimization_table):
index ad2de4d5b22206a439d1a1671e776e7fe36b15e5..78a3e0e19e9a771bbe0d9c4a3ca6328a8837e4a4 100644 (file)
@@ -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);
index 722efecfb91150529ac680ec35effdf0c9a58b86..7642560f276d3fc274ab36411bd43d49c99d8220 100644 (file)
@@ -1,3 +1,8 @@
+2018-07-26  Martin Liska  <mliska@suse.cz>
+
+        PR gcov-profile/86536
+       * gcc.misc-tests/gcov-pr86536.c: New test.
+
 2018-07-25  Martin Sebor  <msebor@redhat.com>
 
        * 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 (file)
index 0000000..4817773
--- /dev/null
@@ -0,0 +1,25 @@
+// PR gcov-profile/86536
+// { dg-options "-fprofile-arcs -ftest-coverage" }
+// { dg-do run { target native } }
+// { dg-require-fork "" }
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+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 } } }