/* Gcov.c: prepend line execution counts and branch probabilities to a
   source file.
   Copyright (C) 1990-2025 Free Software Foundation, Inc.
   Contributed by James E. Wilson of Cygnus Support.
   Mangled by Bob Manson of Cygnus Support.
   Mangled further by Nathan Sidwell <nathan@codesourcery.com>

Gcov is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

Gcov is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Gcov; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* ??? Print a list of the ten blocks with the highest execution counts,
   and list the line numbers corresponding to those blocks.  Also, perhaps
   list the line numbers with the highest execution counts, only printing
   the first if there are several which are all listed in the same block.  */

/* ??? Should have an option to print the number of basic blocks, and the
   percent of them that are covered.  */

/* Need an option to show individual block counts, and show
   probabilities of fall through arcs.  */

#include "config.h"
#define INCLUDE_ALGORITHM
#define INCLUDE_VECTOR
#define INCLUDE_STRING
#define INCLUDE_MAP
#define INCLUDE_SET
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "intl.h"
#include "diagnostic.h"
#include "version.h"
#include "demangle.h"
#include "color-macros.h"
#include "pretty-print.h"
#include "json.h"
#include "hwint.h"
#include "xregex.h"
#include "graphds.h"

#include <zlib.h>
#include <getopt.h>

#include "md5.h"

using namespace std;

#define IN_GCOV 1
#include "gcov-io.h"
#include "gcov-io.cc"

#define GCOV_JSON_FORMAT_VERSION "2"

/* The gcno file is generated by -ftest-coverage option. The gcda file is
   generated by a program compiled with -fprofile-arcs. Their formats
   are documented in gcov-io.h.  */

/* The functions in this file for creating and solution program flow graphs
   are very similar to functions in the gcc source file profile.cc.  In
   some places we make use of the knowledge of how profile.cc works to
   select particular algorithms here.  */

/* The code validates that the profile information read in corresponds
   to the code currently being compiled.  Rather than checking for
   identical files, the code below compares a checksum on the CFG
   (based on the order of basic blocks and the arcs in the CFG).  If
   the CFG checksum in the gcda file match the CFG checksum in the
   gcno file, the profile data will be used.  */

/* This is the size of the buffer used to read in source file lines.  */

class function_info;
class block_info;
class source_info;
class condition_info;
class path_info;

/* Describes an arc between two basic blocks.  */

struct arc_info
{
  /* source and destination blocks.  */
  class block_info *src;
  class block_info *dst;

  /* transition counts.  */
  gcov_type count;
  /* used in cycle search, so that we do not clobber original counts.  */
  gcov_type cs_count;

  unsigned int count_valid : 1;
  unsigned int on_tree : 1;
  unsigned int fake : 1;
  unsigned int fall_through : 1;

  /* Arc to a catch handler.  */
  unsigned int is_throw : 1;

  /* Arc is for a function that abnormally returns.  */
  unsigned int is_call_non_return : 1;

  /* Arc is for catch/setjmp.  */
  unsigned int is_nonlocal_return : 1;

  /* Is an unconditional branch.  */
  unsigned int is_unconditional : 1;

  /* Loop making arc.  */
  unsigned int cycle : 1;

  /* Is a true arc.  */
  unsigned int true_value : 1;

  /* Is a false arc.  */
  unsigned int false_value : 1;

  /* Links to next arc on src and dst lists.  */
  struct arc_info *succ_next;
  struct arc_info *pred_next;
};

/* Describes (prime) path coverage.  */
class path_info
{
public:
  path_info () : paths (), covered () {}

  /* The prime paths of a function.  The paths will be
     lexicographically ordered and identified by their index.  */
  vector<vector<unsigned>> paths;

  /* The covered paths.  This is really a large bitset partitioned
     into buckets of gcov_type_unsigned, and bit n is set if the nth
     path is covered.  */
  vector<gcov_type_unsigned> covered;

  /* The size (in bits) of each bucket.  */
  static const size_t
  bucketsize = sizeof (gcov_type_unsigned) * BITS_PER_UNIT;

  /* Count the covered paths.  */
  unsigned covered_paths () const
  {
    unsigned cnt = 0;
    for (gcov_type_unsigned v : covered)
      cnt += popcount_hwi (v);
    return cnt;
  }

  /* Check if the nth path is covered.  */
  bool covered_p (size_t n) const
  {
    if (covered.empty ())
      return false;
    const size_t bucket = n / bucketsize;
    const uint64_t bit = n % bucketsize;
    return covered[bucket] & (gcov_type_unsigned (1) << bit);
  }
};

/* Describes which locations (lines and files) are associated with
   a basic block.  */

class block_location_info
{
public:
  block_location_info (unsigned _source_file_idx):
    source_file_idx (_source_file_idx)
  {}

  unsigned source_file_idx;
  vector<unsigned> lines;
};

/* Describes a single conditional expression and the (recorded) conditions
   shown to independently affect the outcome.  */
class condition_info
{
public:
  condition_info ();

  int popcount () const;

  /* Bitsets storing the independently significant outcomes for true and false,
     respectively.  */
  gcov_type_unsigned truev;
  gcov_type_unsigned falsev;

  /* Number of terms in the expression; if (x) -> 1, if (x && y) -> 2 etc.  */
  unsigned n_terms;
};

condition_info::condition_info (): truev (0), falsev (0), n_terms (0)
{
}

int condition_info::popcount () const
{
    return popcount_hwi (truev) + popcount_hwi (falsev);
}

/* Describes a basic block. Contains lists of arcs to successor and
   predecessor blocks.  */

class block_info
{
public:
  /* Constructor.  */
  block_info ();

  /* Chain of exit and entry arcs.  */
  arc_info *succ;
  arc_info *pred;

  /* Number of unprocessed exit and entry arcs.  */
  gcov_type num_succ;
  gcov_type num_pred;

  unsigned id;

  /* Block execution count.  */
  gcov_type count;
  unsigned count_valid : 1;
  unsigned valid_chain : 1;
  unsigned invalid_chain : 1;
  unsigned exceptional : 1;

  /* Block is a call instrumenting site.  */
  unsigned is_call_site : 1; /* Does the call.  */
  unsigned is_call_return : 1; /* Is the return.  */

  /* Block is a landing pad for longjmp or throw.  */
  unsigned is_nonlocal_return : 1;

  condition_info conditions;

  vector<block_location_info> locations;

  struct
  {
    /* Single line graph cycle workspace.  Used for all-blocks
       mode.  */
    arc_info *arc;
    unsigned ident;
  } cycle; /* Used in all-blocks mode, after blocks are linked onto
	     lines.  */

  /* Temporary chain for solving graph, and for chaining blocks on one
     line.  */
  class block_info *chain;

};

block_info::block_info (): succ (NULL), pred (NULL), num_succ (0), num_pred (0),
  id (0), count (0), count_valid (0), valid_chain (0), invalid_chain (0),
  exceptional (0), is_call_site (0), is_call_return (0), is_nonlocal_return (0),
  locations (), chain (NULL)
{
  cycle.arc = NULL;
}

/* Describes a single line of source.  Contains a chain of basic blocks
   with code on it.  */

class line_info
{
public:
  /* Default constructor.  */
  line_info ();

  /* Return true when NEEDLE is one of basic blocks the line belongs to.  */
  bool has_block (block_info *needle);

  /* Execution count.  */
  gcov_type count;

  /* Branches from blocks that end on this line.  */
  vector<arc_info *> branches;

  /* blocks which start on this line.  Used in all-blocks mode.  */
  vector<block_info *> blocks;

  unsigned exists : 1;
  unsigned unexceptional : 1;
  unsigned has_unexecuted_block : 1;
};

line_info::line_info (): count (0), branches (), blocks (), exists (false),
  unexceptional (0), has_unexecuted_block (0)
{
}

bool
line_info::has_block (block_info *needle)
{
  return std::find (blocks.begin (), blocks.end (), needle) != blocks.end ();
}

/* Output demangled function names.  */

static int flag_demangled_names = 0;

/* Describes a single function. Contains an array of basic blocks.  */

class function_info
{
public:
  function_info ();
  ~function_info ();

  /* Return true when line N belongs to the function in source file SRC_IDX.
     The line must be defined in body of the function, can't be inlined.  */
  bool group_line_p (unsigned n, unsigned src_idx);

  /* Function filter based on function_info::artificial variable.  */

  static inline bool
  is_artificial (function_info *fn)
  {
    return fn->artificial;
  }

  /* Name of function.  */
  char *m_name;
  char *m_demangled_name;
  unsigned ident;
  unsigned lineno_checksum;
  unsigned cfg_checksum;

  /* The graph contains at least one fake incoming edge.  */
  unsigned has_catch : 1;

  /* True when the function is artificial and does not exist
     in a source file.  */
  unsigned artificial : 1;

  /* True when multiple functions start at a line in a source file.  */
  unsigned is_group : 1;

  /* Array of basic blocks.  Like in GCC, the entry block is
     at blocks[0] and the exit block is at blocks[1].  */
#define ENTRY_BLOCK (0)
#define EXIT_BLOCK (1)
  vector<block_info> blocks;
  unsigned blocks_executed;

  vector<condition_info*> conditions;

  /* Path coverage information.  */
  path_info paths;

  /* Raw arc coverage counts.  */
  vector<gcov_type> counts;

  /* First line number.  */
  unsigned start_line;

  /* First line column.  */
  unsigned start_column;

  /* Last line number.  */
  unsigned end_line;

  /* Last line column.  */
  unsigned end_column;

  /* Index of source file where the function is defined.  */
  unsigned src;

  /* Vector of line information (used only for group functions).  */
  vector<line_info> lines;

  /* Next function.  */
  class function_info *next;

  /*  Get demangled name of a function.  The demangled name
      is converted when it is used for the first time.  */
  char *get_demangled_name ()
  {
    if (m_demangled_name == NULL)
      {
	m_demangled_name = cplus_demangle (m_name, DMGL_PARAMS);
	if (!m_demangled_name)
	  m_demangled_name = m_name;
      }

    return m_demangled_name;
  }

  /* Get name of the function based on flag_demangled_names.  */
  char *get_name ()
  {
    return flag_demangled_names ? get_demangled_name () : m_name;
  }

  /* Return number of basic blocks (without entry and exit block).  */
  unsigned get_block_count ()
  {
    return blocks.size () - 2;
  }
};

/* Function info comparer that will sort functions according to starting
   line.  */

struct function_line_start_cmp
{
  inline bool operator() (const function_info *lhs,
			  const function_info *rhs)
    {
      return (lhs->start_line == rhs->start_line
	      ? lhs->start_column < rhs->start_column
	      : lhs->start_line < rhs->start_line);
    }
};

/* Describes coverage of a file or function.  */

struct coverage_info
{
  int lines;
  int lines_executed;

  int branches;
  int branches_executed;
  int branches_taken;

  int conditions;
  int conditions_covered;

  int calls;
  int calls_executed;

  char *name;

  unsigned paths;
  unsigned paths_covered;
};

/* Describes a file mentioned in the block graph.  Contains an array
   of line info.  */

class source_info
{
public:
  /* Default constructor.  */
  source_info ();

  vector<function_info *> *get_functions_at_location (unsigned line_num) const;

  /* Register a new function.  */
  void add_function (function_info *fn);

  /* Debug the source file.  */
  void debug ();

  /* Index of the source_info in sources vector.  */
  unsigned index;

  /* Canonical name of source file.  */
  char *name;
  time_t file_time;

  /* Vector of line information.  */
  vector<line_info> lines;

  coverage_info coverage;

  /* Maximum line count in the source file.  */
  unsigned int maximum_count;

  /* Functions in this source file.  These are in ascending line
     number order.  */
  vector<function_info *> functions;

  /* Line number to functions map.  */
  vector<vector<function_info *> *> line_to_function_map;
};

source_info::source_info (): index (0), name (NULL), file_time (),
  lines (), coverage (), maximum_count (0), functions ()
{
}

/* Register a new function.  */
void
source_info::add_function (function_info *fn)
{
  functions.push_back (fn);

  if (fn->start_line >= line_to_function_map.size ())
    line_to_function_map.resize (fn->start_line + 1);

  vector<function_info *> **slot = &line_to_function_map[fn->start_line];
  if (*slot == NULL)
    *slot = new vector<function_info *> ();

  (*slot)->push_back (fn);
}

vector<function_info *> *
source_info::get_functions_at_location (unsigned line_num) const
{
  if (line_num >= line_to_function_map.size ())
    return NULL;

  vector<function_info *> *slot = line_to_function_map[line_num];
  if (slot != NULL)
    std::sort (slot->begin (), slot->end (), function_line_start_cmp ());

  return slot;
}

void source_info::debug ()
{
  fprintf (stderr, "source_info: %s\n", name);
  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    {
      function_info *fn = *it;
      fprintf (stderr, "  function_info: %s\n", fn->get_name ());
      for (vector<block_info>::iterator bit = fn->blocks.begin ();
	   bit != fn->blocks.end (); bit++)
	{
	  fprintf (stderr, "    block_info id=%d, count=%" PRId64 " \n",
		   bit->id, bit->count);
	}
    }

  for (unsigned lineno = 1; lineno < lines.size (); ++lineno)
    {
      line_info &line = lines[lineno];
      fprintf (stderr, "  line_info=%d, count=%" PRId64 "\n", lineno, line.count);
    }

  fprintf (stderr, "\n");
}

class name_map
{
public:
  name_map ()
  {
  }

  name_map (char *_name, unsigned _src): name (_name), src (_src)
  {
  }

  bool operator== (const name_map &rhs) const
  {
#if HAVE_DOS_BASED_FILE_SYSTEM
    return strcasecmp (this->name, rhs.name) == 0;
#else
    return strcmp (this->name, rhs.name) == 0;
#endif
  }

  bool operator< (const name_map &rhs) const
  {
#if HAVE_DOS_BASED_FILE_SYSTEM
    return strcasecmp (this->name, rhs.name) < 0;
#else
    return strcmp (this->name, rhs.name) < 0;
#endif
  }

  const char *name;  /* Source file name */
  unsigned src;  /* Source file */
};

/* Vector of all functions.  */
static vector<function_info *> functions;

/* Function ident to function_info * map.  */
static map<unsigned, function_info *> ident_to_fn;

/* Vector of source files.  */
static vector<source_info> sources;

/* Mapping of file names to sources */
static vector<name_map> names;

/* Record all processed files in order to warn about
   a file being read multiple times.  */
static vector<char *> processed_files;

/* The contents of a source file.  The nth SOURCE_LINES entry is the
   contents of the nth SOURCES, or empty if it has not or could not be
   read.  */
static vector<vector<const char *>*> source_lines;

/* This holds data summary information.  */

static unsigned object_runs;

static unsigned total_lines;
static unsigned total_executed;

/* Modification time of graph file.  */

static time_t bbg_file_time;

/* Name of the notes (gcno) output file.  The "bbg" prefix is for
   historical reasons, when the notes file contained only the
   basic block graph notes.  */

static char *bbg_file_name;

/* Stamp of the bbg file */
static unsigned bbg_stamp;

