/* Consolidation of svalues and regions.
   Copyright (C) 2020-2022 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@redhat.com>.

This file is part of GCC.

GCC 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.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "diagnostic-core.h"
#include "gimple-pretty-print.h"
#include "function.h"
#include "basic-block.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "diagnostic-core.h"
#include "graphviz.h"
#include "options.h"
#include "cgraph.h"
#include "tree-dfa.h"
#include "stringpool.h"
#include "convert.h"
#include "target.h"
#include "fold-const.h"
#include "tree-pretty-print.h"
#include "bitmap.h"
#include "analyzer/analyzer.h"
#include "analyzer/analyzer-logging.h"
#include "ordered-hash-map.h"
#include "options.h"
#include "analyzer/supergraph.h"
#include "sbitmap.h"
#include "analyzer/call-string.h"
#include "analyzer/program-point.h"
#include "analyzer/store.h"
#include "analyzer/region-model.h"
#include "analyzer/constraint-manager.h"

#if ENABLE_ANALYZER

namespace ana {

/* class region_model_manager.  */

/* region_model_manager's ctor.  */

region_model_manager::region_model_manager (logger *logger)
: m_logger (logger),
  m_empty_call_string (),
  m_next_region_id (0),
  m_root_region (alloc_region_id ()),
  m_stack_region (alloc_region_id (), &m_root_region),
  m_heap_region (alloc_region_id (), &m_root_region),
  m_unknown_NULL (NULL),
  m_checking_feasibility (false),
  m_max_complexity (0, 0),
  m_code_region (alloc_region_id (), &m_root_region),
  m_fndecls_map (), m_labels_map (),
  m_globals_region (alloc_region_id (), &m_root_region),
  m_globals_map (),
  m_thread_local_region (alloc_region_id (), &m_root_region),
  m_errno_region (alloc_region_id (), &m_thread_local_region),
  m_store_mgr (this),
  m_range_mgr (new bounded_ranges_manager ()),
  m_known_fn_mgr (logger)
{
}

/* region_model_manager's dtor.  Delete all of the managed svalues
   and regions.  */

region_model_manager::~region_model_manager ()
{
  /* Delete consolidated svalues.  */
  for (constants_map_t::iterator iter = m_constants_map.begin ();
       iter != m_constants_map.end (); ++iter)
    delete (*iter).second;
  for (unknowns_map_t::iterator iter = m_unknowns_map.begin ();
       iter != m_unknowns_map.end (); ++iter)
    delete (*iter).second;
  delete m_unknown_NULL;
  for (poisoned_values_map_t::iterator iter = m_poisoned_values_map.begin ();
       iter != m_poisoned_values_map.end (); ++iter)
    delete (*iter).second;
  for (setjmp_values_map_t::iterator iter = m_setjmp_values_map.begin ();
       iter != m_setjmp_values_map.end (); ++iter)
    delete (*iter).second;
  for (initial_values_map_t::iterator iter = m_initial_values_map.begin ();
       iter != m_initial_values_map.end (); ++iter)
    delete (*iter).second;
  for (pointer_values_map_t::iterator iter = m_pointer_values_map.begin ();
       iter != m_pointer_values_map.end (); ++iter)
    delete (*iter).second;
  for (unaryop_values_map_t::iterator iter = m_unaryop_values_map.begin ();
       iter != m_unaryop_values_map.end (); ++iter)
    delete (*iter).second;
  for (binop_values_map_t::iterator iter = m_binop_values_map.begin ();
       iter != m_binop_values_map.end (); ++iter)
    delete (*iter).second;
  for (sub_values_map_t::iterator iter = m_sub_values_map.begin ();
       iter != m_sub_values_map.end (); ++iter)
    delete (*iter).second;
  for (auto iter : m_repeated_values_map)
    delete iter.second;
  for (auto iter : m_bits_within_values_map)
    delete iter.second;
  for (unmergeable_values_map_t::iterator iter
	 = m_unmergeable_values_map.begin ();
       iter != m_unmergeable_values_map.end (); ++iter)
    delete (*iter).second;
  for (widening_values_map_t::iterator iter = m_widening_values_map.begin ();
       iter != m_widening_values_map.end (); ++iter)
    delete (*iter).second;
  for (compound_values_map_t::iterator iter = m_compound_values_map.begin ();
       iter != m_compound_values_map.end (); ++iter)
    delete (*iter).second;
  for (conjured_values_map_t::iterator iter = m_conjured_values_map.begin ();
       iter != m_conjured_values_map.end (); ++iter)
    delete (*iter).second;
  for (auto iter : m_asm_output_values_map)
    delete iter.second;
  for (auto iter : m_const_fn_result_values_map)
    delete iter.second;

  /* Delete consolidated regions.  */
  for (fndecls_map_t::iterator iter = m_fndecls_map.begin ();
       iter != m_fndecls_map.end (); ++iter)
    delete (*iter).second;
  for (labels_map_t::iterator iter = m_labels_map.begin ();
       iter != m_labels_map.end (); ++iter)
    delete (*iter).second;
  for (globals_map_t::iterator iter = m_globals_map.begin ();
       iter != m_globals_map.end (); ++iter)
    delete (*iter).second;
  for (string_map_t::iterator iter = m_string_map.begin ();
       iter != m_string_map.end (); ++iter)
    delete (*iter).second;

  delete m_range_mgr;
}

/* Return true if C exceeds the complexity limit for svalues.  */

bool
region_model_manager::too_complex_p (const complexity &c) const
{
  if (c.m_max_depth > (unsigned)param_analyzer_max_svalue_depth)
    return true;
  return false;
}

/* If SVAL exceeds the complexity limit for svalues, delete it
   and return true.
   Otherwise update m_max_complexity and return false.  */

bool
region_model_manager::reject_if_too_complex (svalue *sval)
{
  if (m_checking_feasibility)
    return false;

  const complexity &c = sval->get_complexity ();
  if (!too_complex_p (c))
    {
      if (m_max_complexity.m_num_nodes < c.m_num_nodes)
	m_max_complexity.m_num_nodes = c.m_num_nodes;
      if (m_max_complexity.m_max_depth < c.m_max_depth)
	m_max_complexity.m_max_depth = c.m_max_depth;
      return false;
    }

  delete sval;
  return true;
}

/* Macro for imposing a complexity limit on svalues, for use within
   region_model_manager member functions.

   If SVAL exceeds the complexity limit, delete it and return an UNKNOWN
   value of the same type.
   Otherwise update m_max_complexity and carry on.  */

#define RETURN_UNKNOWN_IF_TOO_COMPLEX(SVAL)			\
  do {								\
    svalue *sval_ = (SVAL);					\
    tree type_ = sval_->get_type ();				\
    if (reject_if_too_complex (sval_))				\
      return get_or_create_unknown_svalue (type_);		\
  } while (0)

/* svalue consolidation.  */

/* Return the svalue * for a constant_svalue for CST_EXPR,
   creating it if necessary.
   The constant_svalue instances are reused, based on pointer equality
   of trees  */

const svalue *
region_model_manager::get_or_create_constant_svalue (tree cst_expr)
{
  gcc_assert (cst_expr);
  gcc_assert (CONSTANT_CLASS_P (cst_expr));

  constant_svalue **slot = m_constants_map.get (cst_expr);
  if (slot)
    return *slot;
  constant_svalue *cst_sval = new constant_svalue (cst_expr);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (cst_sval);
  m_constants_map.put (cst_expr, cst_sval);
  return cst_sval;
}

/* Return the svalue * for a constant_svalue for the INTEGER_CST
   for VAL of type TYPE, creating it if necessary.  */

const svalue *
region_model_manager::get_or_create_int_cst (tree type, poly_int64 val)
{
  gcc_assert (type);
  tree tree_cst = build_int_cst (type, val);
  return get_or_create_constant_svalue (tree_cst);
}

/* Return the svalue * for a unknown_svalue for TYPE (which can be NULL),
   creating it if necessary.
   The unknown_svalue instances are reused, based on pointer equality
   of the types  */

const svalue *
region_model_manager::get_or_create_unknown_svalue (tree type)
{
  /* Don't create unknown values when doing feasibility testing;
     instead, create a unique svalue.  */
  if (m_checking_feasibility)
    return create_unique_svalue (type);

  /* Special-case NULL, so that the hash_map can use NULL as the
     "empty" value.  */
  if (type == NULL_TREE)
    {
      if (!m_unknown_NULL)
	m_unknown_NULL = new unknown_svalue (type);
      return m_unknown_NULL;
    }

  unknown_svalue **slot = m_unknowns_map.get (type);
  if (slot)
    return *slot;
  unknown_svalue *sval = new unknown_svalue (type);
  m_unknowns_map.put (type, sval);
  return sval;
}

