Bug 550474 - GCov incorrectly interprets gcc version 9.1 data

- fix parseData to check for gcc 9.1 or greater in which case
  read in the column_end field for a function
- for 9.0 or greater, fix GCOV_TAG_OBJECT_SUMMARY logic in
  GcdaRecordsParser to only read in 2 fields
- also use number of program runs for an object to set the
  program number of runs which is no longer available via
  the GCOV_TAG_PROGRAM_SUMMARY


Change-Id: I38b0cd143e03c794e6f02b5b774e3d4c15ef1495
Reviewed-on: https://git.eclipse.org/r/148470
Tested-by: Jeff Johnston <jjohnstn@redhat.com>
Reviewed-by: Jeff Johnston <jjohnstn@redhat.com>
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcdaRecordsParser.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcdaRecordsParser.java
index 8524828..5b984e8 100644
--- a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcdaRecordsParser.java
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcdaRecordsParser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2018 STMicroelectronics and others.
+ * Copyright (c) 2009, 2019 STMicroelectronics and others.
  *
  * This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License 2.0
@@ -35,6 +35,9 @@
     private static final int GCOV_TAG_OBJECT_SYMMARY = 0xa1000000;
     private static final int GCOV_TAG_PROGRAM_SUMMARY = 0xa3000000;
 
+	private static final int GCC_VER_900 = 1094266922; // GCC 9.0.0 ('A90*')
+
+
     private final ArrayList<GcnoFunction> fnctns;
     private long objSmryNbrPgmRuns = 0;
     private long pgmSmryChksm = 0;
@@ -151,8 +154,7 @@
                         throw new CoreException(status);
                     }
 
-                    for (int i = 0; i < fnctnBlcks.size(); i++) {
-                        Block b = fnctnBlcks.get(i);
+                    for (Block b : fnctnBlcks) {
                         int nonFakeExit = 0;
 
                         ArrayList<Arc> arcsExit = b.getExitArcs();
@@ -198,12 +200,19 @@
                 }
 
                 case GCOV_TAG_OBJECT_SYMMARY: {
-                    objSmryChksm = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
-                    objSmryArcCnts = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
-                    objSmryNbrPgmRuns = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
-                    objSmrytotalCnts = stream.readLong();
-                    objSmryRunMax = stream.readLong();
-                    objSmrySumMax = stream.readLong();
+					if (version >= GCC_VER_900) {
+						objSmryNbrPgmRuns = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
+						objSmrySumMax = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
+						pgmSmryNbrPgmRuns = objSmryNbrPgmRuns > pgmSmryNbrPgmRuns ? objSmryNbrPgmRuns
+								: pgmSmryNbrPgmRuns;
+					} else {
+						objSmryChksm = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
+						objSmryArcCnts = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
+						objSmryNbrPgmRuns = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
+						objSmrytotalCnts = stream.readLong();
+						objSmryRunMax = stream.readLong();
+						objSmrySumMax = stream.readLong();
+					}
                     break;
                 }
 
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcnoFunction.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcnoFunction.java
index 58dae54..7ba4055 100644
--- a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcnoFunction.java
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcnoFunction.java
@@ -1,6 +1,6 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2018 STMicroelectronics and others.
- * 
+ * Copyright (c) 2009, 2019 STMicroelectronics and others.
+ *
  * This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License 2.0
  * which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -175,7 +175,7 @@
                     invarc = null;
 
                     for (Arc entrAr : vb.getEntryArcs()) {
-                        total -= entrAr.getCount();
+						total -= entrAr.getCount(); /* total can end up negative here ?? */
                         if (!entrAr.isCountValid()) {
                             invarc = entrAr;
                         }
@@ -183,7 +183,7 @@
 
                     blcksrc = invarc.getSrcBlock();
                     invarc.setCountValid(true);
-                    invarc.setCount(total);
+					invarc.setCount(total < 0 ? 0 : total); /* temporary kludge */
                     vb.decNumPreds();
                     blcksrc.decNumSuccs();
 
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcnoRecordsParser.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcnoRecordsParser.java
index 8a09115..ccd441f 100644
--- a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcnoRecordsParser.java
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/parser/GcnoRecordsParser.java
@@ -1,6 +1,6 @@
 /*******************************************************************************
  * Copyright (c) 2009, 2018 STMicroelectronics and others.
- * 
+ *
  * This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License 2.0
  * which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -38,6 +38,7 @@
     private static final int GCOV_TAG_LINES = 0x01450000;
 
     private static final int GCC_VER_810 = 1094201642; // GCC 8.1.0 ('A81*')
+	private static final int GCC_VER_910 = 1094267178; // GCC 9.1.0 ('A91*')
     private static final int GCC_VER_407 = 875575082; // GCC 4.0.7
 
     private GcnoFunction fnctn = null;
@@ -132,12 +133,19 @@
                     String fnctnSrcFle = GcovStringReader.readString(stream);
                     long fnctnFrstLnNmbr = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
                     if (version >= GCC_VER_810) {
-                        // long fnctnFrstColumnLnNmbr = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
+						// long fnctnFrstColumnNmbr = (stream.readInt() &
+						// MasksGenerator.UNSIGNED_INT_MASK);
                         stream.readInt();
                         // long fnctnLastLnNmbr = (stream.readInt() & MasksGenerator.UNSIGNED_INT_MASK);
                         stream.readInt();
                     }
 
+					if (version >= GCC_VER_910) {
+						// long fnctnLastColumnNmbr = (stream.readInt() &
+						// MasksGenerator.UNSIGNED_INT_MASK);
+						stream.readInt();
+					}
+
                     fnctn = new GcnoFunction(fnctnIdent, fnctnChksm, fnctnName, fnctnSrcFle, fnctnFrstLnNmbr);
                     SourceFile srcFle2 = findOrAdd(fnctn.getSrcFile());
                     if (fnctn.getFirstLineNmbr() >= srcFle2.getNumLines()) {