/* Supports has_unexecuted_blocks functionality.  */
static unsigned bbg_supports_has_unexecuted_blocks;

/* Working directory in which a TU was compiled.  */
static const char *bbg_cwd;

/* Name and file pointer of the input file for the count data (gcda).  */

static char *da_file_name;

/* Data file is missing.  */

static int no_data_file;

/* If there is several input files, compute and display results after
   reading all data files.  This way if two or more gcda file refer to
   the same source file (eg inline subprograms in a .h file), the
   counts are added.  */

static int multiple_files = 0;

/* Output branch probabilities.  */

static int flag_branches = 0;

/* Output conditions (modified condition/decision coverage).  */

static bool flag_conditions = 0;

/* Show unconditional branches too.  */
static int flag_unconditional = 0;

/* Output path coverage.  */
static bool flag_prime_paths = false;

/* Output path coverage - lines mode.  */
static bool flag_prime_paths_lines_covered = false;
static bool flag_prime_paths_lines_uncovered = false;

/* Output path coverage - source mode.  */
static bool flag_prime_paths_source_covered  = false;
static bool flag_prime_paths_source_uncovered  = false;

/* Output a gcov file if this is true.  This is on by default, and can
   be turned off by the -n option.  */

static int flag_gcov_file = 1;

/* Output to stdout instead to a gcov file.  */

static int flag_use_stdout = 0;

/* Output progress indication if this is true.  This is off by default
   and can be turned on by the -d option.  */

static int flag_display_progress = 0;

/* Output *.gcov file in JSON intermediate format used by consumers.  */

static int flag_json_format = 0;

/* For included files, make the gcov output file name include the name
   of the input source file.  For example, if x.h is included in a.c,
   then the output file name is a.c##x.h.gcov instead of x.h.gcov.  */

static int flag_long_names = 0;

/* For situations when a long name can potentially hit filesystem path limit,
   let's calculate md5sum of the path and append it to a file name.  */

static int flag_hash_filenames = 0;

/* Print verbose informations.  */

static int flag_verbose = 0;

/* Print colored output.  */

static int flag_use_colors = 0;

/* Use perf-like colors to indicate hot lines.  */

static int flag_use_hotness_colors = 0;

/* Output count information for every basic block, not merely those
   that contain line number information.  */

static int flag_all_blocks = 0;

/* Output human readable numbers.  */

static int flag_human_readable_numbers = 0;

/* Output summary info for each function.  */

static int flag_function_summary = 0;

/* Print debugging dumps.  */

static int flag_debug = 0;

/* Object directory file prefix.  This is the directory/file where the
   graph and data files are looked for, if nonzero.  */

static char *object_directory = 0;

/* Source directory prefix.  This is removed from source pathnames
   that match, when generating the output file name.  */

static char *source_prefix = 0;
static size_t source_length = 0;

/* Only show data for sources with relative pathnames.  Absolute ones
   usually indicate a system header file, which although it may
   contain inline functions, is usually uninteresting.  */
static int flag_relative_only = 0;

/* Preserve all pathname components. Needed when object files and
   source files are in subdirectories. '/' is mangled as '#', '.' is
   elided and '..' mangled to '^'.  */

static int flag_preserve_paths = 0;

/* Output the number of times a branch was taken as opposed to the percentage
   of times it was taken.  */

static int flag_counts = 0;

/* Return code of the tool invocation.  */
static int return_code = 0;

/* "Keep policy" when adding functions to the global function table.  This will
   be set to false when --include is used, otherwise every function should be
   added to the table.  Used for --include/exclude.  */
static bool default_keep = true;

/* Include/exclude filters function based on matching the (de)mangled name.
   The default is to match the mangled name.  Note that flag_demangled_names
   does not affect this.  */
static bool flag_filter_on_demangled = false;

/* A 'function filter', a filter and action for determining if a function
   should be included in the output or not.  Used for --include/--exclude
   filtering.  */
struct fnfilter
{
  /* The (extended) compiled regex for this filter.  */
  regex_t regex;

  /* The action when this filter (regex) matches - if true, the function should
     be kept, otherwise discarded.  */
  bool keep;

  /* Compile the regex EXPR, or exit if pattern is malformed.  */
  void compile (const char *expr)
  {
    int err = regcomp (&regex, expr, REG_NOSUB | REG_EXTENDED);
    if (err)
      {
	size_t len = regerror (err, &regex, nullptr, 0);
	char *msg = XNEWVEC (char, len);
	regerror (err, &regex, msg, len);
	fprintf (stderr, "Bad regular expression: %s\n", msg);
	free (msg);
	exit (EXIT_FAILURE);
    }
  }
};

/* A collection of filter functions for including/exclude functions in the
   output.  This is empty unless --include/--exclude is used.  */
static vector<fnfilter> filters;

/* Forward declarations.  */
static int process_args (int, char **);
static void print_usage (int) ATTRIBUTE_NORETURN;
static void print_version (void) ATTRIBUTE_NORETURN;
static void process_file (const char *);
static void process_all_functions (void);
static void generate_results (const char *);
static void create_file_names (const char *);
static char *canonicalize_name (const char *);
static unsigned find_source (const char *);
static void read_graph_file (void);
static int read_count_file (void);
static void solve_flow_graph (function_info *);
static void find_prime_paths (function_info *fn);
static void find_exception_blocks (function_info *);
static void add_branch_counts (coverage_info *, const arc_info *);
static void add_condition_counts (coverage_info *, const block_info *);
static void add_path_counts (coverage_info &, const function_info &);
static void add_line_counts (coverage_info *, function_info *);
static void executed_summary (unsigned, unsigned);
static void function_summary (const coverage_info *);
static void file_summary (const coverage_info *);
static const char *format_gcov (gcov_type, gcov_type, int);
static void accumulate_line_counts (source_info *);
static void output_gcov_file (const char *, source_info *);
static int output_branch_count (FILE *, int, const arc_info *);
static void output_conditions (FILE *, const block_info *);
static void output_lines (FILE *, const source_info *);
static string make_gcov_file_name (const char *, const char *);
static char *mangle_name (const char *);
static void release_structures (void);
extern int main (int, char **);
static const vector<const char *>&
slurp (const source_info &src, FILE *gcov_file, const char *line_start);

function_info::function_info (): m_name (NULL), m_demangled_name (NULL),
  ident (0), lineno_checksum (0), cfg_checksum (0), has_catch (0),
  artificial (0), is_group (0),
  blocks (), blocks_executed (0), counts (),
  start_line (0), start_column (0), end_line (0), end_column (0),
  src (0), lines (), next (NULL)
{
}

function_info::~function_info ()
{
  for (int i = blocks.size () - 1; i >= 0; i--)
    {
      arc_info *arc, *arc_n;

      for (arc = blocks[i].succ; arc; arc = arc_n)
	{
	  arc_n = arc->succ_next;
	  free (arc);
	}
    }
  if (m_demangled_name != m_name)
    free (m_demangled_name);
  free (m_name);
}

bool function_info::group_line_p (unsigned n, unsigned src_idx)
{
  return is_group && src == src_idx && start_line <= n && n <= end_line;
}

/* Find the arc that connects BLOCK to the block with id DEST.  This
   edge must exist.  */
static const arc_info&
find_arc (const block_info &block, unsigned dest)
{
  for (const arc_info *arc = block.succ; arc; arc = arc->succ_next)
    if (arc->dst->id == dest)
      return *arc;
  gcc_assert (false);
}

/* Cycle detection!
   There are a bajillion algorithms that do this.  Boost's function is named
   hawick_cycles, so I used the algorithm by K. A. Hawick and H. A. James in
   "Enumerating Circuits and Loops in Graphs with Self-Arcs and Multiple-Arcs"
   (url at <http://complexity.massey.ac.nz/cstn/013/cstn-013.pdf>).

   The basic algorithm is simple: effectively, we're finding all simple paths
   in a subgraph (that shrinks every iteration).  Duplicates are filtered by
   "blocking" a path when a node is added to the path (this also prevents non-
   simple paths)--the node is unblocked only when it participates in a cycle.
   */

typedef vector<arc_info *> arc_vector_t;
typedef vector<const block_info *> block_vector_t;

/* Handle cycle identified by EDGES, where the function finds minimum cs_count
   and subtract the value from all counts.  The subtracted value is added
   to COUNT.  Returns type of loop.  */

static void
handle_cycle (const arc_vector_t &edges, int64_t &count)
{
  /* Find the minimum edge of the cycle, and reduce all nodes in the cycle by
     that amount.  */
  int64_t cycle_count = INTTYPE_MAXIMUM (int64_t);
  for (unsigned i = 0; i < edges.size (); i++)
    {
      int64_t ecount = edges[i]->cs_count;
      if (cycle_count > ecount)
	cycle_count = ecount;
    }
  count += cycle_count;
  for (unsigned i = 0; i < edges.size (); i++)
    edges[i]->cs_count -= cycle_count;

  gcc_assert (cycle_count > 0);
}

/* Unblock a block U from BLOCKED.  Apart from that, iterate all blocks
   blocked by U in BLOCK_LISTS.  */

static void
unblock (const block_info *u, block_vector_t &blocked,
	 vector<block_vector_t > &block_lists)
{
  block_vector_t::iterator it = find (blocked.begin (), blocked.end (), u);
  if (it == blocked.end ())
    return;

  unsigned index = it - blocked.begin ();
  blocked.erase (it);

  block_vector_t to_unblock (block_lists[index]);

  block_lists.erase (block_lists.begin () + index);

  for (block_vector_t::iterator it = to_unblock.begin ();
       it != to_unblock.end (); it++)
    unblock (*it, blocked, block_lists);
}

/* Return true when PATH contains a zero cycle arc count.  */

static bool
path_contains_zero_or_negative_cycle_arc (arc_vector_t &path)
{
  for (unsigned i = 0; i < path.size (); i++)
    if (path[i]->cs_count <= 0)
      return true;
  return false;
}

/* Find circuit going to block V, PATH is provisional seen cycle.
   BLOCKED is vector of blocked vertices, BLOCK_LISTS contains vertices
   blocked by a block.  COUNT is accumulated count of the current LINE.
   Returns what type of loop it contains.  */

static bool
circuit (block_info *v, arc_vector_t &path, block_info *start,
	 block_vector_t &blocked, vector<block_vector_t> &block_lists,
	 line_info &linfo, int64_t &count)
{
  bool loop_found = false;

  /* Add v to the block list.  */
  gcc_assert (find (blocked.begin (), blocked.end (), v) == blocked.end ());
  blocked.push_back (v);
  block_lists.push_back (block_vector_t ());

  for (arc_info *arc = v->succ; arc; arc = arc->succ_next)
    {
      block_info *w = arc->dst;
      if (w < start
	  || arc->cs_count <= 0
	  || !linfo.has_block (w))
	continue;

      path.push_back (arc);
      if (w == start)
	{
	  /* Cycle has been found.  */
	  handle_cycle (path, count);
	  loop_found = true;
	}
      else if (!path_contains_zero_or_negative_cycle_arc (path)
	       &&  find (blocked.begin (), blocked.end (), w) == blocked.end ())
	loop_found |= circuit (w, path, start, blocked, block_lists, linfo,
			       count);

      path.pop_back ();
    }

  if (loop_found)
    unblock (v, blocked, block_lists);
  else
    for (arc_info *arc = v->succ; arc; arc = arc->succ_next)
      {
	block_info *w = arc->dst;
	if (w < start
	    || arc->cs_count <= 0
	    || !linfo.has_block (w))
	  continue;

	size_t index
	  = find (blocked.begin (), blocked.end (), w) - blocked.begin ();
	gcc_assert (index < blocked.size ());
	block_vector_t &list = block_lists[index];
	if (find (list.begin (), list.end (), v) == list.end ())
	  list.push_back (v);
      }

  return loop_found;
}

/* Find cycles for a LINFO.  */

static gcov_type
get_cycles_count (line_info &linfo)
{
  /* Note that this algorithm works even if blocks aren't in sorted order.
     Each iteration of the circuit detection is completely independent
     (except for reducing counts, but that shouldn't matter anyways).
     Therefore, operating on a permuted order (i.e., non-sorted) only
     has the effect of permuting the output cycles.  */

  gcov_type count = 0;
  for (vector<block_info *>::iterator it = linfo.blocks.begin ();
       it != linfo.blocks.end (); it++)
    {
      arc_vector_t path;
      block_vector_t blocked;
      vector<block_vector_t > block_lists;
      circuit (*it, path, *it, blocked, block_lists, linfo, count);
    }

  return count;
}

int
main (int argc, char **argv)
{
  int argno;
  int first_arg;
  const char *p;

  p = argv[0] + strlen (argv[0]);
  while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
    --p;
  progname = p;

  xmalloc_set_program_name (progname);

  /* Unlock the stdio streams.  */
  unlock_std_streams ();

  gcc_init_libintl ();

  diagnostic_initialize (global_dc, 0);

  /* Handle response files.  */
  expandargv (&argc, &argv);

  argno = process_args (argc, argv);
  if (optind == argc)
    print_usage (true);

  if (argc - argno > 1)
    multiple_files = 1;

  first_arg = argno;

  for (; argno != argc; argno++)
    {
      if (flag_display_progress)
	printf ("Processing file %d out of %d\n", argno - first_arg + 1,
		argc - first_arg);
      process_file (argv[argno]);

      if (flag_json_format || argno == argc - 1)
	{
	  process_all_functions ();
	  generate_results (argv[argno]);
	  release_structures ();
	}
    }

  if (!flag_use_stdout)
    executed_summary (total_lines, total_executed);

  return return_code;
}

/* Print a usage message and exit.  If ERROR_P is nonzero, this is an error,
   otherwise the output of --help.  */