/* Return a freshly-allocated svalue of TYPE, owned by this manager.  */

const svalue *
region_model_manager::create_unique_svalue (tree type)
{
  svalue *sval = new placeholder_svalue (type, "unique");
  m_managed_dynamic_svalues.safe_push (sval);
  return sval;
}

/* Return the svalue * for the initial value of REG, creating it if
   necessary.  */

const svalue *
region_model_manager::get_or_create_initial_value (const region *reg)
{
  if (!reg->can_have_initial_svalue_p ())
    return get_or_create_poisoned_svalue (POISON_KIND_UNINIT,
					  reg->get_type ());

  /* The initial value of a cast is a cast of the initial value.  */
  if (const cast_region *cast_reg = reg->dyn_cast_cast_region ())
    {
      const region *original_reg = cast_reg->get_original_region ();
      return get_or_create_cast (cast_reg->get_type (),
				 get_or_create_initial_value (original_reg));
    }

  /* INIT_VAL (*UNKNOWN_PTR) -> UNKNOWN_VAL.  */
  if (reg->symbolic_for_unknown_ptr_p ())
    return get_or_create_unknown_svalue (reg->get_type ());

  if (initial_svalue **slot = m_initial_values_map.get (reg))
    return *slot;
  initial_svalue *initial_sval = new initial_svalue (reg->get_type (), reg);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (initial_sval);
  m_initial_values_map.put (reg, initial_sval);
  return initial_sval;
}

/* Return the svalue * for R using type TYPE, creating it if
   necessary.  */

const svalue *
region_model_manager::get_or_create_setjmp_svalue (const setjmp_record &r,
						   tree type)
{
  setjmp_svalue::key_t key (r, type);
  if (setjmp_svalue **slot = m_setjmp_values_map.get (key))
    return *slot;
  setjmp_svalue *setjmp_sval = new setjmp_svalue (r, type);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (setjmp_sval);
  m_setjmp_values_map.put (key, setjmp_sval);
  return setjmp_sval;
}

/* Return the svalue * for a poisoned value of KIND and TYPE, creating it if
   necessary.  */

const svalue *
region_model_manager::get_or_create_poisoned_svalue (enum poison_kind kind,
						     tree type)
{
  poisoned_svalue::key_t key (kind, type);
  if (poisoned_svalue **slot = m_poisoned_values_map.get (key))
    return *slot;
  poisoned_svalue *poisoned_sval = new poisoned_svalue (kind, type);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (poisoned_sval);
  m_poisoned_values_map.put (key, poisoned_sval);
  return poisoned_sval;
}

/* Return the svalue * for a pointer to POINTEE of type PTR_TYPE,
   creating it if necessary.  */

const svalue *
region_model_manager::get_ptr_svalue (tree ptr_type, const region *pointee)
{
  /* If this is a symbolic region from dereferencing a pointer, and the types
     match, then return the original pointer.  */
  if (const symbolic_region *sym_reg = pointee->dyn_cast_symbolic_region ())
    if (ptr_type == sym_reg->get_pointer ()->get_type ())
      return sym_reg->get_pointer ();

  region_svalue::key_t key (ptr_type, pointee);
  if (region_svalue **slot = m_pointer_values_map.get (key))
    return *slot;
  region_svalue *sval = new region_svalue (ptr_type, pointee);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (sval);
  m_pointer_values_map.put (key, sval);
  return sval;
}

/* Subroutine of region_model_manager::get_or_create_unaryop.
   Attempt to fold the inputs and return a simpler svalue *.
   Otherwise, return NULL.  */

const svalue *
region_model_manager::maybe_fold_unaryop (tree type, enum tree_code op,
					  const svalue *arg)
{
  /* Ops on "unknown" are also unknown.  */
  if (arg->get_kind () == SK_UNKNOWN)
    return get_or_create_unknown_svalue (type);
  /* Likewise for "poisoned".  */
  else if (const poisoned_svalue *poisoned_sval
	     = arg->dyn_cast_poisoned_svalue ())
    return get_or_create_poisoned_svalue (poisoned_sval->get_poison_kind (),
					  type);

  gcc_assert (arg->can_have_associated_state_p ());

  switch (op)
    {
    default: break;
    case VIEW_CONVERT_EXPR:
    case NOP_EXPR:
      {
	/* Handle redundant casts.  */
	if (arg->get_type ()
	    && useless_type_conversion_p (arg->get_type (), type))
	  return arg;

	/* Fold "cast<TYPE> (cast <INNER_TYPE> (innermost_arg))
	     => "cast<TYPE> (innermost_arg)",
	   unless INNER_TYPE is narrower than TYPE.  */
	if (const svalue *innermost_arg = arg->maybe_undo_cast ())
	  {
	    tree inner_type = arg->get_type ();
	    if (TYPE_SIZE (type)
		&& TYPE_SIZE (inner_type)
		&& (fold_binary (LE_EXPR, boolean_type_node,
				 TYPE_SIZE (type), TYPE_SIZE (inner_type))
		    == boolean_true_node))
	      return maybe_fold_unaryop (type, op, innermost_arg);
	  }
	/* Avoid creating symbolic regions for pointer casts by
	   simplifying (T*)(&REGION) to ((T*)&REGION).  */
	if (const region_svalue *region_sval = arg->dyn_cast_region_svalue ())
	  if (POINTER_TYPE_P (type)
	      && region_sval->get_type ()
	      && POINTER_TYPE_P (region_sval->get_type ()))
	    return get_ptr_svalue (type, region_sval->get_pointee ());
      }
      break;
    case TRUTH_NOT_EXPR:
      {
	/* Invert comparisons e.g. "!(x == y)" => "x != y".  */
	if (const binop_svalue *binop = arg->dyn_cast_binop_svalue ())
	  if (TREE_CODE_CLASS (binop->get_op ()) == tcc_comparison)
	    {
	      enum tree_code inv_op
		= invert_tree_comparison (binop->get_op (),
					  HONOR_NANS (binop->get_type ()));
	      if (inv_op != ERROR_MARK)
		return get_or_create_binop (binop->get_type (), inv_op,
					    binop->get_arg0 (),
					    binop->get_arg1 ());
	    }
      }
      break;
    case NEGATE_EXPR:
      {
	/* -(-(VAL)) is VAL, for integer types.  */
	if (const unaryop_svalue *unaryop = arg->dyn_cast_unaryop_svalue ())
	  if (unaryop->get_op () == NEGATE_EXPR
	      && type == unaryop->get_type ()
	      && type
	      && INTEGRAL_TYPE_P (type))
	    return unaryop->get_arg ();
      }
      break;
    }

  /* Constants.  */
  if (tree cst = arg->maybe_get_constant ())
    if (tree result = fold_unary (op, type, cst))
      {
	if (CONSTANT_CLASS_P (result))
	  return get_or_create_constant_svalue (result);

	/* fold_unary can return casts of constants; try to handle them.  */
	if (op != NOP_EXPR
		 && type
		 && TREE_CODE (result) == NOP_EXPR
		 && CONSTANT_CLASS_P (TREE_OPERAND (result, 0)))
	  {
	    const svalue *inner_cst
	      = get_or_create_constant_svalue (TREE_OPERAND (result, 0));
	    return get_or_create_cast (type,
				       get_or_create_cast (TREE_TYPE (result),
							   inner_cst));
	  }
      }

  return NULL;
}

/* Return the svalue * for an unary operation OP on ARG with a result of
   type TYPE, creating it if necessary.  */

const svalue *
region_model_manager::get_or_create_unaryop (tree type, enum tree_code op,
					     const svalue *arg)
{
  if (const svalue *folded = maybe_fold_unaryop  (type, op, arg))
    return folded;
  unaryop_svalue::key_t key (type, op, arg);
  if (unaryop_svalue **slot = m_unaryop_values_map.get (key))
    return *slot;
  unaryop_svalue *unaryop_sval = new unaryop_svalue (type, op, arg);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (unaryop_sval);
  m_unaryop_values_map.put (key, unaryop_sval);
  return unaryop_sval;
}

/* Get a tree code for a cast to DST_TYPE from SRC_TYPE.
   Use NOP_EXPR if possible (e.g. to help fold_unary convert casts
   of 0 to (T*) to simple pointer constants), but use FIX_TRUNC_EXPR
   and VIEW_CONVERT_EXPR for cases that fold_unary would otherwise crash
   on.  */