static void
print_usage (int error_p)
{
  FILE *file = error_p ? stderr : stdout;
  int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;

  fnotice (file, "Usage: gcov [OPTION...] SOURCE|OBJ...\n\n");
  fnotice (file, "Print code coverage information.\n\n");
  fnotice (file, "  -a, --all-blocks                Show information for every basic block\n");
  fnotice (file, "  -b, --branch-probabilities      Include branch probabilities in output\n");
  fnotice (file, "  -c, --branch-counts             Output counts of branches taken\n\
                                    rather than percentages\n");
  fnotice (file, "  -g, --conditions                Include modified condition/decision\n\
                                    coverage (masking MC/DC) in output\n");
  fnotice (file, "  -e, --prime-paths               Show prime path coverage summary\n");
  fnotice (file, "      --prime-paths-lines[=TYPE]  Include paths in output\n\
                                    line trace mode - does not affect json\n\
                                    TYPE is 'covered', 'uncovered', or 'both'\n\
                                    and defaults to 'uncovered'\n");
  fnotice (file, "      --prime-paths-source[=TYPE] Include paths in output\n\
                                    source trace mode - does not affect json\n\
                                    TYPE is 'covered', 'uncovered', or 'both'\n\
                                    and defaults to 'uncovered'\n");
  fnotice (file, "  -d, --display-progress          Display progress information\n");
  fnotice (file, "  -D, --debug			    Display debugging dumps\n");
  fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
  fnotice (file, "      --include                   Include functions matching this regex\n");
  fnotice (file, "      --exclude                   Exclude functions matching this regex\n");
  fnotice (file, "  -h, --help                      Print this help, then exit\n");
  fnotice (file, "  -j, --json-format               Output JSON intermediate format\n\
                                    into .gcov.json.gz file\n");
  fnotice (file, "  -H, --human-readable            Output human readable numbers\n");
  fnotice (file, "  -k, --use-colors                Emit colored output\n");
  fnotice (file, "  -l, --long-file-names           Use long output file names for included\n\
                                    source files\n");
  fnotice (file, "  -m, --demangled-names           Output demangled function names\n");
  fnotice (file, "  -M, --filter-on-demangled       Make --include/--exclude match on demangled\n\
                                    names. This does not imply -m\n");
  fnotice (file, "  -n, --no-output                 Do not create an output file\n");
  fnotice (file, "  -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n");
  fnotice (file, "  -p, --preserve-paths            Preserve all pathname components\n");
  fnotice (file, "  -q, --use-hotness-colors        Emit perf-like colored output for hot lines\n");
  fnotice (file, "  -r, --relative-only             Only show data for relative sources\n");
  fnotice (file, "  -s, --source-prefix DIR         Source prefix to elide\n");
  fnotice (file, "  -t, --stdout                    Output to stdout instead of a file\n");
  fnotice (file, "  -u, --unconditional-branches    Show unconditional branch counts too\n");
  fnotice (file, "  -v, --version                   Print version number, then exit\n");
  fnotice (file, "  -w, --verbose                   Print verbose informations\n");
  fnotice (file, "  -x, --hash-filenames            Hash long pathnames\n");
  fnotice (file, "\nObsolete options:\n");
  fnotice (file, "  -i, --json-format               Replaced with -j, --json-format\n");
  fnotice (file, "  -j, --human-readable            Replaced with -H, --human-readable\n");
  fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
	   bug_report_url);
  exit (status);
}

/* Print version information and exit.  */