static enum tree_code
get_code_for_cast (tree dst_type, tree src_type)
{
  gcc_assert (dst_type);
  if (!src_type)
    return NOP_EXPR;

  if (TREE_CODE (src_type) == REAL_TYPE)
    {
      if (TREE_CODE (dst_type) == INTEGER_TYPE)
	return FIX_TRUNC_EXPR;
      else
	return VIEW_CONVERT_EXPR;
    }

  return NOP_EXPR;
}

/* Return the svalue * for a cast of ARG to type TYPE, creating it
   if necessary.  */

const svalue *
region_model_manager::get_or_create_cast (tree type, const svalue *arg)
{
  gcc_assert (type);

  /* No-op if the types are the same.  */
  if (type == arg->get_type ())
    return arg;

  /* Don't attempt to handle casts involving vector types for now.  */
  if (TREE_CODE (type) == VECTOR_TYPE
      || (arg->get_type ()
	  && TREE_CODE (arg->get_type ()) == VECTOR_TYPE))
    return get_or_create_unknown_svalue (type);

  enum tree_code op = get_code_for_cast (type, arg->get_type ());
  return get_or_create_unaryop (type, op, arg);
}

/* Subroutine of region_model_manager::maybe_fold_binop for handling
   (TYPE)(COMPOUND_SVAL BIT_AND_EXPR CST) that may have been generated by
   optimize_bit_field_compare, where CST is from ARG1.

   Support masking out bits from a compound_svalue for comparing a bitfield
   against a value, as generated by optimize_bit_field_compare for
   BITFIELD == VALUE.

   If COMPOUND_SVAL has a value for the appropriate bits, return it,
   shifted accordingly.
   Otherwise return NULL.  */

const svalue *
region_model_manager::
maybe_undo_optimize_bit_field_compare (tree type,
				       const compound_svalue *compound_sval,
				       tree cst,
				       const svalue *arg1)
{
  if (type != unsigned_char_type_node)
    return NULL;

  const binding_map &map = compound_sval->get_map ();
  unsigned HOST_WIDE_INT mask = TREE_INT_CST_LOW (cst);
  /* If "mask" is a contiguous range of set bits, see if the
     compound_sval has a value for those bits.  */
  bit_range bits (0, 0);
  if (!bit_range::from_mask (mask, &bits))
    return NULL;

  bit_range bound_bits (bits);
  if (BYTES_BIG_ENDIAN)
    bound_bits = bit_range (BITS_PER_UNIT - bits.get_next_bit_offset (),
			    bits.m_size_in_bits);
  const concrete_binding *conc
    = get_store_manager ()->get_concrete_binding (bound_bits);
  const svalue *sval = map.get (conc);
  if (!sval)
    return NULL;

  /* We have a value;
     shift it by the correct number of bits.  */
  const svalue *lhs = get_or_create_cast (type, sval);
  HOST_WIDE_INT bit_offset = bits.get_start_bit_offset ().to_shwi ();
  const svalue *shift_sval = get_or_create_int_cst (type, bit_offset);
  const svalue *shifted_sval = get_or_create_binop (type, LSHIFT_EXPR,
						    lhs, shift_sval);
  /* Reapply the mask (needed for negative
     signed bitfields).  */
  return get_or_create_binop (type, BIT_AND_EXPR,
			      shifted_sval, arg1);
}

/* Subroutine of region_model_manager::get_or_create_binop.
   Attempt to fold the inputs and return a simpler svalue *.
   Otherwise, return NULL.  */

const svalue *
region_model_manager::maybe_fold_binop (tree type, enum tree_code op,
					const svalue *arg0,
					const svalue *arg1)
{
  tree cst0 = arg0->maybe_get_constant ();
  tree cst1 = arg1->maybe_get_constant ();
  /* (CST OP CST).  */
  if (cst0 && cst1)
    {
      if (tree result = fold_binary (op, type, cst0, cst1))
	if (CONSTANT_CLASS_P (result))
	  return get_or_create_constant_svalue (result);
    }

  if (FLOAT_TYPE_P (type)
      || (arg0->get_type () && FLOAT_TYPE_P (arg0->get_type ()))
      || (arg1->get_type () && FLOAT_TYPE_P (arg1->get_type ())))
    return NULL;

  switch (op)
    {
    default:
      break;
    case POINTER_PLUS_EXPR:
    case PLUS_EXPR:
      /* (VAL + 0) -> VAL.  */
      if (cst1 && zerop (cst1) && type == arg0->get_type ())
	return arg0;
      break;
    case MINUS_EXPR:
      /* (VAL - 0) -> VAL.  */
      if (cst1 && zerop (cst1) && type == arg0->get_type ())
	return arg0;
      break;
    case MULT_EXPR:
      /* (VAL * 0).  */
      if (cst1 && zerop (cst1) && INTEGRAL_TYPE_P (type))
	return get_or_create_constant_svalue (build_int_cst (type, 0));
      /* (VAL * 1) -> VAL.  */
      if (cst1 && integer_onep (cst1))
	return arg0;
      break;
    case BIT_AND_EXPR:
      if (cst1)
	{
	  if (zerop (cst1) && INTEGRAL_TYPE_P (type))
	    /* "(ARG0 & 0)" -> "0".  */
	    return get_or_create_constant_svalue (build_int_cst (type, 0));

	  if (const compound_svalue *compound_sval
		= arg0->dyn_cast_compound_svalue ())
	    if (const svalue *sval
		= maybe_undo_optimize_bit_field_compare (type,
							 compound_sval,
							 cst1, arg1))
	      return sval;
	}
      if (arg0->get_type () == boolean_type_node
	  && arg1->get_type () == boolean_type_node)
	{
	  /* If the LHS are both _Bool, then... */
	  /* ..."(1 & x) -> x".  */
	  if (cst0 && !zerop (cst0))
	    return get_or_create_cast (type, arg1);
	  /* ..."(x & 1) -> x".  */
	  if (cst1 && !zerop (cst1))
	    return get_or_create_cast (type, arg0);
	  /* ..."(0 & x) -> 0".  */
	  if (cst0 && zerop (cst0))
	    return get_or_create_int_cst (type, 0);
	  /* ..."(x & 0) -> 0".  */
	  if (cst1 && zerop (cst1))
	    return get_or_create_int_cst (type, 0);
	}
      break;
    case BIT_IOR_EXPR:
      if (arg0->get_type () == boolean_type_node
	  && arg1->get_type () == boolean_type_node)
	{
	  /* If the LHS are both _Bool, then... */
	  /* ..."(1 | x) -> 1".  */
	  if (cst0 && !zerop (cst0))
	    return get_or_create_int_cst (type, 1);
	  /* ..."(x | 1) -> 1".  */
	  if (cst1 && !zerop (cst1))
	    return get_or_create_int_cst (type, 1);
	  /* ..."(0 | x) -> x".  */
	  if (cst0 && zerop (cst0))
	    return get_or_create_cast (type, arg1);
	  /* ..."(x | 0) -> x".  */
	  if (cst1 && zerop (cst1))
	    return get_or_create_cast (type, arg0);
	}
      break;
    case TRUTH_ANDIF_EXPR:
    case TRUTH_AND_EXPR:
      if (cst1)
	{
	  if (zerop (cst1) && INTEGRAL_TYPE_P (type))
	    /* "(ARG0 && 0)" -> "0".  */
	    return get_or_create_constant_svalue (build_int_cst (type, 0));
	  else
	    /* "(ARG0 && nonzero-cst)" -> "ARG0".  */
	    return get_or_create_cast (type, arg0);
	}
      break;
    case TRUTH_ORIF_EXPR:
    case TRUTH_OR_EXPR:
      if (cst1)
	{
	  if (zerop (cst1))
	    /* "(ARG0 || 0)" -> "ARG0".  */
	    return get_or_create_cast (type, arg0);
	  else
	    /* "(ARG0 && nonzero-cst)" -> "nonzero-cst".  */
	    return get_or_create_cast (type, arg1);
	}
      break;
    }

  /* For associative ops, fold "(X op CST_A) op CST_B)" to
     "X op (CST_A op CST_B)".  */
  if (cst1 && associative_tree_code (op))
    if (const binop_svalue *binop = arg0->dyn_cast_binop_svalue ())
      if (binop->get_op () == op
	  && binop->get_arg1 ()->maybe_get_constant ()
	  && type == binop->get_type ()
	  && type == binop->get_arg0 ()->get_type ()
	  && type == binop->get_arg1 ()->get_type ())
	return get_or_create_binop
	  (type, op, binop->get_arg0 (),
	   get_or_create_binop (type, op,
				binop->get_arg1 (), arg1));

  /* associative_tree_code is false for POINTER_PLUS_EXPR, but we
     can fold:
       "(PTR ptr+ CST_A) ptr+ CST_B)" to "PTR ptr+ (CST_A ptr+ CST_B)"
     e.g. in data-model-1.c: test_4c.  */
  if (cst1 && op == POINTER_PLUS_EXPR)
    if (const binop_svalue *binop = arg0->dyn_cast_binop_svalue ())
      if (binop->get_op () == POINTER_PLUS_EXPR)
	if (binop->get_arg1 ()->maybe_get_constant ())
	  return get_or_create_binop
	    (type, op, binop->get_arg0 (),
	     get_or_create_binop (size_type_node, op,
				  binop->get_arg1 (), arg1));

  /* etc.  */

  return NULL;
}

/* Return the svalue * for an binary operation OP on ARG0 and ARG1
   with a result of type TYPE, creating it if necessary.  */

const svalue *
region_model_manager::get_or_create_binop (tree type, enum tree_code op,
					   const svalue *arg0,
					   const svalue *arg1)
{
  /* For commutative ops, put any constant on the RHS.  */
  if (arg0->maybe_get_constant () && commutative_tree_code (op))
    std::swap (arg0, arg1);

  if (const svalue *folded = maybe_fold_binop (type, op, arg0, arg1))
    return folded;

  /* Ops on "unknown"/"poisoned" are unknown (unless we were able to fold
     it via an identity in maybe_fold_binop).  */
  if (!arg0->can_have_associated_state_p ()
      || !arg1->can_have_associated_state_p ())
    return get_or_create_unknown_svalue (type);

  binop_svalue::key_t key (type, op, arg0, arg1);
  if (binop_svalue **slot = m_binop_values_map.get (key))
    return *slot;
  binop_svalue *binop_sval = new binop_svalue (type, op, arg0, arg1);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (binop_sval);
  m_binop_values_map.put (key, binop_sval);
  return binop_sval;
}

/* Subroutine of region_model_manager::get_or_create_sub_svalue.
   Return a folded svalue, or NULL.  */

const svalue *
region_model_manager::maybe_fold_sub_svalue (tree type,
					     const svalue *parent_svalue,
					     const region *subregion)
{
  /* Subvalues of "unknown"/"poisoned" are unknown.  */
  if (!parent_svalue->can_have_associated_state_p ())
    return get_or_create_unknown_svalue (type);

  /* If we have a subregion of a zero-fill, it's zero.  */
  if (const unaryop_svalue *unary
      = parent_svalue->dyn_cast_unaryop_svalue ())
    {
      if (unary->get_op () == NOP_EXPR
	  || unary->get_op () == VIEW_CONVERT_EXPR)
	if (tree cst = unary->get_arg ()->maybe_get_constant ())
	  if (zerop (cst) && type)
	    {
	      const svalue *cst_sval
		= get_or_create_constant_svalue (cst);
	      return get_or_create_cast (type, cst_sval);
	    }
    }

  /* Handle getting individual chars from a STRING_CST.  */
  if (tree cst = parent_svalue->maybe_get_constant ())
    if (TREE_CODE (cst) == STRING_CST)
      {
	/* If we have a concrete 1-byte access within the parent region... */
	byte_range subregion_bytes (0, 0);
	if (subregion->get_relative_concrete_byte_range (&subregion_bytes)
	    && subregion_bytes.m_size_in_bytes == 1
	    && type)
	  {
	    /* ...then attempt to get that char from the STRING_CST.  */
	    HOST_WIDE_INT hwi_start_byte
	      = subregion_bytes.m_start_byte_offset.to_shwi ();
	    tree cst_idx
	      = build_int_cst_type (size_type_node, hwi_start_byte);
	    if (const svalue *char_sval
		= maybe_get_char_from_string_cst (cst, cst_idx))
	      return get_or_create_cast (type, char_sval);
	  }
      }

  if (const initial_svalue *init_sval
	= parent_svalue->dyn_cast_initial_svalue ())
    {
      /* SUB(INIT(r)).FIELD -> INIT(r.FIELD)
	 i.e.
	 Subvalue(InitialValue(R1), FieldRegion(R2, F))
	 -> InitialValue(FieldRegion(R1, F)).  */
      if (const field_region *field_reg = subregion->dyn_cast_field_region ())
	{
	  const region *field_reg_new
	    = get_field_region (init_sval->get_region (),
				field_reg->get_field ());
	  return get_or_create_initial_value (field_reg_new);
	}
      /* SUB(INIT(r)[ELEMENT] -> INIT(e[ELEMENT])
	 i.e.
	 Subvalue(InitialValue(R1), ElementRegion(R2, IDX))
	 -> InitialValue(ElementRegion(R1, IDX)).  */
      if (const element_region *element_reg = subregion->dyn_cast_element_region ())
	{
	  const region *element_reg_new
	    = get_element_region (init_sval->get_region (),
				  element_reg->get_type (),
				  element_reg->get_index ());
	  return get_or_create_initial_value (element_reg_new);
	}
    }

  if (const repeated_svalue *repeated_sval
	= parent_svalue->dyn_cast_repeated_svalue ())
    if (type)
      return get_or_create_cast (type, repeated_sval->get_inner_svalue ());

  return NULL;
}

/* Return the svalue * for extracting a subvalue of type TYPE from
   PARENT_SVALUE based on SUBREGION, creating it if necessary.  */

const svalue *
region_model_manager::get_or_create_sub_svalue (tree type,
						const svalue *parent_svalue,
						const region *subregion)
{
  if (const svalue *folded
	= maybe_fold_sub_svalue (type, parent_svalue, subregion))
    return folded;

  sub_svalue::key_t key (type, parent_svalue, subregion);
  if (sub_svalue **slot = m_sub_values_map.get (key))
    return *slot;
  sub_svalue *sub_sval
    = new sub_svalue (type, parent_svalue, subregion);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (sub_sval);
  m_sub_values_map.put (key, sub_sval);
  return sub_sval;
}

/* Subroutine of region_model_manager::get_or_create_repeated_svalue.
   Return a folded svalue, or NULL.  */

const svalue *
region_model_manager::maybe_fold_repeated_svalue (tree type,
						  const svalue *outer_size,
						  const svalue *inner_svalue)
{
  /* Repeated "unknown"/"poisoned" is unknown.  */
  if (!outer_size->can_have_associated_state_p ()
      || !inner_svalue->can_have_associated_state_p ())
    return get_or_create_unknown_svalue (type);

  /* If INNER_SVALUE is the same size as OUTER_SIZE,
     turn into simply a cast.  */
  if (tree cst_outer_num_bytes = outer_size->maybe_get_constant ())
    {
      HOST_WIDE_INT num_bytes_inner_svalue
	= int_size_in_bytes (inner_svalue->get_type ());
      if (num_bytes_inner_svalue != -1)
	if (num_bytes_inner_svalue
	    == (HOST_WIDE_INT)tree_to_uhwi (cst_outer_num_bytes))
	  {
	    if (type)
	      return get_or_create_cast (type, inner_svalue);
	    else
	      return inner_svalue;
	  }
    }

  /* Handle zero-fill of a specific type.  */
  if (tree cst = inner_svalue->maybe_get_constant ())
    if (zerop (cst) && type)
      return get_or_create_cast (type, inner_svalue);

  return NULL;
}

/* Return the svalue * of type TYPE in which INNER_SVALUE is repeated
   enough times to be of size OUTER_SIZE, creating it if necessary.
   e.g. for filling buffers with a constant value.  */

const svalue *
region_model_manager::get_or_create_repeated_svalue (tree type,
						     const svalue *outer_size,
						     const svalue *inner_svalue)
{
  if (const svalue *folded
	= maybe_fold_repeated_svalue (type, outer_size, inner_svalue))
    return folded;

  repeated_svalue::key_t key (type, outer_size, inner_svalue);
  if (repeated_svalue **slot = m_repeated_values_map.get (key))
    return *slot;
  repeated_svalue *repeated_sval
    = new repeated_svalue (type, outer_size, inner_svalue);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (repeated_sval);
  m_repeated_values_map.put (key, repeated_sval);
  return repeated_sval;
}