static void
print_version (void)
{
  fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
  fnotice (stdout, "JSON format version: %s\n", GCOV_JSON_FORMAT_VERSION);
  fprintf (stdout, "Copyright %s 2025 Free Software Foundation, Inc.\n",
	   _("(C)"));
  fnotice (stdout,
	   _("This is free software; see the source for copying conditions.  There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
  exit (SUCCESS_EXIT_CODE);
}

static const struct option options[] =
{
  { "help",                 no_argument,       NULL, 'h' },
  { "version",              no_argument,       NULL, 'v' },
  { "verbose",              no_argument,       NULL, 'w' },
  { "all-blocks",           no_argument,       NULL, 'a' },
  { "branch-probabilities", no_argument,       NULL, 'b' },
  { "branch-counts",        no_argument,       NULL, 'c' },
  { "conditions",	    no_argument,       NULL, 'g' },
  { "prime-paths",	    no_argument,       NULL, 'e' },
  { "prime-paths-lines",    optional_argument, NULL, 900 },
  { "prime-paths-source",   optional_argument, NULL, 901 },
  { "json-format",	    no_argument,       NULL, 'j' },
  { "include",              required_argument, NULL, 'I' },
  { "exclude",              required_argument, NULL, 'E' },
  { "human-readable",	    no_argument,       NULL, 'H' },
  { "no-output",            no_argument,       NULL, 'n' },
  { "long-file-names",      no_argument,       NULL, 'l' },
  { "function-summaries",   no_argument,       NULL, 'f' },
  { "demangled-names",      no_argument,       NULL, 'm' },
  { "filter-on-demangled",  no_argument,       NULL, 'M' },
  { "preserve-paths",       no_argument,       NULL, 'p' },
  { "relative-only",        no_argument,       NULL, 'r' },
  { "object-directory",     required_argument, NULL, 'o' },
  { "object-file",          required_argument, NULL, 'o' },
  { "source-prefix",        required_argument, NULL, 's' },
  { "stdout",		    no_argument,       NULL, 't' },
  { "unconditional-branches", no_argument,     NULL, 'u' },
  { "display-progress",     no_argument,       NULL, 'd' },
  { "hash-filenames",	    no_argument,       NULL, 'x' },
  { "use-colors",	    no_argument,       NULL, 'k' },
  { "use-hotness-colors",   no_argument,       NULL, 'q' },
  { "debug",		    no_argument,       NULL, 'D' },
  { 0, 0, 0, 0 }
};

/* Process args, return index to first non-arg.  */

static int
process_args (int argc, char **argv)
{
  int opt;

  const char *opts = "abcdDefghHijklmMno:pqrs:tuvwx";
  while ((opt = getopt_long (argc, argv, opts, options, NULL)) != -1)
    {
      switch (opt)
	{
	case 'a':
	  flag_all_blocks = 1;
	  break;
	case 'b':
	  flag_branches = 1;
	  break;
	case 'c':
	  flag_counts = 1;
	  break;
	case 'e':
	  flag_prime_paths = true;
	  break;
	case 900:
	  flag_prime_paths = true;
	  if (!optarg)
	    flag_prime_paths_lines_uncovered = true;
	  else if (strcmp (optarg, "uncovered") == 0)
	    flag_prime_paths_lines_uncovered = true;
	  else if (strcmp (optarg, "covered") == 0)
	    flag_prime_paths_lines_covered = true;
	  else if (strcmp (optarg, "both") == 0)
	    {
		flag_prime_paths_lines_covered = true;
		flag_prime_paths_lines_uncovered = true;
	    }
	  else
	    {
	      fnotice (stderr, "invalid argument '%s' for "
		       "'--prime-paths-lines'. Valid arguments are: "
		       "'covered', 'uncovered', 'both'\n", optarg);
	      exit (FATAL_EXIT_CODE);
	    }
	  break;
	case 901:
	  flag_prime_paths = true;
	  if (!optarg)
	    flag_prime_paths_source_uncovered = true;
	  else if (strcmp (optarg, "uncovered") == 0)
	    flag_prime_paths_source_uncovered = true;
	  else if (strcmp (optarg, "covered") == 0)
	    flag_prime_paths_source_covered = true;
	  else if (strcmp (optarg, "both") == 0)
	    {
		flag_prime_paths_source_covered = true;
		flag_prime_paths_source_uncovered = true;
	    }
	  else
	    {
	      fnotice (stderr, "invalid argument '%s' for "
		       "'--prime-paths-source'. Valid arguments are: "
		       "'covered', 'uncovered', 'both'\n", optarg);
	      exit (FATAL_EXIT_CODE);
	    }
	  break;
	case 'f':
	  flag_function_summary = 1;
	  break;
	case 'g':
	  flag_conditions = 1;
	  break;
	case 'h':
	  print_usage (false);
	  /* print_usage will exit.  */
	case 'l':
	  flag_long_names = 1;
	  break;
	case 'I':
	  default_keep = false;
	  filters.push_back (fnfilter {});
	  filters.back ().keep = true;
	  filters.back ().compile (optarg);
	  break;
	case 'E':
	  filters.push_back (fnfilter {});
	  filters.back ().keep = false;
	  filters.back ().compile (optarg);
	  break;
	case 'H':
	  flag_human_readable_numbers = 1;
	  break;
	case 'k':
	  flag_use_colors = 1;
	  break;
	case 'q':
	  flag_use_hotness_colors = 1;
	  break;
	case 'm':
	  flag_demangled_names = 1;
	  break;
	case 'M':
	  flag_filter_on_demangled = true;
	  break;
	case 'n':
	  flag_gcov_file = 0;
	  break;
	case 'o':
	  object_directory = optarg;
	  break;
	case 's':
	  source_prefix = optarg;
	  source_length = strlen (source_prefix);
	  break;
	case 'r':
	  flag_relative_only = 1;
	  break;
	case 'p':
	  flag_preserve_paths = 1;
	  break;
	case 'u':
	  flag_unconditional = 1;
	  break;
	case 'i':
	case 'j':
	  flag_json_format = 1;
	  flag_gcov_file = 1;
	  break;
	case 'd':
	  flag_display_progress = 1;
	  break;
	case 'x':
	  flag_hash_filenames = 1;
	  break;
	case 'w':
	  flag_verbose = 1;
	  break;
	case 't':
	  flag_use_stdout = 1;
	  break;
	case 'D':
	  flag_debug = 1;
	  break;
	case 'v':
	  print_version ();
	  /* print_version will exit.  */
	default:
	  print_usage (true);
	  /* print_usage will exit.  */
	}
    }

  return optind;
}

/* Output intermediate LINE sitting on LINE_NUM to JSON OBJECT.
   Add FUNCTION_NAME to the LINE.  */

static void
output_intermediate_json_line (json::array *object,
			       line_info *line, unsigned line_num,
			       const char *function_name)
{
  if (!line->exists)
    return;

  json::object *lineo = new json::object ();
  lineo->set_integer ("line_number", line_num);
  if (function_name != NULL)
    lineo->set_string ("function_name", function_name);
  lineo->set_integer ("count", line->count);
  lineo->set_bool ("unexecuted_block", line->has_unexecuted_block);

  json::array *bb_ids = new json::array ();
  for (const block_info *block : line->blocks)
    bb_ids->append (new json::integer_number (block->id));
  lineo->set ("block_ids", bb_ids);

  json::array *branches = new json::array ();
  lineo->set ("branches", branches);

  json::array *calls = new json::array ();
  lineo->set ("calls", calls);

  vector<arc_info *>::const_iterator it;
  if (flag_branches)
    for (it = line->branches.begin (); it != line->branches.end ();
	 it++)
      {
	if (!(*it)->is_unconditional && !(*it)->is_call_non_return)
	  {
	    json::object *branch = new json::object ();
	    branch->set_integer ("count", (*it)->count);
	    branch->set_bool ("throw", (*it)->is_throw);
	    branch->set_bool ("fallthrough", (*it)->fall_through);
	    branch->set_integer ("source_block_id", (*it)->src->id);
	    branch->set_integer ("destination_block_id", (*it)->dst->id);
	    branches->append (branch);
	  }
	else if ((*it)->is_call_non_return)
	  {
	    json::object *call = new json::object ();
	    gcov_type returns = (*it)->src->count - (*it)->count;
	    call->set_integer ("source_block_id", (*it)->src->id);
	    call->set_integer ("destination_block_id", (*it)->dst->id);
	    call->set_integer ("returned", returns);
	    calls->append (call);
	  }
      }

  json::array *conditions = new json::array ();
  lineo->set ("conditions", conditions);
  if (flag_conditions)
  {
    vector<block_info *>::const_iterator it;
    for (it = line->blocks.begin (); it != line->blocks.end (); it++)
      {
	const condition_info& info = (*it)->conditions;
	if (info.n_terms == 0)
	    continue;

	const int count = 2 * info.n_terms;
	const int covered = info.popcount ();

	json::object *cond = new json::object ();
	cond->set_integer ("count", count);
	cond->set_integer ("covered", covered);

	json::array *mtrue = new json::array ();
	json::array *mfalse = new json::array ();
	cond->set ("not_covered_true", mtrue);
	cond->set ("not_covered_false", mfalse);

	if (count != covered)
	  {
	    for (unsigned i = 0; i < info.n_terms; i++)
	      {
		gcov_type_unsigned index = 1;
		index <<= i;
		if (!(index & info.truev))
		    mtrue->append (new json::integer_number (i));
		if (!(index & info.falsev))
		    mfalse->append (new json::integer_number (i));
	      }
	  }
	conditions->append (cond);
      }
  }

  object->append (lineo);
}

/* Strip filename extension in STR.  */

static string
strip_extention (string str)
{
  string::size_type pos = str.rfind ('.');
  if (pos != string::npos)
    str = str.substr (0, pos);

  return str;
}

/* Calcualte md5sum for INPUT string and return it in hex string format.  */

static string
get_md5sum (const char *input)
{
  md5_ctx ctx;
  char md5sum[16];
  string str;

  md5_init_ctx (&ctx);
  md5_process_bytes (input, strlen (input), &ctx);
  md5_finish_ctx (&ctx, md5sum);

  for (unsigned i = 0; i < 16; i++)
    {
      char b[3];
      sprintf (b, "%02x", (unsigned char)md5sum[i]);
      str += b;
    }

  return str;
}

/* Get the name of the gcov file.  The return value must be free'd.

   It appends the '.gcov' extension to the *basename* of the file.
   The resulting file name will be in PWD.

   e.g.,
   input: foo.da,       output: foo.da.gcov
   input: a/b/foo.cc,   output: foo.cc.gcov  */

static string
get_gcov_intermediate_filename (const char *input_file_name)
{
  string base = lbasename (input_file_name);
  string str = strip_extention (base);

  if (flag_hash_filenames)
    {
      str += "##";
      str += get_md5sum (input_file_name);
    }
  else if (flag_preserve_paths && base != input_file_name)
    {
      str += "##";
      str += mangle_path (input_file_name);
      str = strip_extention (str);
    }

  str += ".gcov.json.gz";
  return str.c_str ();
}

/* Add prime path coverage from INFO to FUNCTION.  */
static void
json_set_prime_path_coverage (json::object &function, function_info &info)
{
  json::array *jpaths = new json::array ();
  function.set_integer ("total_prime_paths", info.paths.paths.size ());
  function.set_integer ("covered_prime_paths", info.paths.covered_paths ());
  function.set ("prime_path_coverage", jpaths);

  size_t pathno = 0;
  for (const vector<unsigned> &path : info.paths.paths)
    {
      if (info.paths.covered_p (pathno++))
	continue;

      gcc_assert (!path.empty ());

      json::object *jpath = new json::object ();
      jpaths->append (jpath);
      jpath->set_integer ("id", pathno - 1);

      json::array *jlist = new json::array ();
      jpath->set ("sequence", jlist);

      for (size_t i = 0; i != path.size (); ++i)
	{
	  const unsigned bb = path[i];
	  const block_info &block = info.blocks[bb];
	  const char *edge_kind = "";
	  if (i + 1 != path.size ())
	    {
	      const arc_info &arc = find_arc (block, path[i+1]);
	      if (arc.false_value)
		edge_kind = "true";
	      else if (arc.false_value)
		edge_kind = "false";
	      else if (arc.fall_through)
		edge_kind = "fallthru";
	      else if (arc.is_throw)
		edge_kind = "throw";
	    }

	  json::object *jblock = new json::object ();
	  json::array *jlocs = new json::array ();
	  jblock->set_integer ("block_id", block.id);
	  jblock->set ("locations", jlocs);
	  jblock->set_string ("edge_kind", edge_kind);
	  jlist->append (jblock);
	  for (const block_location_info &loc : block.locations)
	    {
	      /* loc.lines could be empty when a statement is not anchored to a
		 source file -- see g++.dg/gcov/gcov-23.C.  */
	      if (loc.lines.empty ())
		continue;
	      json::object *jloc = new json::object ();
	      json::array *jline_numbers = new json::array ();
	      jlocs->append (jloc);
	      jloc->set_string ("file", sources[loc.source_file_idx].name);
	      jloc->set ("line_numbers", jline_numbers);
	      for (unsigned line : loc.lines)
		jline_numbers->append (new json::integer_number (line));
	    }
	}
    }
}

/* Output the result in JSON intermediate format.
   Source info SRC is dumped into JSON_FILES which is JSON array.  */

static void
output_json_intermediate_file (json::array *json_files, source_info *src)
{
  json::object *root = new json::object ();
  json_files->append (root);

  root->set_string ("file", src->name);

  json::array *functions = new json::array ();
  root->set ("functions", functions);

  std::sort (src->functions.begin (), src->functions.end (),
	     function_line_start_cmp ());
  for (vector<function_info *>::iterator it = src->functions.begin ();
       it != src->functions.end (); it++)
    {
      json::object *function = new json::object ();
      function->set_string ("name", (*it)->m_name);
      function->set_string ("demangled_name", (*it)->get_demangled_name ());
      function->set_integer ("start_line", (*it)->start_line);
      function->set_integer ("start_column", (*it)->start_column);
      function->set_integer ("end_line", (*it)->end_line);
      function->set_integer ("end_column", (*it)->end_column);
      function->set_integer ("blocks", (*it)->get_block_count ());
      function->set_integer ("blocks_executed", (*it)->blocks_executed);
      function->set_integer ("execution_count", (*it)->blocks[0].count);

      json_set_prime_path_coverage (*function, **it);
      functions->append (function);
    }

  json::array *lineso = new json::array ();
  root->set ("lines", lineso);

  vector<function_info *> last_non_group_fns;

  for (unsigned line_num = 1; line_num <= src->lines.size (); line_num++)
    {
      vector<function_info *> *fns = src->get_functions_at_location (line_num);

      if (fns != NULL)
	/* Print info for all group functions that begin on the line.  */
	for (vector<function_info *>::iterator it2 = fns->begin ();
	     it2 != fns->end (); it2++)
	  {
	    if (!(*it2)->is_group)
	      last_non_group_fns.push_back (*it2);

	    vector<line_info> &lines = (*it2)->lines;
	    /* The LINES array is allocated only for group functions.  */
	    for (unsigned i = 0; i < lines.size (); i++)
	      {
		line_info *line = &lines[i];
		output_intermediate_json_line (lineso, line, line_num + i,
					       (*it2)->m_name);
	      }
	  }

      /* Follow with lines associated with the source file.  */
      if (line_num < src->lines.size ())
	{
	  unsigned size = last_non_group_fns.size ();
	  function_info *last_fn = size > 0 ? last_non_group_fns[size - 1] : NULL;
	  const char *fname = last_fn ? last_fn->m_name : NULL;
	  output_intermediate_json_line (lineso, &src->lines[line_num], line_num,
					 fname);

	  /* Pop ending function from stack.  */
	  if (last_fn != NULL && last_fn->end_line == line_num)
	    last_non_group_fns.pop_back ();
	}
    }
}

/* Function start pair.  */
struct function_start
{
  unsigned source_file_idx;
  unsigned start_line;
};

/* Traits class for function start hash maps below.  */

struct function_start_pair_hash : typed_noop_remove <function_start>
{
  typedef function_start value_type;
  typedef function_start compare_type;

  static hashval_t
  hash (const function_start &ref)
  {
    inchash::hash hstate (0);
    hstate.add_int (ref.source_file_idx);
    hstate.add_int (ref.start_line);
    return hstate.end ();
  }

  static bool
  equal (const function_start &ref1, const function_start &ref2)
  {
    return (ref1.source_file_idx == ref2.source_file_idx
	    && ref1.start_line == ref2.start_line);
  }

  static void
  mark_deleted (function_start &ref)
  {
    ref.start_line = ~1U;
  }

  static const bool empty_zero_p = false;

  static void
  mark_empty (function_start &ref)
  {
    ref.start_line = ~2U;
  }

  static bool
  is_deleted (const function_start &ref)
  {
    return ref.start_line == ~1U;
  }

  static bool
  is_empty (const function_start &ref)
  {
    return ref.start_line == ~2U;
  }
};

/* Process a single input file.  */

static void
process_file (const char *file_name)
{
  create_file_names (file_name);

  for (unsigned i = 0; i < processed_files.size (); i++)
    if (strcmp (da_file_name, processed_files[i]) == 0)
      {
	fnotice (stderr, "'%s' file is already processed\n",
		 file_name);
	return;
      }

  processed_files.push_back (xstrdup (da_file_name));

  read_graph_file ();
  read_count_file ();
}

/* Process all functions in all files.  */

static void
process_all_functions (void)
{
  hash_map<function_start_pair_hash, function_info *> fn_map;

  /* Identify group functions.  */
  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    if (!(*it)->artificial)
      {
	function_start needle;
	needle.source_file_idx = (*it)->src;
	needle.start_line = (*it)->start_line;

	function_info **slot = fn_map.get (needle);
	if (slot)
	  {
	    (*slot)->is_group = 1;
	    (*it)->is_group = 1;
	  }
	else
	  fn_map.put (needle, *it);
      }

  /* Remove all artificial function.  */
  functions.erase (remove_if (functions.begin (), functions.end (),
			      function_info::is_artificial), functions.end ());

  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    {
      function_info *fn = *it;
      unsigned src = fn->src;

      if (!fn->counts.empty () || no_data_file)
	{
	  source_info *s = &sources[src];
	  s->add_function (fn);

	  /* Mark last line in files touched by function.  */
	  for (unsigned block_no = 0; block_no != fn->blocks.size ();
	       block_no++)
	    {
	      block_info *block = &fn->blocks[block_no];
	      for (unsigned i = 0; i < block->locations.size (); i++)
		{
		  /* Sort lines of locations.  */
		  sort (block->locations[i].lines.begin (),
			block->locations[i].lines.end ());

		  if (!block->locations[i].lines.empty ())
		    {
		      s = &sources[block->locations[i].source_file_idx];
		      unsigned last_line
			= block->locations[i].lines.back ();

		      /* Record new lines for the function.  */
		      if (last_line >= s->lines.size ())
			{
			  s = &sources[block->locations[i].source_file_idx];
			  unsigned last_line
			    = block->locations[i].lines.back ();

			  /* Record new lines for the function.  */
			  if (last_line >= s->lines.size ())
			    {
			      /* Record new lines for a source file.  */
			      s->lines.resize (last_line + 1);
			    }
			}
		    }
		}
	    }

	  /* Make sure to include the last line for this function even when it
	     is not directly covered by a basic block, for example when } is on
	     its own line.  */
	  if (sources[fn->src].lines.size () <= fn->end_line)
	    sources[fn->src].lines.resize (fn->end_line + 1);

	  /* Allocate lines for group function, following start_line
	     and end_line information of the function.  */
	  if (fn->is_group)
	    fn->lines.resize (fn->end_line - fn->start_line + 1);

	  solve_flow_graph (fn);
	  if (fn->has_catch)
	    find_exception_blocks (fn);

	  /* For path coverage.  */
	  find_prime_paths (fn);
	}
      else
	{
	  /* The function was not in the executable -- some other
	     instance must have been selected.  */
	}
    }
}

static void
output_gcov_file (const char *file_name, source_info *src)
{
  string gcov_file_name_str
    = make_gcov_file_name (file_name, src->coverage.name);
  const char *gcov_file_name = gcov_file_name_str.c_str ();

  if (src->coverage.lines)
    {
      FILE *gcov_file = fopen (gcov_file_name, "w");
      if (gcov_file)
	{
	  fnotice (stdout, "Creating '%s'\n", gcov_file_name);
	  output_lines (gcov_file, src);
	  if (ferror (gcov_file))
	    {
	      fnotice (stderr, "Error writing output file '%s'\n",
		       gcov_file_name);
	      return_code = 6;
	    }
	  fclose (gcov_file);
	}
      else
	{
	  fnotice (stderr, "Could not open output file '%s'\n", gcov_file_name);
	  return_code = 6;
	}
    }
  else
    {
      unlink (gcov_file_name);
      fnotice (stdout, "Removing '%s'\n", gcov_file_name);
    }
}

static void
generate_results (const char *file_name)
{
  string gcov_intermediate_filename;

  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    {
      function_info *fn = *it;
      coverage_info coverage;

      memset (&coverage, 0, sizeof (coverage));
      coverage.name = fn->get_name ();
      add_line_counts (flag_function_summary ? &coverage : NULL, fn);

      if (!flag_function_summary)
	continue;

      for (const block_info& block : fn->blocks)
	for (arc_info *arc = block.succ; arc; arc = arc->succ_next)
	  add_branch_counts (&coverage, arc);

      for (const block_info& block : fn->blocks)
	add_condition_counts (&coverage, &block);

      add_path_counts (coverage, *fn);

      function_summary (&coverage);
      fnotice (stdout, "\n");
    }

  name_map needle;
  needle.name = file_name;
  vector<name_map>::iterator it
    = std::find (names.begin (), names.end (), needle);
  if (it != names.end ())
    file_name = sources[it->src].coverage.name;
  else
    file_name = canonicalize_name (file_name);

  gcov_intermediate_filename = get_gcov_intermediate_filename (file_name);

  json::object *root = new json::object ();
  root->set_string ("format_version", GCOV_JSON_FORMAT_VERSION);
  root->set_string ("gcc_version", version_string);

  if (bbg_cwd != NULL)
    root->set_string ("current_working_directory", bbg_cwd);
  root->set_string ("data_file", file_name);

  json::array *json_files = new json::array ();
  root->set ("files", json_files);

  for (vector<source_info>::iterator it = sources.begin ();
       it != sources.end (); it++)
    {
      source_info *src = &(*it);
      if (flag_relative_only)
	{
	  /* Ignore this source, if it is an absolute path (after
	     source prefix removal).  */
	  char first = src->coverage.name[0];

#if HAVE_DOS_BASED_FILE_SYSTEM
	  if (first && src->coverage.name[1] == ':')
	    first = src->coverage.name[2];
#endif
	  if (IS_DIR_SEPARATOR (first))
	    continue;
	}

      for (function_info *fn : src->functions)
	add_path_counts (src->coverage, *fn);

      accumulate_line_counts (src);
      if (flag_debug)
	src->debug ();

      if (!flag_use_stdout)
	file_summary (&src->coverage);
      total_lines += src->coverage.lines;
      total_executed += src->coverage.lines_executed;
      if (flag_gcov_file)
	{
	  if (flag_json_format)
	    {
	      output_json_intermediate_file (json_files, src);
	      if (!flag_use_stdout)
		fnotice (stdout, "\n");
	    }
	  else
	    {
	      if (flag_use_stdout)
		{
		  if (src->coverage.lines)
		    output_lines (stdout, src);
		}
	      else
		{
		  output_gcov_file (file_name, src);
		  fnotice (stdout, "\n");
		}
	    }
	}
    }

  if (flag_gcov_file && flag_json_format)
    {
      if (flag_use_stdout)
	{
	  root->dump (stdout, false);
	  printf ("\n");
	}
      else
	{
	  pretty_printer pp;
	  root->print (&pp, false);
	  pp_formatted_text (&pp);

	  fnotice (stdout, "Creating '%s'\n",
		   gcov_intermediate_filename.c_str ());
	  gzFile output = gzopen (gcov_intermediate_filename.c_str (), "w");
	  if (output == NULL)
	    {
	      fnotice (stderr, "Cannot open JSON output file %s\n",
		       gcov_intermediate_filename.c_str ());
	      return_code = 6;
	      return;
	    }

	  if (gzputs (output, pp_formatted_text (&pp)) == EOF
	      || gzclose (output))
	    {
	      fnotice (stderr, "Error writing JSON output file %s\n",
		       gcov_intermediate_filename.c_str ());
	      return_code = 6;
	      return;
	    }
	}
    }
}

/* Release all memory used.  */

static void
release_structures (void)
{
  for (vector<function_info *>::iterator it = functions.begin ();
       it != functions.end (); it++)
    delete (*it);

  for (vector<const char *> *lines : source_lines)
    {
      if (lines)
	for (const char *line : *lines)
	  free (const_cast <char*> (line));
      delete (lines);
    }
  source_lines.resize (0);

  for (fnfilter &filter : filters)
    regfree (&filter.regex);

  sources.resize (0);
  names.resize (0);
  functions.resize (0);
  filters.resize (0);
  ident_to_fn.clear ();
}

/* Generate the names of the graph and data files.  If OBJECT_DIRECTORY
   is not specified, these are named from FILE_NAME sans extension.  If
   OBJECT_DIRECTORY is specified and is a directory, the files are in that
   directory, but named from the basename of the FILE_NAME, sans extension.
   Otherwise OBJECT_DIRECTORY is taken to be the name of the object *file*
   and the data files are named from that.  */

static void
create_file_names (const char *file_name)
{
  char *cptr;
  char *name;
  int length = strlen (file_name);
  int base;

  /* Free previous file names.  */
  free (bbg_file_name);
  free (da_file_name);
  da_file_name = bbg_file_name = NULL;
  bbg_file_time = 0;
  bbg_stamp = 0;

  if (object_directory && object_directory[0])
    {
      struct stat status;

      length += strlen (object_directory) + 2;
      name = XNEWVEC (char, length);
      name[0] = 0;

      base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
      strcat (name, object_directory);
      if (base && (!IS_DIR_SEPARATOR (name[strlen (name) - 1])))
	strcat (name, "/");
    }
  else
    {
      name = XNEWVEC (char, length + 1);
      strcpy (name, file_name);
      base = 0;
    }

  if (base)
    {
      /* Append source file name.  */
      const char *cptr = lbasename (file_name);
      strcat (name, cptr ? cptr : file_name);
    }

  /* Remove the extension.  */
  cptr = strrchr (CONST_CAST (char *, lbasename (name)), '.');
  if (cptr)
    *cptr = 0;

  length = strlen (name);

  bbg_file_name = XNEWVEC (char, length + strlen (GCOV_NOTE_SUFFIX) + 1);
  strcpy (bbg_file_name, name);
  strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX);

  da_file_name = XNEWVEC (char, length + strlen (GCOV_DATA_SUFFIX) + 1);
  strcpy (da_file_name, name);
  strcpy (da_file_name + length, GCOV_DATA_SUFFIX);

  free (name);
  return;
}

/* Find or create a source file structure for FILE_NAME. Copies
   FILE_NAME on creation */

static unsigned
find_source (const char *file_name)
{
  char *canon;
  unsigned idx;
  struct stat status;

  if (!file_name)
    file_name = "<unknown>";

  name_map needle;
  needle.name = file_name;

  vector<name_map>::iterator it = std::find (names.begin (), names.end (),
					     needle);
  if (it != names.end ())
    {
      idx = it->src;
      goto check_date;
    }

  /* Not found, try the canonical name. */
  canon = canonicalize_name (file_name);
  needle.name = canon;
  it = std::find (names.begin (), names.end (), needle);
  if (it == names.end ())
    {
      /* Not found with canonical name, create a new source.  */
      source_info *src;

      idx = sources.size ();
      needle = name_map (canon, idx);
      names.push_back (needle);

      sources.push_back (source_info ());
      src = &sources.back ();
      src->name = canon;
      src->coverage.name = src->name;
      src->index = idx;
      if (source_length
#if HAVE_DOS_BASED_FILE_SYSTEM
	  /* You lose if separators don't match exactly in the
	     prefix.  */
	  && !strncasecmp (source_prefix, src->coverage.name, source_length)
#else
	  && !strncmp (source_prefix, src->coverage.name, source_length)
#endif
	  && IS_DIR_SEPARATOR (src->coverage.name[source_length]))
	src->coverage.name += source_length + 1;
      if (!stat (src->name, &status))
	src->file_time = status.st_mtime;
    }
  else
    idx = it->src;

  needle.name = file_name;
  if (std::find (names.begin (), names.end (), needle) == names.end ())
    {
      /* Append the non-canonical name.  */
      names.push_back (name_map (xstrdup (file_name), idx));
    }

  /* Resort the name map.  */
  std::sort (names.begin (), names.end ());

 check_date:
  if (sources[idx].file_time > bbg_file_time)
    {
      static int info_emitted;

      fnotice (stderr, "%s:source file is newer than notes file '%s'\n",
	       file_name, bbg_file_name);
      if (!info_emitted)
	{
	  fnotice (stderr,
		   "(the message is displayed only once per source file)\n");
	  info_emitted = 1;
	}
      sources[idx].file_time = 0;
    }

  return idx;
}

/* Read the notes file.  Save functions to FUNCTIONS global vector.  */

static void
read_graph_file (void)
{
  unsigned version;
  unsigned current_tag = 0;
  unsigned tag;

  if (!gcov_open (bbg_file_name, 1))
    {
      fnotice (stderr, "%s:cannot open notes file\n", bbg_file_name);
      return_code = 1;
      return;
    }
  bbg_file_time = gcov_time ();
  if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
    {
      fnotice (stderr, "%s:not a gcov notes file\n", bbg_file_name);
      return_code = 2;
      gcov_close ();
      return;
    }

  version = gcov_read_unsigned ();
  if (version != GCOV_VERSION)
    {
      char v[4], e[4];

      GCOV_UNSIGNED2STRING (v, version);
      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);

      fnotice (stderr, "%s:version '%.4s', prefer '%.4s'\n",
	       bbg_file_name, v, e);
      return_code = 3;
    }
  bbg_stamp = gcov_read_unsigned ();
  /* Read checksum.  */
  gcov_read_unsigned ();
  bbg_cwd = xstrdup (gcov_read_string ());
  bbg_supports_has_unexecuted_blocks = gcov_read_unsigned ();

  function_info *fn = NULL;
  while ((tag = gcov_read_unsigned ()))
    {
      unsigned length = gcov_read_unsigned ();
      gcov_position_t base = gcov_position ();

      if (tag == GCOV_TAG_FUNCTION)
	{
	  char *function_name;
	  unsigned ident;
	  unsigned lineno_checksum, cfg_checksum;

	  ident = gcov_read_unsigned ();
	  lineno_checksum = gcov_read_unsigned ();
	  cfg_checksum = gcov_read_unsigned ();
	  function_name = xstrdup (gcov_read_string ());
	  unsigned artificial = gcov_read_unsigned ();
	  unsigned src_idx = find_source (gcov_read_string ());
	  unsigned start_line = gcov_read_unsigned ();
	  unsigned start_column = gcov_read_unsigned ();
	  unsigned end_line = gcov_read_unsigned ();
	  unsigned end_column = gcov_read_unsigned ();

	  fn = new function_info ();

	  fn->m_name = function_name;
	  fn->ident = ident;
	  fn->lineno_checksum = lineno_checksum;
	  fn->cfg_checksum = cfg_checksum;
	  fn->src = src_idx;
	  fn->start_line = start_line;
	  fn->start_column = start_column;
	  fn->end_line = end_line;
	  fn->end_column = end_column;
	  fn->artificial = artificial;

	  current_tag = tag;

	  /* This is separate from flag_demangled_names to support filtering on
	     mangled names while printing demangled names, or filtering on
	     demangled names while printing mangled names.  An independent flag
	     makes sure the function selection does not change even if
	     demangling is turned on/off.  */
	  const char *fname = function_name;
	  if (flag_filter_on_demangled)
	    fname = fn->get_demangled_name ();

	  bool keep = default_keep;
	  for (const fnfilter &fn : filters)
	    if (regexec (&fn.regex, fname, 0, nullptr, 0) == 0)
	      keep = fn.keep;

	  if (keep)
	    {
	      functions.push_back (fn);
	      ident_to_fn[ident] = fn;
	    }
	}
      else if (fn && tag == GCOV_TAG_BLOCKS)
	{
	  if (!fn->blocks.empty ())
	    fnotice (stderr, "%s:already seen blocks for '%s'\n",
		     bbg_file_name, fn->get_name ());
	  else
	    fn->blocks.resize (gcov_read_unsigned ());
	}
      else if (fn && tag == GCOV_TAG_ARCS)
	{
	  unsigned src = gcov_read_unsigned ();
	  fn->blocks[src].id = src;
	  unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
	  block_info *src_blk = &fn->blocks[src];
	  unsigned mark_catches = 0;
	  struct arc_info *arc;

	  if (src >= fn->blocks.size () || fn->blocks[src].succ)
	    goto corrupt;

	  while (num_dests--)
	    {
	      unsigned dest = gcov_read_unsigned ();
	      unsigned flags = gcov_read_unsigned ();

	      if (dest >= fn->blocks.size ())
		goto corrupt;
	      arc = XCNEW (arc_info);

	      arc->dst = &fn->blocks[dest];
	      /* Set id in order to find EXIT_BLOCK.  */
	      arc->dst->id = dest;
	      arc->src = src_blk;

	      arc->count = 0;
	      arc->count_valid = 0;
	      arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
	      arc->fake = !!(flags & GCOV_ARC_FAKE);
	      arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);
	      arc->true_value = !!(flags & GCOV_ARC_TRUE);
	      arc->false_value = !!(flags & GCOV_ARC_FALSE);

	      arc->succ_next = src_blk->succ;
	      src_blk->succ = arc;
	      src_blk->num_succ++;

	      arc->pred_next = fn->blocks[dest].pred;
	      fn->blocks[dest].pred = arc;
	      fn->blocks[dest].num_pred++;

	      if (arc->fake)
		{
		  if (src)
		    {
		      /* Exceptional exit from this function, the
			 source block must be a call.  */
		      fn->blocks[src].is_call_site = 1;
		      arc->is_call_non_return = 1;
		      mark_catches = 1;
		    }
		  else
		    {
		      /* Non-local return from a callee of this
			 function.  The destination block is a setjmp.  */
		      arc->is_nonlocal_return = 1;
		      fn->blocks[dest].is_nonlocal_return = 1;
		    }
		}

	      if (!arc->on_tree)
		fn->counts.push_back (0);
	    }

	  if (mark_catches)
	    {
	      /* We have a fake exit from this block.  The other
		 non-fall through exits must be to catch handlers.
		 Mark them as catch arcs.  */

	      for (arc = src_blk->succ; arc; arc = arc->succ_next)
		if (!arc->fake && !arc->fall_through)
		  {
		    arc->is_throw = 1;
		    fn->has_catch = 1;
		  }
	    }
	}
      else if (fn && tag == GCOV_TAG_CONDS)
	{
	  unsigned num_dests = GCOV_TAG_CONDS_NUM (length);

	  if (!fn->conditions.empty ())
	    fnotice (stderr, "%s:already seen conditions for '%s'\n",
		     bbg_file_name, fn->get_name ());
	  else
	    fn->conditions.resize (num_dests);

	  for (unsigned i = 0; i < num_dests; ++i)
	    {
	      unsigned idx = gcov_read_unsigned ();

	      if (idx >= fn->blocks.size ())
		goto corrupt;

	      condition_info *info = &fn->blocks[idx].conditions;
	      info->n_terms = gcov_read_unsigned ();
	      fn->conditions[i] = info;
	    }
    }
      else if (fn && tag == GCOV_TAG_PATHS)
	{
	  const unsigned npaths = gcov_read_unsigned ();
	  const size_t nbits = path_info::bucketsize;
	  const size_t nbuckets = (npaths + (nbits - 1)) / nbits;
	  fn->paths.covered.assign (nbuckets, 0);
	}
      else if (fn && tag == GCOV_TAG_LINES)
	{
	  unsigned blockno = gcov_read_unsigned ();
	  block_info *block = &fn->blocks[blockno];

	  if (blockno >= fn->blocks.size ())
	    goto corrupt;

	  while (true)
	    {
	      unsigned lineno = gcov_read_unsigned ();

	      if (lineno)
		block->locations.back ().lines.push_back (lineno);
	      else
		{
		  const char *file_name = gcov_read_string ();

		  if (!file_name)
		    break;
		  block->locations.push_back (block_location_info
					      (find_source (file_name)));
		}
	    }
	}
      else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
	{
	  fn = NULL;
	  current_tag = 0;
	}
      gcov_sync (base, length);
      if (gcov_is_error ())
	{
	corrupt:;
	  fnotice (stderr, "%s:corrupted\n", bbg_file_name);
	  return_code = 4;
	  break;
	}
    }
  gcov_close ();

  if (functions.empty ())
    fnotice (stderr, "%s:no functions found\n", bbg_file_name);
}

/* Reads profiles from the count file and attach to each
   function. Return nonzero if fatal error.  */

static int
read_count_file (void)
{
  unsigned ix;
  unsigned version;
  unsigned tag;
  function_info *fn = NULL;
  int error = 0;
  map<unsigned, function_info *>::iterator it;

  if (!gcov_open (da_file_name, 1))
    {
      fnotice (stderr, "%s:cannot open data file, assuming not executed\n",
	       da_file_name);
      no_data_file = 1;
      return 0;
    }
  if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
    {
      fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
      return_code = 2;
    cleanup:;
      gcov_close ();
      return 1;
    }
  version = gcov_read_unsigned ();
  if (version != GCOV_VERSION)
    {
      char v[4], e[4];

      GCOV_UNSIGNED2STRING (v, version);
      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);

      fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
	       da_file_name, v, e);
      return_code = 3;
    }
  tag = gcov_read_unsigned ();
  if (tag != bbg_stamp)
    {
      fnotice (stderr, "%s:stamp mismatch with notes file\n", da_file_name);
      return_code = 5;
      goto cleanup;
    }

  /* Read checksum.  */
  gcov_read_unsigned ();

  while ((tag = gcov_read_unsigned ()))
    {
      unsigned length = gcov_read_unsigned ();
      int read_length = (int)length;
      unsigned long base = gcov_position ();

      if (tag == GCOV_TAG_OBJECT_SUMMARY)
	{
	  struct gcov_summary summary;
	  gcov_read_summary (&summary);
	  object_runs = summary.runs;
	}
      else if (tag == GCOV_TAG_FUNCTION && !length)
	; /* placeholder  */
      else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH)
	{
	  unsigned ident;
	  ident = gcov_read_unsigned ();
	  fn = NULL;
	  it = ident_to_fn.find (ident);
	  if (it != ident_to_fn.end ())
	    fn = it->second;

	  if (!fn)
	    ;
	  else if (gcov_read_unsigned () != fn->lineno_checksum
		   || gcov_read_unsigned () != fn->cfg_checksum)
	    {
	    mismatch:;
	      fnotice (stderr, "%s:profile mismatch for '%s'\n",
		       da_file_name, fn->get_name ());
	      goto cleanup;
	    }
	}
      else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_CONDS) && fn)
	{
	  length = abs (read_length);
	  if (length != GCOV_TAG_COUNTER_LENGTH (2 * fn->conditions.size ()))
	      goto mismatch;

	  if (read_length > 0)
	    {
	      for (ix = 0; ix != fn->conditions.size (); ix++)
		{
		  fn->conditions[ix]->truev  |= gcov_read_counter ();
		  fn->conditions[ix]->falsev |= gcov_read_counter ();
		}
	    }
	}
      else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
	{
	  length = abs (read_length);
	  if (length != GCOV_TAG_COUNTER_LENGTH (fn->counts.size ()))
	    goto mismatch;

	  if (read_length > 0)
	    for (ix = 0; ix != fn->counts.size (); ix++)
	      fn->counts[ix] += gcov_read_counter ();
	}
      else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_PATHS) && fn)
	{
	  vector<gcov_type_unsigned> &covered = fn->paths.covered;
	  length = abs (read_length);
	  if (length != GCOV_TAG_COUNTER_LENGTH (covered.size ()))
	    goto mismatch;

	  if (read_length > 0)
	    for (ix = 0; ix != covered.size (); ix++)
	      covered[ix] = gcov_read_counter ();
	}
      if (read_length < 0)
	read_length = 0;
      gcov_sync (base, read_length);
      if ((error = gcov_is_error ()))
	{
	  fnotice (stderr,
		   error < 0
		   ? N_("%s:overflowed\n")
		   : N_("%s:corrupted\n"),
		   da_file_name);
	  return_code = 4;
	  goto cleanup;
	}
    }

  gcov_close ();
  return 0;
}

/* Solve the flow graph. Propagate counts from the instrumented arcs
   to the blocks and the uninstrumented arcs.  */