/* Attempt to get the bit_range for FIELD within a RECORD_TYPE.
   Return true and write the result to OUT if successful.
   Return false otherwise.  */

static bool
get_bit_range_for_field (tree field, bit_range *out)
{
  bit_size_t bit_size;
  if (!int_size_in_bits (TREE_TYPE (field), &bit_size))
    return false;
  int field_bit_offset = int_bit_position (field);
  *out = bit_range (field_bit_offset, bit_size);
  return true;
}

/* Attempt to get the byte_range for FIELD within a RECORD_TYPE.
   Return true and write the result to OUT if successful.
   Return false otherwise.  */

static bool
get_byte_range_for_field (tree field, byte_range *out)
{
  bit_range field_bits (0, 0);
  if (!get_bit_range_for_field (field, &field_bits))
    return false;
  return field_bits.as_byte_range (out);
}

/* Attempt to determine if there is a specific field within RECORD_TYPE
   at BYTES.  If so, return it, and write the location of BYTES relative
   to the field to *OUT_RANGE_WITHIN_FIELD.
   Otherwise, return NULL_TREE.
   For example, given:
     struct foo { uint32 a; uint32; b};
   and
     bytes = {bytes 6-7} (of foo)
   we have bytes 3-4 of field b.  */

static tree
get_field_at_byte_range (tree record_type, const byte_range &bytes,
			 byte_range *out_range_within_field)
{
  bit_offset_t bit_offset = bytes.m_start_byte_offset * BITS_PER_UNIT;

  tree field = get_field_at_bit_offset (record_type, bit_offset);
  if (!field)
    return NULL_TREE;

  byte_range field_bytes (0,0);
  if (!get_byte_range_for_field (field, &field_bytes))
    return NULL_TREE;

  /* Is BYTES fully within field_bytes?  */
  byte_range bytes_within_field (0,0);
  if (!field_bytes.contains_p (bytes, &bytes_within_field))
    return NULL_TREE;

  *out_range_within_field = bytes_within_field;
  return field;
}

/* Subroutine of region_model_manager::get_or_create_bits_within.
   Return a folded svalue, or NULL.  */

const svalue *
region_model_manager::maybe_fold_bits_within_svalue (tree type,
						     const bit_range &bits,
						     const svalue *inner_svalue)
{
  tree inner_type = inner_svalue->get_type ();
  /* Fold:
       BITS_WITHIN ((0, sizeof (VAL), VAL))
     to:
       CAST(TYPE, VAL).  */
  if (bits.m_start_bit_offset == 0 && inner_type)
    {
      bit_size_t inner_type_size;
      if (int_size_in_bits (inner_type, &inner_type_size))
	if (inner_type_size == bits.m_size_in_bits)
	  {
	    if (type)
	      return get_or_create_cast (type, inner_svalue);
	    else
	      return inner_svalue;
	  }
    }

  /* Kind-specific folding.  */
  if (const svalue *sval
      = inner_svalue->maybe_fold_bits_within (type, bits, this))
    return sval;

  byte_range bytes (0,0);
  if (bits.as_byte_range (&bytes) && inner_type)
    switch (TREE_CODE (inner_type))
      {
      default:
	break;
      case ARRAY_TYPE:
	{
	  /* Fold:
	       BITS_WITHIN (range, KIND(REG))
	     to:
	       BITS_WITHIN (range - offsetof(ELEMENT), KIND(REG.ELEMENT))
	     if range1 is a byte-range fully within one ELEMENT.  */
	  tree element_type = TREE_TYPE (inner_type);
	  HOST_WIDE_INT element_byte_size
	    = int_size_in_bytes (element_type);
	  if (element_byte_size > 0)
	    {
	      HOST_WIDE_INT start_idx
		= (bytes.get_start_byte_offset ().to_shwi ()
		   / element_byte_size);
	      HOST_WIDE_INT last_idx
		= (bytes.get_last_byte_offset ().to_shwi ()
		   / element_byte_size);
	      if (start_idx == last_idx)
		{
		  if (const initial_svalue *initial_sval
		      = inner_svalue->dyn_cast_initial_svalue ())
		    {
		      bit_offset_t start_of_element
			= start_idx * element_byte_size * BITS_PER_UNIT;
		      bit_range bits_within_element
			(bits.m_start_bit_offset - start_of_element,
			 bits.m_size_in_bits);
		      const svalue *idx_sval
			= get_or_create_int_cst (integer_type_node, start_idx);
		      const region *element_reg =
			get_element_region (initial_sval->get_region (),
					    element_type, idx_sval);
		      const svalue *element_reg_sval
			= get_or_create_initial_value (element_reg);
		      return get_or_create_bits_within (type,
							bits_within_element,
							element_reg_sval);
		    }
		}
	    }
	}
	break;
      case RECORD_TYPE:
	{
	  /* Fold:
	       BYTES_WITHIN (range, KIND(REG))
	     to:
	       BYTES_WITHIN (range - offsetof(FIELD), KIND(REG.FIELD))
	     if range1 is fully within FIELD.  */
	  byte_range bytes_within_field (0, 0);
	  if (tree field = get_field_at_byte_range (inner_type, bytes,
						    &bytes_within_field))
	    {
	      if (const initial_svalue *initial_sval
		  = inner_svalue->dyn_cast_initial_svalue ())
		{
		  const region *field_reg =
		    get_field_region (initial_sval->get_region (), field);
		  const svalue *initial_reg_sval
		    = get_or_create_initial_value (field_reg);
		  return get_or_create_bits_within
		    (type,
		     bytes_within_field.as_bit_range (),
		     initial_reg_sval);
		}
	    }
	}
	break;
      }
  return NULL;
}

/* Return the svalue * of type TYPE for extracting BITS from INNER_SVALUE,
   creating it if necessary.  */

const svalue *
region_model_manager::get_or_create_bits_within (tree type,
						 const bit_range &bits,
						 const svalue *inner_svalue)
{
  if (const svalue *folded
	= maybe_fold_bits_within_svalue (type, bits, inner_svalue))
    return folded;

  bits_within_svalue::key_t key (type, bits, inner_svalue);
  if (bits_within_svalue **slot = m_bits_within_values_map.get (key))
    return *slot;
  bits_within_svalue *bits_within_sval
    = new bits_within_svalue (type, bits, inner_svalue);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (bits_within_sval);
  m_bits_within_values_map.put (key, bits_within_sval);
  return bits_within_sval;
}

/* Return the svalue * that decorates ARG as being unmergeable,
   creating it if necessary.  */

const svalue *
region_model_manager::get_or_create_unmergeable (const svalue *arg)
{
  if (arg->get_kind () == SK_UNMERGEABLE)
    return arg;

  if (unmergeable_svalue **slot = m_unmergeable_values_map.get (arg))
    return *slot;
  unmergeable_svalue *unmergeable_sval = new unmergeable_svalue (arg);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (unmergeable_sval);
  m_unmergeable_values_map.put (arg, unmergeable_sval);
  return unmergeable_sval;
}

/* Return the svalue * of type TYPE for the merger of value BASE_SVAL
   and ITER_SVAL at POINT, creating it if necessary.  */

const svalue *
region_model_manager::
get_or_create_widening_svalue (tree type,
			       const function_point &point,
			       const svalue *base_sval,
			       const svalue *iter_sval)
{
  gcc_assert (base_sval->get_kind () != SK_WIDENING);
  gcc_assert (iter_sval->get_kind () != SK_WIDENING);
  widening_svalue::key_t key (type, point, base_sval, iter_sval);
  if (widening_svalue **slot = m_widening_values_map.get (key))
    return *slot;
  widening_svalue *widening_sval
    = new widening_svalue (type, point, base_sval, iter_sval);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (widening_sval);
  m_widening_values_map.put (key, widening_sval);
  return widening_sval;
}

/* Return the svalue * of type TYPE for the compound values in MAP,
   creating it if necessary.  */

const svalue *
region_model_manager::get_or_create_compound_svalue (tree type,
						     const binding_map &map)
{
  compound_svalue::key_t tmp_key (type, &map);
  if (compound_svalue **slot = m_compound_values_map.get (tmp_key))
    return *slot;
  compound_svalue *compound_sval
    = new compound_svalue (type, map);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (compound_sval);
  /* Use make_key rather than reusing the key, so that we use a
     ptr to compound_sval's binding_map, rather than the MAP param.  */
  m_compound_values_map.put (compound_sval->make_key (), compound_sval);
  return compound_sval;
}

/* class conjured_purge.  */

/* Purge state relating to SVAL.  */