static void
solve_flow_graph (function_info *fn)
{
  unsigned ix;
  arc_info *arc;
  gcov_type *count_ptr = &fn->counts.front ();
  block_info *blk;
  block_info *valid_blocks = NULL;    /* valid, but unpropagated blocks.  */
  block_info *invalid_blocks = NULL;  /* invalid, but inferable blocks.  */

  /* The arcs were built in reverse order.  Fix that now.  */
  for (ix = fn->blocks.size (); ix--;)
    {
      arc_info *arc_p, *arc_n;

      for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
	   arc_p = arc, arc = arc_n)
	{
	  arc_n = arc->succ_next;
	  arc->succ_next = arc_p;
	}
      fn->blocks[ix].succ = arc_p;

      for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
	   arc_p = arc, arc = arc_n)
	{
	  arc_n = arc->pred_next;
	  arc->pred_next = arc_p;
	}
      fn->blocks[ix].pred = arc_p;
    }

  if (fn->blocks.size () < 2)
    fnotice (stderr, "%s:'%s' lacks entry and/or exit blocks\n",
	     bbg_file_name, fn->get_name ());
  else
    {
      if (fn->blocks[ENTRY_BLOCK].num_pred)
	fnotice (stderr, "%s:'%s' has arcs to entry block\n",
		 bbg_file_name, fn->get_name ());
      else
	/* We can't deduce the entry block counts from the lack of
	   predecessors.  */
	fn->blocks[ENTRY_BLOCK].num_pred = ~(unsigned)0;

      if (fn->blocks[EXIT_BLOCK].num_succ)
	fnotice (stderr, "%s:'%s' has arcs from exit block\n",
		 bbg_file_name, fn->get_name ());
      else
	/* Likewise, we can't deduce exit block counts from the lack
	   of its successors.  */
	fn->blocks[EXIT_BLOCK].num_succ = ~(unsigned)0;
    }

  /* Propagate the measured counts, this must be done in the same
     order as the code in profile.cc  */
  for (unsigned i = 0; i < fn->blocks.size (); i++)
    {
      blk = &fn->blocks[i];
      block_info const *prev_dst = NULL;
      int out_of_order = 0;
      int non_fake_succ = 0;

      for (arc = blk->succ; arc; arc = arc->succ_next)
	{
	  if (!arc->fake)
	    non_fake_succ++;

	  if (!arc->on_tree)
	    {
	      if (count_ptr)
		arc->count = *count_ptr++;
	      arc->count_valid = 1;
	      blk->num_succ--;
	      arc->dst->num_pred--;
	    }
	  if (prev_dst && prev_dst > arc->dst)
	    out_of_order = 1;
	  prev_dst = arc->dst;
	}
      if (non_fake_succ == 1)
	{
	  /* If there is only one non-fake exit, it is an
	     unconditional branch.  */
	  for (arc = blk->succ; arc; arc = arc->succ_next)
	    if (!arc->fake)
	      {
		arc->is_unconditional = 1;
		/* If this block is instrumenting a call, it might be
		   an artificial block. It is not artificial if it has
		   a non-fallthrough exit, or the destination of this
		   arc has more than one entry.  Mark the destination
		   block as a return site, if none of those conditions
		   hold.  */
		if (blk->is_call_site && arc->fall_through
		    && arc->dst->pred == arc && !arc->pred_next)
		  arc->dst->is_call_return = 1;
	      }
	}

      /* Sort the successor arcs into ascending dst order. profile.cc
	 normally produces arcs in the right order, but sometimes with
	 one or two out of order.  We're not using a particularly
	 smart sort.  */
      if (out_of_order)
	{
	  arc_info *start = blk->succ;
	  unsigned changes = 1;

	  while (changes)
	    {
	      arc_info *arc, *arc_p, *arc_n;

	      changes = 0;
	      for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
		{
		  if (arc->dst > arc_n->dst)
		    {
		      changes = 1;
		      if (arc_p)
			arc_p->succ_next = arc_n;
		      else
			start = arc_n;
		      arc->succ_next = arc_n->succ_next;
		      arc_n->succ_next = arc;
		      arc_p = arc_n;
		    }
		  else
		    {
		      arc_p = arc;
		      arc = arc_n;
		    }
		}
	    }
	  blk->succ = start;
	}

      /* Place it on the invalid chain, it will be ignored if that's
	 wrong.  */
      blk->invalid_chain = 1;
      blk->chain = invalid_blocks;
      invalid_blocks = blk;
    }

  while (invalid_blocks || valid_blocks)
    {
      while ((blk = invalid_blocks))
	{
	  gcov_type total = 0;
	  const arc_info *arc;

	  invalid_blocks = blk->chain;
	  blk->invalid_chain = 0;
	  if (!blk->num_succ)
	    for (arc = blk->succ; arc; arc = arc->succ_next)
	      total += arc->count;
	  else if (!blk->num_pred)
	    for (arc = blk->pred; arc; arc = arc->pred_next)
	      total += arc->count;
	  else
	    continue;

	  blk->count = total;
	  blk->count_valid = 1;
	  blk->chain = valid_blocks;
	  blk->valid_chain = 1;
	  valid_blocks = blk;
	}
      while ((blk = valid_blocks))
	{
	  gcov_type total;
	  arc_info *arc, *inv_arc;

	  valid_blocks = blk->chain;
	  blk->valid_chain = 0;
	  if (blk->num_succ == 1)
	    {
	      block_info *dst;

	      total = blk->count;
	      inv_arc = NULL;
	      for (arc = blk->succ; arc; arc = arc->succ_next)
		{
		  total -= arc->count;
		  if (!arc->count_valid)
		    inv_arc = arc;
		}
	      dst = inv_arc->dst;
	      inv_arc->count_valid = 1;
	      inv_arc->count = total;
	      blk->num_succ--;
	      dst->num_pred--;
	      if (dst->count_valid)
		{
		  if (dst->num_pred == 1 && !dst->valid_chain)
		    {
		      dst->chain = valid_blocks;
		      dst->valid_chain = 1;
		      valid_blocks = dst;
		    }
		}
	      else
		{
		  if (!dst->num_pred && !dst->invalid_chain)
		    {
		      dst->chain = invalid_blocks;
		      dst->invalid_chain = 1;
		      invalid_blocks = dst;
		    }
		}
	    }
	  if (blk->num_pred == 1)
	    {
	      block_info *src;

	      total = blk->count;
	      inv_arc = NULL;
	      for (arc = blk->pred; arc; arc = arc->pred_next)
		{
		  total -= arc->count;
		  if (!arc->count_valid)
		    inv_arc = arc;
		}
	      src = inv_arc->src;
	      inv_arc->count_valid = 1;
	      inv_arc->count = total;
	      blk->num_pred--;
	      src->num_succ--;
	      if (src->count_valid)
		{
		  if (src->num_succ == 1 && !src->valid_chain)
		    {
		      src->chain = valid_blocks;
		      src->valid_chain = 1;
		      valid_blocks = src;
		    }
		}
	      else
		{
		  if (!src->num_succ && !src->invalid_chain)
		    {
		      src->chain = invalid_blocks;
		      src->invalid_chain = 1;
		      invalid_blocks = src;
		    }
		}
	    }
	}
    }

  /* If the graph has been correctly solved, every block will have a
     valid count.  */
  for (unsigned i = 0; ix < fn->blocks.size (); i++)
    if (!fn->blocks[i].count_valid)
      {
	fnotice (stderr, "%s:graph is unsolvable for '%s'\n",
		 bbg_file_name, fn->get_name ());
	break;
      }
}

/* Find the prime paths of the function from the CFG and add to FN
   using the same function as gcc.  It relies on gcc recording the CFG
   faithfully.  Storing the paths explicitly takes up way too much
   space to be practical, but this means we need to recompute the
   (exact) same paths in gcov.  This should give paths in
   lexicographical order so that the nth path in gcc is the nth path
   in gcov.  ENTRY_BLOCK and EXIT_BLOCK are both removed from all
   paths.  */
static void
find_prime_paths (function_info *fn)
{
  if (!flag_prime_paths)
    return;

  /* If paths.covered being empty then this function was not
     instrumented, probably because it exceeded #-of-paths limit.  In
     this case we don't want to find the prime paths as it will take
     too long, and covered paths are not measured.  */
  if (fn->paths.covered.empty ())
    return;

  struct graph *cfg = new_graph (fn->blocks.size ());
  for (block_info &block : fn->blocks)
    {
      cfg->vertices[block.id].data = &block;
      for (arc_info *arc = block.succ; arc; arc = arc->succ_next)
	if (!arc->fake)
	  add_edge (cfg, arc->src->id, arc->dst->id)->data = arc;
    }

  vec<vec<int>> prime_paths (struct graph*, size_t);
  /* TODO: Pass extra information in the PATH_TAG section.  In case
     that is empty this might still need to be tunable should the
     coverage be requested without instrumentation.  */
  vec<vec<int>> paths = prime_paths (cfg, (size_t)-1);
  fn->paths.paths.reserve (paths.length ());
  for (vec<int> &path : paths)
    {
      const int *begin = path.begin ();
      const int *end = path.end ();
      if (begin != end && path.last () == EXIT_BLOCK)
	--end;
      if (begin != end && *begin == ENTRY_BLOCK)
	++begin;

      if (begin == end)
	continue;

      /* If this is an isolated vertex because abnormal edges and fake
	 edges are removed, don't include it.  */
      if (end - begin == 1 && !cfg->vertices[*begin].succ
	  && !cfg->vertices[*begin].pred)
	continue;

      fn->paths.paths.emplace_back (begin, end);
    }

  release_vec_vec (paths);
  free_graph (cfg);
}

/* Mark all the blocks only reachable via an incoming catch.  */

static void
find_exception_blocks (function_info *fn)
{
  unsigned ix;
  block_info **queue = XALLOCAVEC (block_info *, fn->blocks.size ());

  /* First mark all blocks as exceptional.  */
  for (ix = fn->blocks.size (); ix--;)
    fn->blocks[ix].exceptional = 1;

  /* Now mark all the blocks reachable via non-fake edges */
  queue[0] = &fn->blocks[0];
  queue[0]->exceptional = 0;
  for (ix = 1; ix;)
    {
      block_info *block = queue[--ix];
      const arc_info *arc;

      for (arc = block->succ; arc; arc = arc->succ_next)
	if (!arc->fake && !arc->is_throw && arc->dst->exceptional)
	  {
	    arc->dst->exceptional = 0;
	    queue[ix++] = arc->dst;
	  }
    }
}


/* Increment totals in COVERAGE according to arc ARC.  */

static void
add_branch_counts (coverage_info *coverage, const arc_info *arc)
{
  if (arc->is_call_non_return)
    {
      coverage->calls++;
      if (arc->src->count)
	coverage->calls_executed++;
    }
  else if (!arc->is_unconditional)
    {
      coverage->branches++;
      if (arc->src->count)
	coverage->branches_executed++;
      if (arc->count)
	coverage->branches_taken++;
    }
}

/* Increment totals in COVERAGE according to block BLOCK.  */

static void
add_condition_counts (coverage_info *coverage, const block_info *block)
{
  coverage->conditions += 2 * block->conditions.n_terms;
  coverage->conditions_covered += block->conditions.popcount ();
}

/* Increment path totals, number of paths and number of covered paths,
   in COVERAGE according to FN.  */

static void
add_path_counts (coverage_info &coverage, const function_info &fn)
{
  coverage.paths += fn.paths.paths.size ();
  coverage.paths_covered += fn.paths.covered_paths ();
}

/* Format COUNT, if flag_human_readable_numbers is set, return it human
   readable format.  */

static char const *
format_count (gcov_type count)
{
  static char buffer[64];
  const char *units = " kMGTPEZY";

  if (count < 1000 || !flag_human_readable_numbers)
    {
      sprintf (buffer, "%" PRId64, count);
      return buffer;
    }

  unsigned i;
  gcov_type divisor = 1;
  for (i = 0; units[i+1]; i++, divisor *= 1000)
    {
      if (count + divisor / 2 < 1000 * divisor)
	break;
    }
  float r = 1.0f * count / divisor;
  sprintf (buffer, "%.1f%c", r, units[i]);
  return buffer;
}

/* Format a GCOV_TYPE integer as either a percent ratio, or absolute
   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 decimal_places)
{
  static char buffer[20];

  if (decimal_places >= 0)
    {
      float ratio = bottom ? 100.0f * top / bottom : 0;

      /* 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);

  return buffer;
}

/* Summary of execution */

static void
executed_summary (unsigned lines, unsigned executed)
{
  if (lines)
    fnotice (stdout, "Lines executed:%s of %d\n",
	     format_gcov (executed, lines, 2), lines);
  else
    fnotice (stdout, "No executable lines\n");
}

/* Output summary info for a function.  */

static void
function_summary (const coverage_info *coverage)
{
  fnotice (stdout, "%s '%s'\n", "Function", coverage->name);
  executed_summary (coverage->lines, coverage->lines_executed);

  if (coverage->branches)
    {
      fnotice (stdout, "Branches executed:%s of %d\n",
	       format_gcov (coverage->branches_executed, coverage->branches, 2),
	       coverage->branches);
      fnotice (stdout, "Taken at least once:%s of %d\n",
	       format_gcov (coverage->branches_taken, coverage->branches, 2),
			    coverage->branches);
    }
  else
    fnotice (stdout, "No branches\n");

  if (coverage->calls)
    fnotice (stdout, "Calls executed:%s of %d\n",
	     format_gcov (coverage->calls_executed, coverage->calls, 2),
	     coverage->calls);
  else
    fnotice (stdout, "No calls\n");

  if (flag_conditions)
    {
      if (coverage->conditions)
	fnotice (stdout, "Condition outcomes covered:%s of %d\n",
		 format_gcov (coverage->conditions_covered,
			      coverage->conditions, 2),
		 coverage->conditions);
      else
	fnotice (stdout, "No conditions\n");
    }

  if (flag_prime_paths)
    {
      if (coverage->paths)
	fnotice (stdout, "Prime paths covered:%s of %d\n",
		 format_gcov (coverage->paths_covered, coverage->paths, 2),
			      coverage->paths);
      else
	fnotice (stdout, "No path information\n");
    }
}

/* Output summary info for a file.  */

static void
file_summary (const coverage_info *coverage)
{
  fnotice (stdout, "%s '%s'\n", "File", coverage->name);
  executed_summary (coverage->lines, coverage->lines_executed);

  if (flag_branches)
    {
      if (coverage->branches)
	{
	  fnotice (stdout, "Branches executed:%s of %d\n",
		   format_gcov (coverage->branches_executed,
				coverage->branches, 2),
		   coverage->branches);
	  fnotice (stdout, "Taken at least once:%s of %d\n",
		   format_gcov (coverage->branches_taken,
				coverage->branches, 2),
		   coverage->branches);
	}
      else
	fnotice (stdout, "No branches\n");
      if (coverage->calls)
	fnotice (stdout, "Calls executed:%s of %d\n",
		 format_gcov (coverage->calls_executed, coverage->calls, 2),
		 coverage->calls);
      else
	fnotice (stdout, "No calls\n");

    }

  if (flag_conditions)
    {
      if (coverage->conditions)
	fnotice (stdout, "Condition outcomes covered:%s of %d\n",
		 format_gcov (coverage->conditions_covered,
			      coverage->conditions, 2),
		 coverage->conditions);
      else
	fnotice (stdout, "No conditions\n");
    }

  if (flag_prime_paths)
    {
      if (coverage->paths)
	fnotice (stdout, "Prime paths covered:%s of %d\n",
		 format_gcov (coverage->paths_covered, coverage->paths, 2),
			      coverage->paths);
      else
	fnotice (stdout, "No path information\n");
    }
}

/* Canonicalize the filename NAME by canonicalizing directory
   separators, eliding . components and resolving .. components
   appropriately.  Always returns a unique string.  */

static char *
canonicalize_name (const char *name)
{
  /* The canonical name cannot be longer than the incoming name.  */
  char *result = XNEWVEC (char, strlen (name) + 1);
  const char *base = name, *probe;
  char *ptr = result;
  char *dd_base;
  int slash = 0;

#if HAVE_DOS_BASED_FILE_SYSTEM
  if (base[0] && base[1] == ':')
    {
      result[0] = base[0];
      result[1] = ':';
      base += 2;
      ptr += 2;
    }
#endif
  for (dd_base = ptr; *base; base = probe)
    {
      size_t len;

      for (probe = base; *probe; probe++)
	if (IS_DIR_SEPARATOR (*probe))
	  break;

      len = probe - base;
      if (len == 1 && base[0] == '.')
	/* Elide a '.' directory */
	;
      else if (len == 2 && base[0] == '.' && base[1] == '.')
	{
	  /* '..', we can only elide it and the previous directory, if
	     we're not a symlink.  */
	  struct stat ATTRIBUTE_UNUSED buf;

	  *ptr = 0;
	  if (dd_base == ptr
#if defined (S_ISLNK)
	      /* S_ISLNK is not POSIX.1-1996.  */
	      || stat (result, &buf) || S_ISLNK (buf.st_mode)
#endif
		)
	    {
	      /* Cannot elide, or unreadable or a symlink.  */
	      dd_base = ptr + 2 + slash;
	      goto regular;
	    }
	  while (ptr != dd_base && *ptr != '/')
	    ptr--;
	  slash = ptr != result;
	}
      else
	{
	regular:
	  /* Regular pathname component.  */
	  if (slash)
	    *ptr++ = '/';
	  memcpy (ptr, base, len);
	  ptr += len;
	  slash = 1;
	}

      for (; IS_DIR_SEPARATOR (*probe); probe++)
	continue;
    }
  *ptr = 0;

  return result;
}