void
conjured_purge::purge (const conjured_svalue *sval) const
{
  m_model->purge_state_involving (sval, m_ctxt);
}

/* Return the svalue * of type TYPE for the value conjured for ID_REG
   at STMT, creating it if necessary.
   Use P to purge existing state from the svalue, for the case where a
   conjured_svalue would be reused along an execution path.  */

const svalue *
region_model_manager::get_or_create_conjured_svalue (tree type,
						     const gimple *stmt,
						     const region *id_reg,
						     const conjured_purge &p)
{
  conjured_svalue::key_t key (type, stmt, id_reg);
  if (conjured_svalue **slot = m_conjured_values_map.get (key))
    {
      const conjured_svalue *sval = *slot;
      /* We're reusing an existing conjured_svalue, perhaps from a different
	 state within this analysis, or perhaps from an earlier state on this
	 execution path.  For the latter, purge any state involving the "new"
	 svalue from the current program_state.  */
      p.purge (sval);
      return sval;
    }
  conjured_svalue *conjured_sval
    = new conjured_svalue (type, stmt, id_reg);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (conjured_sval);
  m_conjured_values_map.put (key, conjured_sval);
  return conjured_sval;
}

/* Subroutine of region_model_manager::get_or_create_asm_output_svalue.
   Return a folded svalue, or NULL.  */

const svalue *
region_model_manager::
maybe_fold_asm_output_svalue (tree type,
			      const vec<const svalue *> &inputs)
{
  /* Unknown inputs should lead to unknown results.  */
  for (const auto &iter : inputs)
    if (iter->get_kind () == SK_UNKNOWN)
      return get_or_create_unknown_svalue (type);

  return NULL;
}

/* Return the svalue * of type TYPE for OUTPUT_IDX of the deterministic
   asm stmt ASM_STMT, given INPUTS as inputs.  */

const svalue *
region_model_manager::
get_or_create_asm_output_svalue (tree type,
				 const gasm *asm_stmt,
				 unsigned output_idx,
				 const vec<const svalue *> &inputs)
{
  gcc_assert (inputs.length () <= asm_output_svalue::MAX_INPUTS);

  if (const svalue *folded
	= maybe_fold_asm_output_svalue (type, inputs))
    return folded;

  const char *asm_string = gimple_asm_string (asm_stmt);
  const unsigned noutputs = gimple_asm_noutputs (asm_stmt);

  asm_output_svalue::key_t key (type, asm_string, output_idx, inputs);
  if (asm_output_svalue **slot = m_asm_output_values_map.get (key))
    return *slot;
  asm_output_svalue *asm_output_sval
    = new asm_output_svalue (type, asm_string, output_idx, noutputs, inputs);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (asm_output_sval);
  m_asm_output_values_map.put (key, asm_output_sval);
  return asm_output_sval;
}

/* Return the svalue * of type TYPE for OUTPUT_IDX of a deterministic
   asm stmt with string ASM_STRING with NUM_OUTPUTS outputs, given
   INPUTS as inputs.  */

const svalue *
region_model_manager::
get_or_create_asm_output_svalue (tree type,
				 const char *asm_string,
				 unsigned output_idx,
				 unsigned num_outputs,
				 const vec<const svalue *> &inputs)
{
  gcc_assert (inputs.length () <= asm_output_svalue::MAX_INPUTS);

  if (const svalue *folded
	= maybe_fold_asm_output_svalue (type, inputs))
    return folded;

  asm_output_svalue::key_t key (type, asm_string, output_idx, inputs);
  if (asm_output_svalue **slot = m_asm_output_values_map.get (key))
    return *slot;
  asm_output_svalue *asm_output_sval
    = new asm_output_svalue (type, asm_string, output_idx, num_outputs, inputs);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (asm_output_sval);
  m_asm_output_values_map.put (key, asm_output_sval);
  return asm_output_sval;
}

/* Return the svalue * of type TYPE for the result of a call to FNDECL
   with __attribute__((const)), given INPUTS as inputs.  */

const svalue *
region_model_manager::
get_or_create_const_fn_result_svalue (tree type,
				      tree fndecl,
				      const vec<const svalue *> &inputs)
{
  gcc_assert (type);
  gcc_assert (fndecl);
  gcc_assert (DECL_P (fndecl));
  gcc_assert (TREE_READONLY (fndecl));
  gcc_assert (inputs.length () <= const_fn_result_svalue::MAX_INPUTS);

  const_fn_result_svalue::key_t key (type, fndecl, inputs);
  if (const_fn_result_svalue **slot = m_const_fn_result_values_map.get (key))
    return *slot;
  const_fn_result_svalue *const_fn_result_sval
    = new const_fn_result_svalue (type, fndecl, inputs);
  RETURN_UNKNOWN_IF_TOO_COMPLEX (const_fn_result_sval);
  m_const_fn_result_values_map.put (key, const_fn_result_sval);
  return const_fn_result_sval;
}

/* Given STRING_CST, a STRING_CST and BYTE_OFFSET_CST a constant,
   attempt to get the character at that offset, returning either
   the svalue for the character constant, or NULL if unsuccessful.  */

const svalue *
region_model_manager::maybe_get_char_from_string_cst (tree string_cst,
						      tree byte_offset_cst)
{
  gcc_assert (TREE_CODE (string_cst) == STRING_CST);

  /* Adapted from fold_read_from_constant_string.  */
  scalar_int_mode char_mode;
  if (TREE_CODE (byte_offset_cst) == INTEGER_CST
      && compare_tree_int (byte_offset_cst,
			   TREE_STRING_LENGTH (string_cst)) < 0
      && is_int_mode (TYPE_MODE (TREE_TYPE (TREE_TYPE (string_cst))),
		      &char_mode)
      && GET_MODE_SIZE (char_mode) == 1)
    {
      tree char_cst
	= build_int_cst_type (TREE_TYPE (TREE_TYPE (string_cst)),
			      (TREE_STRING_POINTER (string_cst)
			       [TREE_INT_CST_LOW (byte_offset_cst)]));
      return get_or_create_constant_svalue (char_cst);
    }
  return NULL;
}

/* region consolidation.  */

/* Return the region for FNDECL, creating it if necessary.  */

const function_region *
region_model_manager::get_region_for_fndecl (tree fndecl)
{
  gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);

  function_region **slot = m_fndecls_map.get (fndecl);
  if (slot)
    return *slot;
  function_region *reg
    = new function_region (alloc_region_id (), &m_code_region, fndecl);
  m_fndecls_map.put (fndecl, reg);
  return reg;
}

/* Return the region for LABEL, creating it if necessary.  */

const label_region *
region_model_manager::get_region_for_label (tree label)
{
  gcc_assert (TREE_CODE (label) == LABEL_DECL);

  label_region **slot = m_labels_map.get (label);
  if (slot)
    return *slot;

  tree fndecl = DECL_CONTEXT (label);
  gcc_assert (fndecl && TREE_CODE (fndecl) == FUNCTION_DECL);

  const function_region *func_reg = get_region_for_fndecl (fndecl);
  label_region *reg
    = new label_region (alloc_region_id (), func_reg, label);
  m_labels_map.put (label, reg);
  return reg;
}

/* Return the region for EXPR, creating it if necessary.  */

const decl_region *
region_model_manager::get_region_for_global (tree expr)
{
  gcc_assert (TREE_CODE (expr) == VAR_DECL);

  decl_region **slot = m_globals_map.get (expr);
  if (slot)
    return *slot;
  decl_region *reg
    = new decl_region (alloc_region_id (), &m_globals_region, expr);
  m_globals_map.put (expr, reg);
  return reg;
}

/* Return the region for an unknown access of type REGION_TYPE,
   creating it if necessary.
   This is a symbolic_region, where the pointer is an unknown_svalue
   of type &REGION_TYPE.  */

const region *
region_model_manager::get_unknown_symbolic_region (tree region_type)
{
  tree ptr_type = region_type ? build_pointer_type (region_type) : NULL_TREE;
  const svalue *unknown_ptr = get_or_create_unknown_svalue (ptr_type);
  return get_symbolic_region (unknown_ptr);
}

/* Return the region that describes accessing field FIELD of PARENT,
   creating it if necessary.  */