/* Generate an output file name. INPUT_NAME is the canonicalized main
   input file and SRC_NAME is the canonicalized file name.
   LONG_OUTPUT_NAMES and PRESERVE_PATHS affect name generation.  With
   long_output_names we prepend the processed name of the input file
   to each output name (except when the current source file is the
   input file, so you don't get a double concatenation). The two
   components are separated by '##'.  With preserve_paths we create a
   filename from all path components of the source file, replacing '/'
   with '#', and .. with '^', without it we simply take the basename
   component.  (Remember, the canonicalized name will already have
   elided '.' components and converted \\ separators.)  */

static string
make_gcov_file_name (const char *input_name, const char *src_name)
{
  string str;

  /* When hashing filenames, we shorten them by only using the filename
     component and appending a hash of the full (mangled) pathname.  */
  if (flag_hash_filenames)
    str = (string (mangle_name (src_name)) + "##"
	   + get_md5sum (src_name) + ".gcov");
  else
    {
      if (flag_long_names && input_name && strcmp (src_name, input_name) != 0)
	{
	  str += mangle_name (input_name);
	  str += "##";
	}

      str += mangle_name (src_name);
      str += ".gcov";
    }

  return str;
}

/* Mangle BASE name, copy it at the beginning of PTR buffer and
   return address of the \0 character of the buffer.  */

static char *
mangle_name (char const *base)
{
  /* Generate the source filename part.  */
  if (!flag_preserve_paths)
    return xstrdup (lbasename (base));
  else
    return mangle_path (base);
}

/* Scan through the bb_data for each line in the block, increment
   the line number execution count indicated by the execution count of
   the appropriate basic block.  */

static void
add_line_counts (coverage_info *coverage, function_info *fn)
{
  bool has_any_line = false;
  /* Scan each basic block.  */
  for (unsigned ix = 0; ix != fn->blocks.size (); ix++)
    {
      line_info *line = NULL;
      block_info *block = &fn->blocks[ix];
      if (block->count && ix && ix + 1 != fn->blocks.size ())
	fn->blocks_executed++;
      for (unsigned i = 0; i < block->locations.size (); i++)
	{
	  unsigned src_idx = block->locations[i].source_file_idx;
	  vector<unsigned> &lines = block->locations[i].lines;

	  block->cycle.arc = NULL;
	  block->cycle.ident = ~0U;

	  for (unsigned j = 0; j < lines.size (); j++)
	    {
	      unsigned ln = lines[j];

	      /* Line belongs to a function that is in a group.  */
	      if (fn->group_line_p (ln, src_idx))
		{
		  gcc_assert (lines[j] - fn->start_line < fn->lines.size ());
		  line = &(fn->lines[lines[j] - fn->start_line]);
		  if (coverage)
		    {
		      if (!line->exists)
			coverage->lines++;
		      if (!line->count && block->count)
			coverage->lines_executed++;
		    }
		  line->exists = 1;
		  if (!block->exceptional)
		    {
		      line->unexceptional = 1;
		      if (block->count == 0)
			line->has_unexecuted_block = 1;
		    }
		  line->count += block->count;
		}
	      else
		{
		  gcc_assert (ln < sources[src_idx].lines.size ());
		  line = &(sources[src_idx].lines[ln]);
		  if (coverage)
		    {
		      if (!line->exists)
			coverage->lines++;
		      if (!line->count && block->count)
			coverage->lines_executed++;
		    }
		  line->exists = 1;
		  if (!block->exceptional)
		    {
		      line->unexceptional = 1;
		      if (block->count == 0)
			line->has_unexecuted_block = 1;
		    }
		  line->count += block->count;
		}
	    }

	  has_any_line = true;

	  if (!ix || ix + 1 == fn->blocks.size ())
	    /* Entry or exit block.  */;
	  else if (line != NULL)
	    {
	      line->blocks.push_back (block);

	      if (flag_branches)
		{
		  arc_info *arc;

		  for (arc = block->succ; arc; arc = arc->succ_next)
		    line->branches.push_back (arc);
		}
	    }
	}
    }

  if (!has_any_line)
    fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name,
	     fn->get_name ());
}

/* Accumulate info for LINE that belongs to SRC source file.  If ADD_COVERAGE
   is set to true, update source file summary.  */

static void accumulate_line_info (line_info *line, source_info *src,
				  bool add_coverage)
{
  if (add_coverage)
    for (vector<arc_info *>::iterator it = line->branches.begin ();
	 it != line->branches.end (); it++)
      add_branch_counts (&src->coverage, *it);

  if (add_coverage)
    for (vector<block_info *>::iterator it = line->blocks.begin ();
	 it != line->blocks.end (); it++)
      add_condition_counts (&src->coverage, *it);


  if (!line->blocks.empty ())
    {
      /* The user expects the line count to be the number of times
	 a line has been executed.  Simply summing the block count
	 will give an artificially high number.  The Right Thing
	 is to sum the entry counts to the graph of blocks on this
	 line, then find the elementary cycles of the local graph
	 and add the transition counts of those cycles.  */
      gcov_type count = 0;

      /* Cycle detection.  */
      for (vector<block_info *>::iterator it = line->blocks.begin ();
	   it != line->blocks.end (); it++)
	{
	  for (arc_info *arc = (*it)->pred; arc; arc = arc->pred_next)
	    if (!line->has_block (arc->src))
	      count += arc->count;
	  for (arc_info *arc = (*it)->succ; arc; arc = arc->succ_next)
	    arc->cs_count = arc->count;
	}

      /* Now, add the count of loops entirely on this line.  */
      count += get_cycles_count (*line);
      line->count = count;

      if (line->count > src->maximum_count)
	src->maximum_count = line->count;
    }

  if (line->exists && add_coverage)
    {
      src->coverage.lines++;
      if (line->count)
	src->coverage.lines_executed++;
    }
}

/* Accumulate the line counts of a file.  */

static void
accumulate_line_counts (source_info *src)
{
  /* First work on group functions.  */
  for (vector<function_info *>::iterator it = src->functions.begin ();
       it != src->functions.end (); it++)
    {
      function_info *fn = *it;

      if (fn->src != src->index || !fn->is_group)
	continue;

      for (vector<line_info>::iterator it2 = fn->lines.begin ();
	   it2 != fn->lines.end (); it2++)
	  {
	    line_info *line = &(*it2);
	    accumulate_line_info (line, src, true);
	  }
    }

  /* Work on global lines that line in source file SRC.  */
  for (vector<line_info>::iterator it = src->lines.begin ();
       it != src->lines.end (); it++)
    accumulate_line_info (&(*it), src, true);

  /* If not using intermediate mode, sum lines of group functions and
     add them to lines that live in a source file.  */
  if (!flag_json_format)
    for (vector<function_info *>::iterator it = src->functions.begin ();
	 it != src->functions.end (); it++)
      {
	function_info *fn = *it;

	if (fn->src != src->index || !fn->is_group)
	  continue;

	for (unsigned i = 0; i < fn->lines.size (); i++)
	  {
	    line_info *fn_line = &fn->lines[i];
	    if (fn_line->exists)
	      {
		unsigned ln = fn->start_line + i;
		line_info *src_line = &src->lines[ln];

		if (!src_line->exists)
		  src->coverage.lines++;
		if (!src_line->count && fn_line->count)
		  src->coverage.lines_executed++;

		src_line->count += fn_line->count;
		src_line->exists = 1;

		if (fn_line->has_unexecuted_block)
		  src_line->has_unexecuted_block = 1;

		if (fn_line->unexceptional)
		  src_line->unexceptional = 1;
	      }
	  }
      }
}

/* Output information about the conditions in block BINFO.  The output includes
 * a summary (n/m outcomes covered) and a list of the missing (uncovered)
 * outcomes.  */

static void
output_conditions (FILE *gcov_file, const block_info *binfo)
{
    const condition_info& info = binfo->conditions;
    if (info.n_terms == 0)
	return;

    const int expected = 2 * info.n_terms;
    const int got = info.popcount ();

    fnotice (gcov_file, "condition outcomes covered %d/%d\n", got, expected);
    if (expected == got)
	return;

    for (unsigned i = 0; i < info.n_terms; i++)
    {
	gcov_type_unsigned index = 1;
	index <<= i;
	if ((index & info.truev & info.falsev))
	    continue;

	const char *t = (index & info.truev) ? "" : "true";
	const char *f = (index & info.falsev) ? "" : " false";
	fnotice (gcov_file, "condition %2u not covered (%s%s)\n", i, t, f + !t[0]);
    }
}

/* Output information about ARC number IX.  Returns nonzero if
   anything is output.  */

static int
output_branch_count (FILE *gcov_file, int ix, const arc_info *arc)
{
  if (arc->is_call_non_return)
    {
      if (arc->src->count)
	{
	  fnotice (gcov_file, "call   %2d returned %s\n", ix,
		   format_gcov (arc->src->count - arc->count,
				arc->src->count, -flag_counts));
	}
      else
	fnotice (gcov_file, "call   %2d never executed\n", ix);
    }
  else if (!arc->is_unconditional)
    {
      if (arc->src->count)
	fnotice (gcov_file, "branch %2d taken %s%s", ix,
		 format_gcov (arc->count, arc->src->count, -flag_counts),
		 arc->fall_through ? " (fallthrough)"
		 : arc->is_throw ? " (throw)" : "");
      else
	fnotice (gcov_file, "branch %2d never executed%s", ix,
		 (arc->fall_through ? " (fallthrough)"
		  : arc->is_throw ? " (throw)" : ""));

      if (flag_verbose)
	fnotice (gcov_file, " (BB %d)", arc->dst->id);

      fnotice (gcov_file, "\n");
    }
  else if (flag_unconditional && !arc->dst->is_call_return)
    {
      if (arc->src->count)
	fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
		 format_gcov (arc->count, arc->src->count, -flag_counts));
      else
	fnotice (gcov_file, "unconditional %2d never executed\n", ix);
    }
  else
    return 0;
  return 1;
}

static void
print_source_line (FILE *f, const vector<const char *> &source_lines,
		   unsigned line);


/* Print a dense coverage report for PATH of FN to GCOV_FILE.  PATH should be
   number PATHNO in the sorted set of paths.  This function prints a dense form
   where only the line numbers, and optionally the source file the line comes
   from, in the order they need to be executed to achieve coverage.  This
   produces very long lines for large functions, but is a useful and greppable
   output.

   Returns 1 if the path was printed, 0 otherwise.  */
static unsigned
print_prime_path_lines (FILE *gcov_file, const function_info &fn,
			const vector<unsigned> &path, unsigned pathno)
{
  const bool is_covered = fn.paths.covered_p (pathno);
  if (is_covered && !flag_prime_paths_lines_covered)
    return 0;
  if (!is_covered && !flag_prime_paths_lines_uncovered)
    return 0;

  if (is_covered)
    fprintf (gcov_file, "path %u covered: lines", pathno);
  else
    fprintf (gcov_file, "path %u not covered: lines", pathno);

  for (size_t k = 0; k != path.size (); ++k)
    {
      const block_info &block = fn.blocks[path[k]];
      const char *edge_kind = "";
      if (k + 1 != path.size ())
	{
	  gcc_checking_assert (block.id == path[k]);
	  const arc_info &arc = find_arc (block, path[k+1]);
	  if (arc.true_value)
	    edge_kind = "(true)";
	  else if (arc.false_value)
	    edge_kind = "(false)";
	  else if (arc.is_throw)
	    edge_kind = "(throw)";
	}

      for (const block_location_info &loc : block.locations)
	{
	  /* loc.lines could be empty when a statement is not anchored to a
	     source file -- see g++.dg/gcov/gcov-23.C.  Since there is no
	     actual source line to list anyway we can skip this location.  */
	  if (loc.lines.empty ())
	    continue;
	  if (loc.source_file_idx == fn.src)
	    fprintf (gcov_file, " %u%s", loc.lines.back (), edge_kind);
	  else
	    fprintf (gcov_file, " %s:%u%s", sources[loc.source_file_idx].name,
		     loc.lines.back (), edge_kind);
	}
    }

  fprintf (gcov_file, "\n");
  return 1;
}

static unsigned
print_inlined_separator (FILE *gcov_file, unsigned current_index, const
			 block_location_info &loc, const function_info &fn)
{
  if (loc.source_file_idx != current_index && loc.source_file_idx == fn.src)
    fprintf (gcov_file, "------------------\n");
  if (loc.source_file_idx != current_index && loc.source_file_idx != fn.src)
    fprintf (gcov_file, "== inlined from %s ==\n",
	     sources[loc.source_file_idx].name);
  return loc.source_file_idx;
}

/* Print a coverage report for PATH of FN to GCOV_FILE.  PATH should be number
   PATHNO in the sorted set of paths.  This function prints the lines that need
   to be executed (and in what order) to cover it.

   Returns 1 if the path was printed, 0 otherwise.  */
static unsigned
print_prime_path_source (FILE *gcov_file, const function_info &fn,
			 const vector<unsigned> &path, unsigned pathno)
{
  const bool is_covered = fn.paths.covered_p (pathno);
  if (is_covered && !flag_prime_paths_source_covered)
    return 0;
  if (!is_covered && !flag_prime_paths_source_uncovered)
    return 0;

  if (is_covered)
    fprintf (gcov_file, "path %u covered:\n", pathno);
  else
    fprintf (gcov_file, "path %u not covered:\n", pathno);
  unsigned current = fn.src;
  for (size_t k = 0; k != path.size (); ++k)
    {
      const unsigned bb = path[k];
      const block_info &block = fn.blocks[bb];
      gcc_checking_assert (block.id == bb);

      const char *edge_kind = "";
      if (k + 1 != path.size ())
	{
	  const arc_info &arc = find_arc (block, path[k+1]);
	  if (arc.true_value)
	    edge_kind = "(true)";
	  else if (arc.false_value)
	    edge_kind = "(false)";
	  else if (arc.is_throw)
	    edge_kind = "(throw)";
	}

      for (const block_location_info &loc : block.locations)
	{
	  /* loc.lines could be empty when a statement is not anchored to a
	     source file -- see g++.dg/gcov/gcov-24.C.  Since there is no
	     actual source line to list anyway we can skip this location.  */
	  if (loc.lines.empty ())
	    continue;
	  const source_info &src = sources[loc.source_file_idx];
	  const vector<const char *> &lines = slurp (src, gcov_file, "");
	  current = print_inlined_separator (gcov_file, current, loc, fn);
	  for (unsigned i = 0; i != loc.lines.size () - 1; ++i)
	    {
	      const unsigned line = loc.lines[i];
	      fprintf (gcov_file, "BB %2d: %-7s %3d", bb, "", line);
	      print_source_line (gcov_file, lines, line);
	    }

	  const unsigned line = loc.lines.back ();
	  fprintf (gcov_file, "BB %2d: %-7s %3d", bb, edge_kind, line);
	  print_source_line (gcov_file, lines, line);
	}
    }

  fputc ('\n', gcov_file);
  return 1;
}

/* Print path coverage counts for FN to GCOV_FILE.  LINES is the vector of
   source lines for FN.  Note that unlike statements, branch counts, and
   conditions, this is not anchored to source lines but the function root.  */
static int
output_path_coverage (FILE *gcov_file, const function_info *fn)
{
  if (!flag_prime_paths)
    return 0;

  if (fn->paths.paths.empty ())
    fnotice (gcov_file, "path coverage omitted\n");
  else
    fnotice (gcov_file, "paths covered %u of " HOST_SIZE_T_PRINT_UNSIGNED "\n",
	     fn->paths.covered_paths (), (fmt_size_t)fn->paths.paths.size ());

  if (flag_prime_paths_lines_uncovered || flag_prime_paths_lines_covered)
    {
      unsigned pathno = 0;
      for (const vector<unsigned> &path : fn->paths.paths)
	print_prime_path_lines (gcov_file, *fn, path, pathno++);
    }

  if (flag_prime_paths_source_uncovered || flag_prime_paths_source_covered)
    {
      unsigned pathno = 0;
      for (const vector<unsigned> &path : fn->paths.paths)
	print_prime_path_source (gcov_file, *fn, path, pathno++);
    }
  return 1;
}

static const char *
read_line (FILE *file)
{
  static char *string;
  static size_t string_len;
  size_t pos = 0;

  if (!string_len)
    {
      string_len = 200;
      string = XNEWVEC (char, string_len);
    }

  while (fgets (string + pos, string_len - pos, file))
    {
      size_t len = strlen (string + pos);

      if (len && string[pos + len - 1] == '\n')
	{
	  string[pos + len - 1] = 0;
	  return string;
	}
      pos += len;
      /* If the file contains NUL characters or an incomplete
	 last line, which can happen more than once in one run,
	 we have to avoid doubling the STRING_LEN unnecessarily.  */
      if (pos > string_len / 2)
	{
	  string_len *= 2;
	  string = XRESIZEVEC (char, string, string_len);
	}
    }

  return pos ? string : NULL;
}

/* Get the vector with the contents SRC, possibly from a cache.  If
   the reading fails, a message prefixed with LINE_START is written to
   GCOV_FILE.  */
static const vector<const char *>&
slurp (const source_info &src, FILE *gcov_file,
       const char *line_start)
{
  if (source_lines.size () <= src.index)
    source_lines.resize (src.index + 1);

  /* Store vector pointers so that the returned references remain
     stable and won't be broken by successive calls to slurp.  */
  if (!source_lines[src.index])
    source_lines[src.index] = new vector<const char *> ();

  if (!source_lines[src.index]->empty ())
    return *source_lines[src.index];

  FILE *source_file = fopen (src.name, "r");
  if (!source_file)
    fnotice (stderr, "Cannot open source file %s\n", src.name);
  else if (src.file_time == 0)
    fprintf (gcov_file, "%sSource is newer than graph\n", line_start);

  const char *retval;
  vector<const char *> &lines = *source_lines[src.index];
  if (source_file)
    while ((retval = read_line (source_file)))
      lines.push_back (xstrdup (retval));

  if (source_file)
    fclose (source_file);
  return lines;
}

/* Pad string S with spaces from left to have total width equal to 9.  */

static void
pad_count_string (string &s)
{
  if (s.size () < 9)
    s.insert (0, 9 - s.size (), ' ');
}

/* Print GCOV line beginning to F stream.  If EXISTS is set to true, the
   line exists in source file.  UNEXCEPTIONAL indicated that it's not in
   an exceptional statement.  The output is printed for LINE_NUM of given
   COUNT of executions.  EXCEPTIONAL_STRING and UNEXCEPTIONAL_STRING are
   used to indicate non-executed blocks.  */

static void
output_line_beginning (FILE *f, bool exists, bool unexceptional,
		       bool has_unexecuted_block,
		       gcov_type count, unsigned line_num,
		       const char *exceptional_string,
		       const char *unexceptional_string,
		       unsigned int maximum_count)
{
  string s;
  if (exists)
    {
      if (count > 0)
	{
	  s = format_gcov (count, 0, -1);
	  if (has_unexecuted_block
	      && bbg_supports_has_unexecuted_blocks)
	    {
	      if (flag_use_colors)
		{
		  pad_count_string (s);
		  s.insert (0, SGR_SEQ (COLOR_BG_MAGENTA
					COLOR_SEPARATOR COLOR_FG_WHITE));
		  s += SGR_RESET;
		}
	      else
		s += "*";
	    }
	  pad_count_string (s);
	}
      else
	{
	  if (flag_use_colors)
	    {
	      s = "0";
	      pad_count_string (s);
	      if (unexceptional)
		s.insert (0, SGR_SEQ (COLOR_BG_RED
				      COLOR_SEPARATOR COLOR_FG_WHITE));
	      else
		s.insert (0, SGR_SEQ (COLOR_BG_CYAN
				      COLOR_SEPARATOR COLOR_FG_WHITE));
	      s += SGR_RESET;
	    }
	  else
	    {
	      s = unexceptional ? unexceptional_string : exceptional_string;
	      pad_count_string (s);
	    }
	}
    }
  else
    {
      s = "-";
      pad_count_string (s);
    }

  /* Format line number in output.  */
  char buffer[16];
  sprintf (buffer, "%5u", line_num);
  string linestr (buffer);

  if (flag_use_hotness_colors && maximum_count)
    {
      if (count * 2 > maximum_count) /* > 50%.  */
	linestr.insert (0, SGR_SEQ (COLOR_BG_RED));
      else if (count * 5 > maximum_count) /* > 20%.  */
	linestr.insert (0, SGR_SEQ (COLOR_BG_YELLOW));
      else if (count * 10 > maximum_count) /* > 10%.  */
	linestr.insert (0, SGR_SEQ (COLOR_BG_GREEN));
      linestr += SGR_RESET;
    }

  fprintf (f, "%s:%s", s.c_str (), linestr.c_str ());
}

static void
print_source_line (FILE *f, const vector<const char *> &source_lines,
		   unsigned line)
{
  gcc_assert (line >= 1);
  gcc_assert (line <= source_lines.size ());

  fprintf (f, ":%s\n", source_lines[line - 1]);
}

/* Output line details for LINE and print it to F file.  LINE lives on
   LINE_NUM.  */

static void
output_line_details (FILE *f, const line_info *line, unsigned line_num)
{
  if (flag_all_blocks)
    {
      arc_info *arc;
      int jx = 0;
      for (vector<block_info *>::const_iterator it = line->blocks.begin ();
	   it != line->blocks.end (); it++)
	{
	  if (!(*it)->is_call_return)
	    {
	      output_line_beginning (f, line->exists,
				     (*it)->exceptional, false,
				     (*it)->count, line_num,
				     "%%%%%", "$$$$$", 0);
	      fprintf (f, "-block %d", (*it)->id);
	      if (flag_verbose)
		fprintf (f, " (BB %u)", (*it)->id);
	      fprintf (f, "\n");
	    }
	  if (flag_branches)
	    for (arc = (*it)->succ; arc; arc = arc->succ_next)
	      jx += output_branch_count (f, jx, arc);

	  if (flag_conditions)
	      output_conditions (f, *it);
	}
    }
  else
    {
      if (flag_branches)
	{
	  int ix;

	  ix = 0;
	  for (vector<arc_info *>::const_iterator it = line->branches.begin ();
		  it != line->branches.end (); it++)
	      ix += output_branch_count (f, ix, (*it));
	}

      if (flag_conditions)
	{
	  for (vector<block_info *>::const_iterator it = line->blocks.begin ();
	       it != line->blocks.end (); it++)
	      output_conditions (f, *it);
	}
    }
}

/* Output detail statistics about function FN to file F.  */

static void
output_function_details (FILE *f, function_info *fn)
{
  if (!flag_branches)
    return;

  arc_info *arc = fn->blocks[EXIT_BLOCK].pred;
  gcov_type return_count = fn->blocks[EXIT_BLOCK].count;
  gcov_type called_count = fn->blocks[ENTRY_BLOCK].count;

  for (; arc; arc = arc->pred_next)
    if (arc->fake)
      return_count -= arc->count;

  fprintf (f, "function %s", fn->get_name ());
  fprintf (f, " called %s",
	   format_gcov (called_count, 0, -1));
  fprintf (f, " returned %s",
	   format_gcov (return_count, called_count, 0));
  fprintf (f, " blocks executed %s",
	   format_gcov (fn->blocks_executed, fn->get_block_count (), 0));
  fprintf (f, "\n");
}

/* Read in the source file one line at a time, and output that line to
   the gcov file preceded by its execution count and other
   information.  */

static void
output_lines (FILE *gcov_file, const source_info *src)
{
#define  DEFAULT_LINE_START "        -:    0:"
#define FN_SEPARATOR "------------------\n"

  /* Print colorization legend.  */
  if (flag_use_colors)
    fprintf (gcov_file, "%s",
	     DEFAULT_LINE_START "Colorization: profile count: " \
	     SGR_SEQ (COLOR_BG_CYAN) "zero coverage (exceptional)" SGR_RESET \
	     " " \
	     SGR_SEQ (COLOR_BG_RED) "zero coverage (unexceptional)" SGR_RESET \
	     " " \
	     SGR_SEQ (COLOR_BG_MAGENTA) "unexecuted block" SGR_RESET "\n");

  if (flag_use_hotness_colors)
    fprintf (gcov_file, "%s",
	     DEFAULT_LINE_START "Colorization: line numbers: hotness: " \
	     SGR_SEQ (COLOR_BG_RED) "> 50%" SGR_RESET " " \
	     SGR_SEQ (COLOR_BG_YELLOW) "> 20%" SGR_RESET " " \
	     SGR_SEQ (COLOR_BG_GREEN) "> 10%" SGR_RESET "\n");

  fprintf (gcov_file, DEFAULT_LINE_START "Source:%s\n", src->coverage.name);
  if (!multiple_files)
    {
      fprintf (gcov_file, DEFAULT_LINE_START "Graph:%s\n", bbg_file_name);
      fprintf (gcov_file, DEFAULT_LINE_START "Data:%s\n",
	       no_data_file ? "-" : da_file_name);
      fprintf (gcov_file, DEFAULT_LINE_START "Runs:%u\n", object_runs);
    }

  const vector<const char *> &source_lines = slurp (*src, gcov_file,
						    DEFAULT_LINE_START);
  unsigned line_start_group = 0;
  vector<function_info *> *fns;
  unsigned filtered_line_end = !filters.empty () ? 0 : source_lines.size ();

  for (unsigned line_num = 1; line_num <= source_lines.size (); line_num++)
    {
      if (line_num >= src->lines.size ())
	{
	  /* If the src->lines is truncated because the rest of the functions
	     are filtered out we must stop here, and not fall back to printing
	     the rest of the file.  */
	  if (!filters.empty ())
	    break;
	  fprintf (gcov_file, "%9s:%5u", "-", line_num);
	  print_source_line (gcov_file, source_lines, line_num);
	  continue;
	}

      const line_info *line = &src->lines[line_num];

      if (line_start_group == 0)
	{
	  fns = src->get_functions_at_location (line_num);
	  if (fns != NULL && fns->size () > 1)
	    {
	      /* It's possible to have functions that partially overlap,
		 thus take the maximum end_line of functions starting
		 at LINE_NUM.  */
	      for (unsigned i = 0; i < fns->size (); i++)
		if ((*fns)[i]->end_line > line_start_group)
		  line_start_group = (*fns)[i]->end_line;

	      /* When filtering, src->lines will be cut short for the last
		 selected function.  To make sure the "overlapping function"
		 section is printed too, adjust the end so that it is within
		 src->lines.  */
	      if (line_start_group >= src->lines.size ())
		line_start_group = src->lines.size () - 1;

	      if (!filters.empty ())
		filtered_line_end = line_start_group;
	    }
	  else if (fns != NULL && fns->size () == 1)
	    {
	      function_info *fn = (*fns)[0];
	      output_function_details (gcov_file, fn);
	      output_path_coverage (gcov_file, fn);

	      /* If functions are filtered, only the matching functions will be in
		 fns and there is no need for extra checking.  */
	      if (!filters.empty ())
		filtered_line_end = fn->end_line;
	    }
	}

      /* For lines which don't exist in the .bb file, print '-' before
	 the source line.  For lines which exist but were never
	 executed, print '#####' or '=====' before the source line.
	 Otherwise, print the execution count before the source line.
	 There are 16 spaces of indentation added before the source
	 line so that tabs won't be messed up.  */
      if (line_num <= filtered_line_end)
	{
	  output_line_beginning (gcov_file, line->exists, line->unexceptional,
				 line->has_unexecuted_block, line->count,
				 line_num, "=====", "#####",
				 src->maximum_count);

	  print_source_line (gcov_file, source_lines, line_num);
	  output_line_details (gcov_file, line, line_num);
	}

      if (line_start_group == line_num)
	{
	  for (vector<function_info *>::iterator it = fns->begin ();
	       it != fns->end (); it++)
	    {
	      function_info *fn = *it;
	      vector<line_info> &lines = fn->lines;

	      fprintf (gcov_file, FN_SEPARATOR);

	      string fn_name = fn->get_name ();
	      if (flag_use_colors)
		{
		  fn_name.insert (0, SGR_SEQ (COLOR_FG_CYAN));
		  fn_name += SGR_RESET;
		}

	      fprintf (gcov_file, "%s:\n", fn_name.c_str ());

	      output_function_details (gcov_file, fn);
	      output_path_coverage (gcov_file, fn);

	      /* Print all lines covered by the function.  */
	      for (unsigned i = 0; i < lines.size (); i++)
		{
		  line_info *line = &lines[i];
		  unsigned l = fn->start_line + i;

		  /* For lines which don't exist in the .bb file, print '-'
		     before the source line.  For lines which exist but
		     were never executed, print '#####' or '=====' before
		     the source line.  Otherwise, print the execution count
		     before the source line.
		     There are 16 spaces of indentation added before the source
		     line so that tabs won't be messed up.  */
		  output_line_beginning (gcov_file, line->exists,
					 line->unexceptional,
					 line->has_unexecuted_block,
					 line->count,
					 l, "=====", "#####",
					 src->maximum_count);

		  print_source_line (gcov_file, source_lines, l);
		  output_line_details (gcov_file, line, l);
		}
	    }

	  fprintf (gcov_file, FN_SEPARATOR);
	  line_start_group = 0;
	}
    }
}