const region *
region_model_manager::get_field_region (const region *parent, tree field)
{
  gcc_assert (TREE_CODE (field) == FIELD_DECL);

  /* (*UNKNOWN_PTR).field is (*UNKNOWN_PTR_OF_&FIELD_TYPE).  */
  if (parent->symbolic_for_unknown_ptr_p ())
    return get_unknown_symbolic_region (TREE_TYPE (field));

  field_region::key_t key (parent, field);
  if (field_region *reg = m_field_regions.get (key))
    return reg;

  field_region *field_reg
    = new field_region (alloc_region_id (), parent, field);
  m_field_regions.put (key, field_reg);
  return field_reg;
}

/* Return the region that describes accessing the element of type
   ELEMENT_TYPE at index INDEX of PARENT, creating it if necessary.  */

const region *
region_model_manager::get_element_region (const region *parent,
					  tree element_type,
					  const svalue *index)
{
  /* (UNKNOWN_PTR[IDX]) is (UNKNOWN_PTR).  */
  if (parent->symbolic_for_unknown_ptr_p ())
    return get_unknown_symbolic_region (element_type);

  element_region::key_t key (parent, element_type, index);
  if (element_region *reg = m_element_regions.get (key))
    return reg;

  element_region *element_reg
    = new element_region (alloc_region_id (), parent, element_type, index);
  m_element_regions.put (key, element_reg);
  return element_reg;
}

/* Return the region that describes accessing the subregion of type
   ELEMENT_TYPE at offset BYTE_OFFSET within PARENT, creating it if
   necessary.  */

const region *
region_model_manager::get_offset_region (const region *parent,
					 tree type,
					 const svalue *byte_offset)
{
  /* (UNKNOWN_PTR + OFFSET) is (UNKNOWN_PTR).  */
  if (parent->symbolic_for_unknown_ptr_p ())
    return get_unknown_symbolic_region (type);

  /* If BYTE_OFFSET is zero, return PARENT.  */
  if (tree cst_offset = byte_offset->maybe_get_constant ())
    if (zerop (cst_offset))
      return get_cast_region (parent, type);

  /* Fold OFFSET_REGION(OFFSET_REGION(REG, X), Y)
     to   OFFSET_REGION(REG, (X + Y)).  */
  if (const offset_region *parent_offset_reg
	= parent->dyn_cast_offset_region ())
    {
      const svalue *sval_x = parent_offset_reg->get_byte_offset ();
      const svalue *sval_sum
	= get_or_create_binop (byte_offset->get_type (),
			       PLUS_EXPR, sval_x, byte_offset);
      return get_offset_region (parent->get_parent_region (), type, sval_sum);
    }

  offset_region::key_t key (parent, type, byte_offset);
  if (offset_region *reg = m_offset_regions.get (key))
    return reg;

  offset_region *offset_reg
    = new offset_region (alloc_region_id (), parent, type, byte_offset);
  m_offset_regions.put (key, offset_reg);
  return offset_reg;
}

/* Return the region that describes accessing the subregion of type
   TYPE of size BYTE_SIZE_SVAL within PARENT, creating it if necessary.  */

const region *
region_model_manager::get_sized_region (const region *parent,
					tree type,
					const svalue *byte_size_sval)
{
  if (parent->symbolic_for_unknown_ptr_p ())
    return get_unknown_symbolic_region (type);

  if (byte_size_sval->get_type () != size_type_node)
    byte_size_sval = get_or_create_cast (size_type_node, byte_size_sval);

  /* If PARENT is already that size, return it.  */
  const svalue *parent_byte_size_sval = parent->get_byte_size_sval (this);
  if (tree parent_size_cst = parent_byte_size_sval->maybe_get_constant ())
    if (tree size_cst = byte_size_sval->maybe_get_constant ())
      {
	tree comparison
	  = fold_binary (EQ_EXPR, boolean_type_node, parent_size_cst, size_cst);
	if (comparison == boolean_true_node)
	  return parent;
      }

  sized_region::key_t key (parent, type, byte_size_sval);
  if (sized_region *reg = m_sized_regions.get (key))
    return reg;

  sized_region *sized_reg
    = new sized_region (alloc_region_id (), parent, type, byte_size_sval);
  m_sized_regions.put (key, sized_reg);
  return sized_reg;
}

/* Return the region that describes accessing PARENT_REGION as if
   it were of type TYPE, creating it if necessary.  */

const region *
region_model_manager::get_cast_region (const region *original_region,
				       tree type)
{
  /* If types match, return ORIGINAL_REGION.  */
  if (type == original_region->get_type ())
    return original_region;

  if (original_region->symbolic_for_unknown_ptr_p ())
    return get_unknown_symbolic_region (type);

  cast_region::key_t key (original_region, type);
  if (cast_region *reg = m_cast_regions.get (key))
    return reg;

  cast_region *cast_reg
    = new cast_region (alloc_region_id (), original_region, type);
  m_cast_regions.put (key, cast_reg);
  return cast_reg;
}

/* Return the frame_region for call to FUN from CALLING_FRAME, creating it
   if necessary.  CALLING_FRAME may be NULL.  */

const frame_region *
region_model_manager::get_frame_region (const frame_region *calling_frame,
					function *fun)
{
  int index = calling_frame ? calling_frame->get_index () + 1 : 0;

  frame_region::key_t key (calling_frame, fun);
  if (frame_region *reg = m_frame_regions.get (key))
    return reg;

  frame_region *frame_reg
    = new frame_region (alloc_region_id (), &m_stack_region, calling_frame,
			 fun, index);
  m_frame_regions.put (key, frame_reg);
  return frame_reg;
}

/* Return the region that describes dereferencing SVAL, creating it
   if necessary.  */

const region *
region_model_manager::get_symbolic_region (const svalue *sval)
{
  symbolic_region::key_t key (&m_root_region, sval);
  if (symbolic_region *reg = m_symbolic_regions.get (key))
    return reg;

  symbolic_region *symbolic_reg
    = new symbolic_region (alloc_region_id (), &m_root_region, sval);
  m_symbolic_regions.put (key, symbolic_reg);
  return symbolic_reg;
}

/* Return the region that describes accessing STRING_CST, creating it
   if necessary.  */

const string_region *
region_model_manager::get_region_for_string (tree string_cst)
{
  gcc_assert (TREE_CODE (string_cst) == STRING_CST);

  string_region **slot = m_string_map.get (string_cst);
  if (slot)
    return *slot;
  string_region *reg
    = new string_region (alloc_region_id (), &m_root_region, string_cst);
  m_string_map.put (string_cst, reg);
  return reg;
}

/* Return the region that describes accessing BITS within PARENT as TYPE,
   creating it if necessary.  */

const region *
region_model_manager::get_bit_range (const region *parent, tree type,
				     const bit_range &bits)
{
  gcc_assert (parent);

  if (parent->symbolic_for_unknown_ptr_p ())
    return get_unknown_symbolic_region (type);

  bit_range_region::key_t key (parent, type, bits);
  if (bit_range_region *reg = m_bit_range_regions.get (key))
    return reg;

  bit_range_region *bit_range_reg
    = new bit_range_region (alloc_region_id (), parent, type, bits);
  m_bit_range_regions.put (key, bit_range_reg);
  return bit_range_reg;
}

/* Return the region that describes accessing the IDX-th variadic argument
   within PARENT_FRAME, creating it if necessary.  */

const var_arg_region *
region_model_manager::get_var_arg_region (const frame_region *parent_frame,
					  unsigned idx)
{
  gcc_assert (parent_frame);

  var_arg_region::key_t key (parent_frame, idx);
  if (var_arg_region *reg = m_var_arg_regions.get (key))
    return reg;

  var_arg_region *var_arg_reg
    = new var_arg_region (alloc_region_id (), parent_frame, idx);
  m_var_arg_regions.put (key, var_arg_reg);
  return var_arg_reg;
}

/* If we see a tree code we don't know how to handle, rather than
   ICE or generate bogus results, create a dummy region, and notify
   CTXT so that it can mark the new state as being not properly
   modelled.  The exploded graph can then stop exploring that path,
   since any diagnostics we might issue will have questionable
   validity.  */

const region *
region_model_manager::
get_region_for_unexpected_tree_code (region_model_context *ctxt,
				     tree t,
				     const dump_location_t &loc)
{
  tree type = TYPE_P (t) ? t : TREE_TYPE (t);
  region *new_reg
    = new unknown_region (alloc_region_id (), &m_root_region, type);
  if (ctxt)
    ctxt->on_unexpected_tree_code (t, loc);
  return new_reg;
}

/* Return a new region describing a heap-allocated block of memory.  */

const region *
region_model_manager::create_region_for_heap_alloc ()
{
  region *reg
    = new heap_allocated_region (alloc_region_id (), &m_heap_region);
  m_managed_dynamic_regions.safe_push (reg);
  return reg;
}

/* Return a new region describing a block of memory allocated within FRAME.  */

const region *
region_model_manager::create_region_for_alloca (const frame_region *frame)
{
  gcc_assert (frame);
  region *reg = new alloca_region (alloc_region_id (), frame);
  m_managed_dynamic_regions.safe_push (reg);
  return reg;
}

/* Log OBJ to LOGGER.  */

template <typename T>
static void
log_managed_object (logger *logger, const T *obj)
{
  logger->start_log_line ();
  pretty_printer *pp = logger->get_printer ();
  pp_string (pp, "    ");
  obj->dump_to_pp (pp, true);
  logger->end_log_line ();
}

/* Specialization for frame_region, which also logs the count of locals
   managed by the frame_region.  */

template <>
void
log_managed_object (logger *logger, const frame_region *obj)
{
  logger->start_log_line ();
  pretty_printer *pp = logger->get_printer ();
  pp_string (pp, "    ");
  obj->dump_to_pp (pp, true);
  pp_printf (pp, " [with %i region(s) for locals]", obj->get_num_locals ());
  logger->end_log_line ();
}

/* Dump the number of objects that were managed by UNIQ_MAP to LOGGER.
   If SHOW_OBJS is true, also dump the objects themselves.  */

template <typename K, typename T>
static void
log_uniq_map (logger *logger, bool show_objs, const char *title,
	      const hash_map<K, T*> &uniq_map)
{
  logger->log ("  # %s: %li", title, (long)uniq_map.elements ());
  if (!show_objs)
    return;
  auto_vec<const T *> vec_objs (uniq_map.elements ());
  for (typename hash_map<K, T*>::iterator iter = uniq_map.begin ();
       iter != uniq_map.end (); ++iter)
    vec_objs.quick_push ((*iter).second);

  vec_objs.qsort (T::cmp_ptr_ptr);

  unsigned i;
  const T *obj;
  FOR_EACH_VEC_ELT (vec_objs, i, obj)
    log_managed_object<T> (logger, obj);
}

/* Dump the number of objects that were managed by MAP to LOGGER.
   If SHOW_OBJS is true, also dump the objects themselves.  */

template <typename T>
static void
log_uniq_map (logger *logger, bool show_objs, const char *title,
	      const consolidation_map<T> &map)
{
  logger->log ("  # %s: %li", title, (long)map.elements ());
  if (!show_objs)
    return;

  auto_vec<const T *> vec_objs (map.elements ());
  for (typename consolidation_map<T>::iterator iter = map.begin ();
       iter != map.end (); ++iter)
    vec_objs.quick_push ((*iter).second);

  vec_objs.qsort (T::cmp_ptr_ptr);

  unsigned i;
  const T *obj;
  FOR_EACH_VEC_ELT (vec_objs, i, obj)
    log_managed_object<T> (logger, obj);
}

/* Dump the number of objects of each class that were managed by this
   manager to LOGGER.
   If SHOW_OBJS is true, also dump the objects themselves.  */

void
region_model_manager::log_stats (logger *logger, bool show_objs) const
{
  LOG_SCOPE (logger);
  logger->log ("call string consolidation");
  m_empty_call_string.recursive_log (logger);
  logger->log ("svalue consolidation");
  log_uniq_map (logger, show_objs, "constant_svalue", m_constants_map);
  log_uniq_map (logger, show_objs, "unknown_svalue", m_unknowns_map);
  if (m_unknown_NULL)
    log_managed_object (logger, m_unknown_NULL);
  log_uniq_map (logger, show_objs, "poisoned_svalue", m_poisoned_values_map);
  log_uniq_map (logger, show_objs, "setjmp_svalue", m_setjmp_values_map);
  log_uniq_map (logger, show_objs, "initial_svalue", m_initial_values_map);
  log_uniq_map (logger, show_objs, "region_svalue", m_pointer_values_map);
  log_uniq_map (logger, show_objs, "unaryop_svalue", m_unaryop_values_map);
  log_uniq_map (logger, show_objs, "binop_svalue", m_binop_values_map);
  log_uniq_map (logger, show_objs, "sub_svalue", m_sub_values_map);
  log_uniq_map (logger, show_objs, "repeated_svalue", m_repeated_values_map);
  log_uniq_map (logger, show_objs, "bits_within_svalue",
		m_bits_within_values_map);
  log_uniq_map (logger, show_objs, "unmergeable_svalue",
		m_unmergeable_values_map);
  log_uniq_map (logger, show_objs, "widening_svalue", m_widening_values_map);
  log_uniq_map (logger, show_objs, "compound_svalue", m_compound_values_map);
  log_uniq_map (logger, show_objs, "conjured_svalue", m_conjured_values_map);
  log_uniq_map (logger, show_objs, "asm_output_svalue",
		m_asm_output_values_map);
  log_uniq_map (logger, show_objs, "const_fn_result_svalue",
		m_const_fn_result_values_map);

  logger->log ("max accepted svalue num_nodes: %i",
	       m_max_complexity.m_num_nodes);
  logger->log ("max accepted svalue max_depth: %i",
	       m_max_complexity.m_max_depth);

  logger->log ("region consolidation");
  logger->log ("  next region id: %i", m_next_region_id);
  log_uniq_map (logger, show_objs, "function_region", m_fndecls_map);
  log_uniq_map (logger, show_objs, "label_region", m_labels_map);
  log_uniq_map (logger, show_objs, "decl_region for globals", m_globals_map);
  log_uniq_map (logger, show_objs, "field_region", m_field_regions);
  log_uniq_map (logger, show_objs, "element_region", m_element_regions);
  log_uniq_map (logger, show_objs, "offset_region", m_offset_regions);
  log_uniq_map (logger, show_objs, "sized_region", m_sized_regions);
  log_uniq_map (logger, show_objs, "cast_region", m_cast_regions);
  log_uniq_map (logger, show_objs, "frame_region", m_frame_regions);
  log_uniq_map (logger, show_objs, "symbolic_region", m_symbolic_regions);
  log_uniq_map (logger, show_objs, "string_region", m_string_map);
  log_uniq_map (logger, show_objs, "bit_range_region", m_bit_range_regions);
  log_uniq_map (logger, show_objs, "var_arg_region", m_var_arg_regions);
  logger->log ("  # managed dynamic regions: %i",
	       m_managed_dynamic_regions.length ());
  m_store_mgr.log_stats (logger, show_objs);
  m_range_mgr->log_stats (logger, show_objs);
}

/* Dump the number of objects of each class that were managed by this
   manager to LOGGER.
   If SHOW_OBJS is true, also dump the objects themselves.
   This is here so it can use log_uniq_map.  */

void
store_manager::log_stats (logger *logger, bool show_objs) const
{
  LOG_SCOPE (logger);
  log_uniq_map (logger, show_objs, "concrete_binding",
		m_concrete_binding_key_mgr);
  log_uniq_map (logger, show_objs, "symbolic_binding",
		m_symbolic_binding_key_mgr);
}

/* Emit a warning showing DECL_REG->tracked_p () for use in DejaGnu tests
   (using -fdump-analyzer-untracked).  */

static void
dump_untracked_region (const decl_region *decl_reg)
{
  tree decl = decl_reg->get_decl ();
  if (TREE_CODE (decl) != VAR_DECL)
    return;
  /* For now, don't emit the status of decls in the constant pool, to avoid
     differences in DejaGnu test results between targets that use these vs
     those that don't.
     (Eventually these decls should probably be untracked and we should test
     for that, but that's not stage 4 material).  */
  if (DECL_IN_CONSTANT_POOL (decl))
    return;
  warning_at (DECL_SOURCE_LOCATION (decl), 0,
	      "track %qD: %s",
	      decl, (decl_reg->tracked_p () ? "yes" : "no"));
}

/* Implementation of -fdump-analyzer-untracked.  */

void
region_model_manager::dump_untracked_regions () const
{
  for (auto iter : m_globals_map)
    {
      const decl_region *decl_reg = iter.second;
      dump_untracked_region (decl_reg);
    }
  for (auto frame_iter : m_frame_regions)
    {
      const frame_region *frame_reg = frame_iter.second;
      frame_reg->dump_untracked_regions ();
    }
}

void
frame_region::dump_untracked_regions () const
{
  for (auto iter : m_locals)
    {
      const decl_region *decl_reg = iter.second;
      dump_untracked_region (decl_reg);
    }
}

} // namespace ana

#endif /* #if ENABLE_ANALYZER */
