/* __builtin_object_size (ptr, object_size_type) computation
   Copyright (C) 2004-2022 Free Software Foundation, Inc.
   Contributed by Jakub Jelinek <jakub@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"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "fold-const.h"
#include "tree-object-size.h"
#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "tree-cfg.h"
#include "tree-dfa.h"
#include "stringpool.h"
#include "attribs.h"
#include "builtins.h"
#include "gimplify-me.h"

struct object_size_info
{
  int object_size_type;
  unsigned char pass;
  bool changed;
  bitmap visited, reexamine, unknowns;
  unsigned int *depths;
  unsigned int *stack, *tos;
};

struct GTY(()) object_size
{
  /* Estimate of bytes till the end of the object.  */
  tree size;
  /* Estimate of the size of the whole object.  */
  tree wholesize;
};

static tree compute_object_offset (const_tree, const_tree);
static bool addr_object_size (struct object_size_info *,
			      const_tree, int, tree *, tree *t = NULL);
static tree alloc_object_size (const gcall *, int);
static tree pass_through_call (const gcall *);
static void collect_object_sizes_for (struct object_size_info *, tree);
static void expr_object_size (struct object_size_info *, tree, tree);
static bool merge_object_sizes (struct object_size_info *, tree, tree);
static bool plus_stmt_object_size (struct object_size_info *, tree, gimple *);
static bool cond_expr_object_size (struct object_size_info *, tree, gimple *);
static void init_offset_limit (void);
static void check_for_plus_in_loops (struct object_size_info *, tree);
static void check_for_plus_in_loops_1 (struct object_size_info *, tree,
				       unsigned int);

/* object_sizes[0] is upper bound for the object size and number of bytes till
   the end of the object.
   object_sizes[1] is upper bound for the object size and number of bytes till
   the end of the subobject (innermost array or field with address taken).
   object_sizes[2] is lower bound for the object size and number of bytes till
   the end of the object and object_sizes[3] lower bound for subobject.

   For static object sizes, the object size and the bytes till the end of the
   object are both INTEGER_CST.  In the dynamic case, they are finally either a
   gimple variable or an INTEGER_CST.  */
static vec<object_size> object_sizes[OST_END];

/* Bitmaps what object sizes have been computed already.  */
static bitmap computed[OST_END];

/* Maximum value of offset we consider to be addition.  */
static unsigned HOST_WIDE_INT offset_limit;

/* Tell the generic SSA updater what kind of update is needed after the pass
   executes.  */
static unsigned todo;

/* Return true if VAL represents an initial size for OBJECT_SIZE_TYPE.  */

static inline bool
size_initval_p (tree val, int object_size_type)
{
  return ((object_size_type & OST_MINIMUM)
	  ? integer_all_onesp (val) : integer_zerop (val));
}

/* Return true if VAL represents an unknown size for OBJECT_SIZE_TYPE.  */

static inline bool
size_unknown_p (tree val, int object_size_type)
{
  return ((object_size_type & OST_MINIMUM)
	  ? integer_zerop (val) : integer_all_onesp (val));
}

/* Return true if VAL represents a valid size for OBJECT_SIZE_TYPE.  */

static inline bool
size_valid_p (tree val, int object_size_type)
{
  return ((object_size_type & OST_DYNAMIC) || TREE_CODE (val) == INTEGER_CST);
}

/* Return true if VAL is usable as an object size in the object_sizes
   vectors.  */

static inline bool
size_usable_p (tree val)
{
  return TREE_CODE (val) == SSA_NAME || TREE_CODE (val) == INTEGER_CST;
}

/* Return a tree with initial value for OBJECT_SIZE_TYPE.  */

static inline tree
size_initval (int object_size_type)
{
  return ((object_size_type & OST_MINIMUM)
	  ? TYPE_MAX_VALUE (sizetype) : size_zero_node);
}

/* Return a tree with unknown value for OBJECT_SIZE_TYPE.  */

static inline tree
size_unknown (int object_size_type)
{
  return ((object_size_type & OST_MINIMUM)
	  ? size_zero_node : TYPE_MAX_VALUE (sizetype));
}

/* Grow object_sizes[OBJECT_SIZE_TYPE] to num_ssa_names.  */

static inline void
object_sizes_grow (int object_size_type)
{
  if (num_ssa_names > object_sizes[object_size_type].length ())
    object_sizes[object_size_type].safe_grow (num_ssa_names, true);
}

/* Release object_sizes[OBJECT_SIZE_TYPE].  */

static inline void
object_sizes_release (int object_size_type)
{
  object_sizes[object_size_type].release ();
}

/* Return true if object_sizes[OBJECT_SIZE_TYPE][VARNO] is unknown.  */

static inline bool
object_sizes_unknown_p (int object_size_type, unsigned varno)
{
  return size_unknown_p (object_sizes[object_size_type][varno].size,
			 object_size_type);
}

/* Return the raw size expression for VARNO corresponding to OSI.  This returns
   the TREE_VEC as is and should only be used during gimplification.  */

static inline object_size
object_sizes_get_raw (struct object_size_info *osi, unsigned varno)
{
  gcc_assert (osi->pass != 0);
  return object_sizes[osi->object_size_type][varno];
}

/* Return a size tree for VARNO corresponding to OSI.  If WHOLE is true, return
   the whole object size.  Use this for building size expressions based on size
   of VARNO.  */

static inline tree
object_sizes_get (struct object_size_info *osi, unsigned varno,
		  bool whole = false)
{
  tree ret;
  int object_size_type = osi->object_size_type;

  if (whole)
    ret = object_sizes[object_size_type][varno].wholesize;
  else
    ret = object_sizes[object_size_type][varno].size;

  if (object_size_type & OST_DYNAMIC)
    {
      if (TREE_CODE (ret) == MODIFY_EXPR)
	return TREE_OPERAND (ret, 0);
      else if (TREE_CODE (ret) == TREE_VEC)
	return TREE_VEC_ELT (ret, TREE_VEC_LENGTH (ret) - 1);
      else
	gcc_checking_assert (size_usable_p (ret));
    }

  return ret;
}

/* Set size for VARNO corresponding to OSI to VAL.  */

static inline void
object_sizes_initialize (struct object_size_info *osi, unsigned varno,
			 tree val, tree wholeval)
{
  int object_size_type = osi->object_size_type;

  object_sizes[object_size_type][varno].size = val;
  object_sizes[object_size_type][varno].wholesize = wholeval;
}

/* Return a MODIFY_EXPR for cases where SSA and EXPR have the same type.  The
   TREE_VEC is returned only in case of PHI nodes.  */

static tree
bundle_sizes (tree name, tree expr)
{
  gcc_checking_assert (TREE_TYPE (name) == sizetype);

  if (TREE_CODE (expr) == TREE_VEC)
    {
      TREE_VEC_ELT (expr, TREE_VEC_LENGTH (expr) - 1) = name;
      return expr;
    }

  gcc_checking_assert (types_compatible_p (TREE_TYPE (expr), sizetype));
  return build2 (MODIFY_EXPR, sizetype, name, expr);
}

/* Set size for VARNO corresponding to OSI to VAL if it is the new minimum or
   maximum.  For static sizes, each element of TREE_VEC is always INTEGER_CST
   throughout the computation.  For dynamic sizes, each element may either be a
   gimple variable, a MODIFY_EXPR or a TREE_VEC.  The MODIFY_EXPR is for
   expressions that need to be gimplified.  TREE_VECs are special, they're
   emitted only for GIMPLE_PHI and the PHI result variable is the last element
   of the vector.  */

static bool
object_sizes_set (struct object_size_info *osi, unsigned varno, tree val,
		  tree wholeval)
{
  int object_size_type = osi->object_size_type;
  object_size osize = object_sizes[object_size_type][varno];
  bool changed = true;

  tree oldval = osize.size;
  tree old_wholeval = osize.wholesize;

  if (object_size_type & OST_DYNAMIC)
    {
      if (bitmap_bit_p (osi->reexamine, varno))
	{
	  if (size_unknown_p (val, object_size_type))
	    {
	      oldval = object_sizes_get (osi, varno);
	      old_wholeval = object_sizes_get (osi, varno, true);
	      bitmap_set_bit (osi->unknowns, SSA_NAME_VERSION (oldval));
	      bitmap_set_bit (osi->unknowns, SSA_NAME_VERSION (old_wholeval));
	      bitmap_clear_bit (osi->reexamine, varno);
	    }
	  else
	    {
	      val = bundle_sizes (oldval, val);
	      wholeval = bundle_sizes (old_wholeval, wholeval);
	    }
	}
      else
	{
	  gcc_checking_assert (size_initval_p (oldval, object_size_type));
	  gcc_checking_assert (size_initval_p (old_wholeval,
					       object_size_type));
	  /* For dynamic object sizes, all object sizes that are not gimple
	     variables will need to be gimplified.  */
	  if (wholeval != val && !size_usable_p (wholeval))
	    {
	      bitmap_set_bit (osi->reexamine, varno);
	      wholeval = bundle_sizes (make_ssa_name (sizetype), wholeval);
	    }
	  if (!size_usable_p (val))
	    {
	      bitmap_set_bit (osi->reexamine, varno);
	      tree newval = bundle_sizes (make_ssa_name (sizetype), val);
	      if (val == wholeval)
		wholeval = newval;
	      val = newval;
	    }
	  /* If the new value is a temporary variable, mark it for
	     reexamination.  */
	  else if (TREE_CODE (val) == SSA_NAME && !SSA_NAME_DEF_STMT (val))
	    bitmap_set_bit (osi->reexamine, varno);
	}
    }
  else
    {
      enum tree_code code = (object_size_type & OST_MINIMUM
			     ? MIN_EXPR : MAX_EXPR);

      val = size_binop (code, val, oldval);
      wholeval = size_binop (code, wholeval, old_wholeval);
      changed = (tree_int_cst_compare (val, oldval) != 0
		 || tree_int_cst_compare (old_wholeval, wholeval) != 0);
    }

  object_sizes[object_size_type][varno].size = val;
  object_sizes[object_size_type][varno].wholesize = wholeval;

  return changed;
}

/* Set temporary SSA names for object size and whole size to resolve dependency
   loops in dynamic size computation.  */

static inline void
object_sizes_set_temp (struct object_size_info *osi, unsigned varno)
{
  tree val = object_sizes_get (osi, varno);

  if (size_initval_p (val, osi->object_size_type))
    object_sizes_set (osi, varno,
		      make_ssa_name (sizetype),
		      make_ssa_name (sizetype));
}

/* Initialize OFFSET_LIMIT variable.  */
static void
init_offset_limit (void)
{
  if (tree_fits_uhwi_p (TYPE_MAX_VALUE (sizetype)))
    offset_limit = tree_to_uhwi (TYPE_MAX_VALUE (sizetype));
  else
    offset_limit = -1;
  offset_limit /= 2;
}

/* Bytes at end of the object with SZ from offset OFFSET.  If WHOLESIZE is not
   NULL_TREE, use it to get the net offset of the pointer, which should always
   be positive and hence, be within OFFSET_LIMIT for valid offsets.  */

static tree
size_for_offset (tree sz, tree offset, tree wholesize = NULL_TREE)
{
  gcc_checking_assert (types_compatible_p (TREE_TYPE (sz), sizetype));

  /* For negative offsets, if we have a distinct WHOLESIZE, use it to get a net
     offset from the whole object.  */
  if (wholesize && wholesize != sz
      && (TREE_CODE (sz) != INTEGER_CST
	  || TREE_CODE (wholesize) != INTEGER_CST
	  || tree_int_cst_compare (sz, wholesize)))
    {
      gcc_checking_assert (types_compatible_p (TREE_TYPE (wholesize),
					       sizetype));

      /* Restructure SZ - OFFSET as
	 WHOLESIZE - (WHOLESIZE + OFFSET - SZ) so that the offset part, i.e.
	 WHOLESIZE + OFFSET - SZ is only allowed to be positive.  */
      tree tmp = size_binop (MAX_EXPR, wholesize, sz);
      offset = fold_build2 (PLUS_EXPR, sizetype, tmp, offset);
      offset = fold_build2 (MINUS_EXPR, sizetype, offset, sz);
      sz = tmp;
    }

  /* Safe to convert now, since a valid net offset should be non-negative.  */
  if (!useless_type_conversion_p (sizetype, TREE_TYPE (offset)))
    offset = fold_convert (sizetype, offset);

  if (TREE_CODE (offset) == INTEGER_CST)
    {
      if (integer_zerop (offset))
	return sz;

      /* Negative or too large offset even after adjustment, cannot be within
	 bounds of an object.  */
      if (compare_tree_int (offset, offset_limit) > 0)
	return size_zero_node;
    }

  return size_binop (MINUS_EXPR, size_binop (MAX_EXPR, sz, offset), offset);
}

/* Compute offset of EXPR within VAR.  Return error_mark_node
   if unknown.  */

static tree
compute_object_offset (const_tree expr, const_tree var)
{
  enum tree_code code = PLUS_EXPR;
  tree base, off, t;

  if (expr == var)
    return size_zero_node;

  switch (TREE_CODE (expr))
    {
    case COMPONENT_REF:
      base = compute_object_offset (TREE_OPERAND (expr, 0), var);
      if (base == error_mark_node)
	return base;

      t = TREE_OPERAND (expr, 1);
      off = size_binop (PLUS_EXPR, DECL_FIELD_OFFSET (t),
			size_int (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (t))
				  / BITS_PER_UNIT));
      break;

    case REALPART_EXPR:
    CASE_CONVERT:
    case VIEW_CONVERT_EXPR:
    case NON_LVALUE_EXPR:
      return compute_object_offset (TREE_OPERAND (expr, 0), var);

    case IMAGPART_EXPR:
      base = compute_object_offset (TREE_OPERAND (expr, 0), var);
      if (base == error_mark_node)
	return base;

      off = TYPE_SIZE_UNIT (TREE_TYPE (expr));
      break;

    case ARRAY_REF:
      base = compute_object_offset (TREE_OPERAND (expr, 0), var);
      if (base == error_mark_node)
	return base;

      t = TREE_OPERAND (expr, 1);
      tree low_bound, unit_size;
      low_bound = array_ref_low_bound (CONST_CAST_TREE (expr));
      unit_size = array_ref_element_size (CONST_CAST_TREE (expr));
      if (! integer_zerop (low_bound))
	t = fold_build2 (MINUS_EXPR, TREE_TYPE (t), t, low_bound);
      if (TREE_CODE (t) == INTEGER_CST && tree_int_cst_sgn (t) < 0)
	{
	  code = MINUS_EXPR;
	  t = fold_build1 (NEGATE_EXPR, TREE_TYPE (t), t);
	}
      t = fold_convert (sizetype, t);
      off = size_binop (MULT_EXPR, unit_size, t);
      break;

    case MEM_REF:
      gcc_assert (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR);
      return wide_int_to_tree (sizetype, mem_ref_offset (expr));

    default:
      return error_mark_node;
    }

  return size_binop (code, base, off);
}

/* Returns the size of the object designated by DECL considering its
   initializer if it either has one or if it would not affect its size,
   otherwise the size of the object without the initializer when MIN
   is true, else null.  An object's initializer affects the object's
   size if it's a struct type with a flexible array member.  */

tree
decl_init_size (tree decl, bool min)
{
  tree size = DECL_SIZE_UNIT (decl);
  tree type = TREE_TYPE (decl);
  if (TREE_CODE (type) != RECORD_TYPE)
    return size;

  tree last = last_field (type);
  if (!last)
    return size;

  tree last_type = TREE_TYPE (last);
  if (TREE_CODE (last_type) != ARRAY_TYPE
      || TYPE_SIZE (last_type))
    return size;

  /* Use TYPE_SIZE_UNIT; DECL_SIZE_UNIT sometimes reflects the size
     of the initializer and sometimes doesn't.  */
  size = TYPE_SIZE_UNIT (type);
  tree ref = build3 (COMPONENT_REF, type, decl, last, NULL_TREE);
  tree compsize = component_ref_size (ref);
  if (!compsize)
    return min ? size : NULL_TREE;

  /* The size includes tail padding and initializer elements.  */
  tree pos = byte_position (last);
  size = fold_build2 (PLUS_EXPR, TREE_TYPE (size), pos, compsize);
  return size;
}

/* Compute __builtin_object_size for PTR, which is a ADDR_EXPR.
   OBJECT_SIZE_TYPE is the second argument from __builtin_object_size.
   If unknown, return size_unknown (object_size_type).  */

static bool
addr_object_size (struct object_size_info *osi, const_tree ptr,
		  int object_size_type, tree *psize, tree *pwholesize)
{
  tree pt_var, pt_var_size = NULL_TREE, pt_var_wholesize = NULL_TREE;
  tree var_size, bytes, wholebytes;

  gcc_assert (TREE_CODE (ptr) == ADDR_EXPR);

  /* Set to unknown and overwrite just before returning if the size
     could be determined.  */
  *psize = size_unknown (object_size_type);
  if (pwholesize)
    *pwholesize = size_unknown (object_size_type);

  pt_var = TREE_OPERAND (ptr, 0);
  while (handled_component_p (pt_var))
    pt_var = TREE_OPERAND (pt_var, 0);

  if (!pt_var)
    return false;

  if (TREE_CODE (pt_var) == MEM_REF)
    {
      tree sz, wholesize;

      if (!osi || (object_size_type & OST_SUBOBJECT) != 0
	  || TREE_CODE (TREE_OPERAND (pt_var, 0)) != SSA_NAME)
	{
	  compute_builtin_object_size (TREE_OPERAND (pt_var, 0),
				       object_size_type & ~OST_SUBOBJECT, &sz);
	  wholesize = sz;
	}
      else
	{
	  tree var = TREE_OPERAND (pt_var, 0);
	  if (osi->pass == 0)
	    collect_object_sizes_for (osi, var);
	  if (bitmap_bit_p (computed[object_size_type],
			    SSA_NAME_VERSION (var)))
	    {
	      sz = object_sizes_get (osi, SSA_NAME_VERSION (var));
	      wholesize = object_sizes_get (osi, SSA_NAME_VERSION (var), true);
	    }
	  else
	    sz = wholesize = size_unknown (object_size_type);
	}
      if (!size_unknown_p (sz, object_size_type))
	sz = size_for_offset (sz, TREE_OPERAND (pt_var, 1), wholesize);

      if (!size_unknown_p (sz, object_size_type)
	  && (TREE_CODE (sz) != INTEGER_CST
	      || compare_tree_int (sz, offset_limit) < 0))
	{
	  pt_var_size = sz;
	  pt_var_wholesize = wholesize;
	}
    }
  else if (DECL_P (pt_var))
    {
      pt_var_size = pt_var_wholesize
	= decl_init_size (pt_var, object_size_type & OST_MINIMUM);
      if (!pt_var_size)
	return false;
    }
  else if (TREE_CODE (pt_var) == STRING_CST)
    pt_var_size = pt_var_wholesize = TYPE_SIZE_UNIT (TREE_TYPE (pt_var));
  else
    return false;

  if (pt_var_size)
    {
      /* Validate the size determined above if it is a constant.  */
      if (TREE_CODE (pt_var_size) == INTEGER_CST
	  && compare_tree_int (pt_var_size, offset_limit) >= 0)
	return false;
    }

  if (pt_var != TREE_OPERAND (ptr, 0))
    {
      tree var;

      if (object_size_type & OST_SUBOBJECT)
	{
	  var = TREE_OPERAND (ptr, 0);

	  while (var != pt_var
		 && TREE_CODE (var) != BIT_FIELD_REF
		 && TREE_CODE (var) != COMPONENT_REF
		 && TREE_CODE (var) != ARRAY_REF
		 && TREE_CODE (var) != ARRAY_RANGE_REF
		 && TREE_CODE (var) != REALPART_EXPR
		 && TREE_CODE (var) != IMAGPART_EXPR)
	    var = TREE_OPERAND (var, 0);
	  if (var != pt_var && TREE_CODE (var) == ARRAY_REF)
	    var = TREE_OPERAND (var, 0);
	  if (! TYPE_SIZE_UNIT (TREE_TYPE (var))
	      || ! tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (var)))
	      || (pt_var_size && TREE_CODE (pt_var_size) == INTEGER_CST
		  && tree_int_cst_lt (pt_var_size,
				      TYPE_SIZE_UNIT (TREE_TYPE (var)))))
	    var = pt_var;
	  else if (var != pt_var && TREE_CODE (pt_var) == MEM_REF)
	    {
	      tree v = var;
	      /* For &X->fld, compute object size if fld isn't a flexible array
		 member.  */
	      bool is_flexible_array_mem_ref = false;
	      while (v && v != pt_var)
		switch (TREE_CODE (v))
		  {
		  case ARRAY_REF:
		    if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_OPERAND (v, 0))))
		      {
			tree domain
			  = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (v, 0)));
			if (domain && TYPE_MAX_VALUE (domain))
			  {
			    v = NULL_TREE;
			    break;
			  }
		      }
		    v = TREE_OPERAND (v, 0);
		    break;
		  case REALPART_EXPR:
		  case IMAGPART_EXPR:
		    v = NULL_TREE;
		    break;
		  case COMPONENT_REF:
		    if (TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE)
		      {
			v = NULL_TREE;
			break;
		      }
		    is_flexible_array_mem_ref = array_ref_flexible_size_p (v);
		    while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
		      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
			  != UNION_TYPE
			  && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
			  != QUAL_UNION_TYPE)
			break;
		      else
			v = TREE_OPERAND (v, 0);
		    if (TREE_CODE (v) == COMPONENT_REF
			&& TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
			   == RECORD_TYPE)
		      {
			/* compute object size only if v is not a
			   flexible array member.  */
			if (!is_flexible_array_mem_ref)
			  {
			    v = NULL_TREE;
			    break;
			  }
			v = TREE_OPERAND (v, 0);
		      }
		    while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
		      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
			  != UNION_TYPE
			  && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
			  != QUAL_UNION_TYPE)
			break;
		      else
			v = TREE_OPERAND (v, 0);
		    if (v != pt_var)
		      v = NULL_TREE;
		    else
		      v = pt_var;
		    break;
		  default:
		    v = pt_var;
		    break;
		  }
	      if (v == pt_var)
		var = pt_var;
	    }
	}
      else
	var = pt_var;

      if (var != pt_var)
	{
	  var_size = TYPE_SIZE_UNIT (TREE_TYPE (var));
	  if (!TREE_CONSTANT (var_size))
	    var_size = get_or_create_ssa_default_def (cfun, var_size);
	  if (!var_size)
	    return false;
	}
      else if (!pt_var_size)
	return false;
      else
	var_size = pt_var_size;
      bytes = compute_object_offset (TREE_OPERAND (ptr, 0), var);
      if (bytes != error_mark_node)
	{
	  bytes = size_for_offset (var_size, bytes);
	  if (var != pt_var && pt_var_size && TREE_CODE (pt_var) == MEM_REF)
	    {
	      tree bytes2 = compute_object_offset (TREE_OPERAND (ptr, 0),
						   pt_var);
	      if (bytes2 != error_mark_node)
		{
		  bytes2 = size_for_offset (pt_var_size, bytes2);
		  bytes = size_binop (MIN_EXPR, bytes, bytes2);
		}
	    }
	}
      else
	bytes = size_unknown (object_size_type);

      wholebytes
	= object_size_type & OST_SUBOBJECT ? var_size : pt_var_wholesize;
    }
  else if (!pt_var_size)
    return false;
  else
    {
      bytes = pt_var_size;
      wholebytes = pt_var_wholesize;
    }

  if (!size_unknown_p (bytes, object_size_type)
      && size_valid_p (bytes, object_size_type)
      && !size_unknown_p (bytes, object_size_type)
      && size_valid_p (wholebytes, object_size_type))
    {
      *psize = bytes;
      if (pwholesize)
	*pwholesize = wholebytes;
      return true;
    }

  return false;
}


/* Compute __builtin_object_size for CALL, which is a GIMPLE_CALL.
   Handles calls to functions declared with attribute alloc_size.
   OBJECT_SIZE_TYPE is the second argument from __builtin_object_size.
   If unknown, return size_unknown (object_size_type).  */

static tree
alloc_object_size (const gcall *call, int object_size_type)
{
  gcc_assert (is_gimple_call (call));

  tree calltype;
  tree callfn = gimple_call_fndecl (call);
  if (callfn)
    calltype = TREE_TYPE (callfn);
  else
    calltype = gimple_call_fntype (call);

  if (!calltype)
    return size_unknown (object_size_type);

  /* Set to positions of alloc_size arguments.  */
  int arg1 = -1, arg2 = -1;
  tree alloc_size = lookup_attribute ("alloc_size",
				      TYPE_ATTRIBUTES (calltype));
  if (alloc_size && TREE_VALUE (alloc_size))
    {
      tree p = TREE_VALUE (alloc_size);

      arg1 = TREE_INT_CST_LOW (TREE_VALUE (p))-1;
      if (TREE_CHAIN (p))
        arg2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (p)))-1;
    }
  else if (gimple_call_builtin_p (call, BUILT_IN_NORMAL)
	   && callfn && ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callfn)))
  arg1 = 0;

  /* Non-const arguments are OK here, let the caller handle constness.  */
  if (arg1 < 0 || arg1 >= (int) gimple_call_num_args (call)
      || arg2 >= (int) gimple_call_num_args (call))
    return size_unknown (object_size_type);

  tree bytes = NULL_TREE;
  if (arg2 >= 0)
    bytes = size_binop (MULT_EXPR,
	fold_convert (sizetype, gimple_call_arg (call, arg1)),
	fold_convert (sizetype, gimple_call_arg (call, arg2)));
  else if (arg1 >= 0)
    bytes = fold_convert (sizetype, gimple_call_arg (call, arg1));

  return bytes ? bytes : size_unknown (object_size_type);
}

/* Compute __builtin_object_size for CALL, which is a call to either
   BUILT_IN_STRDUP or BUILT_IN_STRNDUP; IS_STRNDUP indicates which it is.
   OBJECT_SIZE_TYPE is the second argument from __builtin_object_size.
   If unknown, return size_unknown (object_size_type).  */

static tree
strdup_object_size (const gcall *call, int object_size_type, bool is_strndup)
{
  tree src = gimple_call_arg (call, 0);
  tree sz = size_unknown (object_size_type);
  tree n = NULL_TREE;

  if (is_strndup)
    n = fold_build2 (PLUS_EXPR, sizetype, size_one_node,
		     gimple_call_arg (call, 1));
  /* For strdup, simply emit strlen (SRC) + 1 and let the optimizer fold it the
     way it likes.  */
  else
    {
      tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
      if (strlen_fn)
	{
	  sz = fold_build2 (PLUS_EXPR, sizetype, size_one_node,
			    build_call_expr (strlen_fn, 1, src));
	  todo = TODO_update_ssa_only_virtuals;
	}
    }

  /* In all other cases, return the size of SRC since the object size cannot
     exceed that.  We cannot do this for OST_MINIMUM unless SRC points into a
     string constant since otherwise the object size could go all the way down
     to zero.  */
  if (!size_valid_p (sz, object_size_type)
       || size_unknown_p (sz, object_size_type))
    {
      tree wholesrc = NULL_TREE;
      if (TREE_CODE (src) == ADDR_EXPR)
	wholesrc = get_base_address (TREE_OPERAND (src, 0));

      /* If the source points within a string constant, we try to get its
	 length.  */
      if (wholesrc && TREE_CODE (wholesrc) == STRING_CST)
	{
	  tree len = c_strlen (src, 0);
	  if (len)
	    sz = fold_build2 (PLUS_EXPR, sizetype, size_one_node, len);
	}

      /* For maximum estimate, our next best guess is the object size of the
	 source.  */
      if (size_unknown_p (sz, object_size_type)
	  && !(object_size_type & OST_MINIMUM))
	compute_builtin_object_size (src, object_size_type, &sz);
    }

  /* String duplication allocates at least one byte, so we should never fail
     for OST_MINIMUM.  */
  if ((!size_valid_p (sz, object_size_type)
       || size_unknown_p (sz, object_size_type))
      && (object_size_type & OST_MINIMUM))
    sz = size_one_node;

  /* Factor in the N.  */
  return n ? fold_build2 (MIN_EXPR, sizetype, n, sz) : sz;
}

/* If object size is propagated from one of function's arguments directly
   to its return value, return that argument for GIMPLE_CALL statement CALL.
   Otherwise return NULL.  */

static tree
pass_through_call (const gcall *call)
{
  unsigned rf = gimple_call_return_flags (call);
  if (rf & ERF_RETURNS_ARG)
    {
      unsigned argnum = rf & ERF_RETURN_ARG_MASK;
      if (argnum < gimple_call_num_args (call))
	return gimple_call_arg (call, argnum);
    }

  /* __builtin_assume_aligned is intentionally not marked RET1.  */
  if (gimple_call_builtin_p (call, BUILT_IN_ASSUME_ALIGNED))
    return gimple_call_arg (call, 0);

  return NULL_TREE;
}

/* Emit PHI nodes for size expressions fo.  */

static void
emit_phi_nodes (gimple *stmt, tree size, tree wholesize)
{
  tree phires;
  gphi *wholephi = NULL;

  if (wholesize != size)
    {
      phires = TREE_VEC_ELT (wholesize, TREE_VEC_LENGTH (wholesize) - 1);
      wholephi = create_phi_node (phires, gimple_bb (stmt));
    }

  phires = TREE_VEC_ELT (size, TREE_VEC_LENGTH (size) - 1);
  gphi *phi = create_phi_node (phires, gimple_bb (stmt));
  gphi *obj_phi = as_a <gphi *> (stmt);

  gcc_checking_assert (TREE_CODE (wholesize) == TREE_VEC);
  gcc_checking_assert (TREE_CODE (size) == TREE_VEC);

  for (unsigned i = 0; i < gimple_phi_num_args (stmt); i++)
    {
      gimple_seq seq = NULL;
      tree wsz = TREE_VEC_ELT (wholesize, i);
      tree sz = TREE_VEC_ELT (size, i);

      /* If we built an expression, we will need to build statements
	 and insert them on the edge right away.  */
      if (TREE_CODE (wsz) != SSA_NAME)
	wsz = force_gimple_operand (wsz, &seq, true, NULL);
      if (TREE_CODE (sz) != SSA_NAME)
	{
	  gimple_seq s;
	  sz = force_gimple_operand (sz, &s, true, NULL);
	  gimple_seq_add_seq (&seq, s);
	}

      if (seq)
	gsi_insert_seq_on_edge (gimple_phi_arg_edge (obj_phi, i), seq);

      if (wholephi)
	add_phi_arg (wholephi, wsz,
		     gimple_phi_arg_edge (obj_phi, i),
		     gimple_phi_arg_location (obj_phi, i));

      add_phi_arg (phi, sz,
		   gimple_phi_arg_edge (obj_phi, i),
		   gimple_phi_arg_location (obj_phi, i));
    }
}

/* Descend through EXPR and return size_unknown if it uses any SSA variable
   object_size_set or object_size_set_temp generated, which turned out to be
   size_unknown, as noted in UNKNOWNS.  */

static tree
propagate_unknowns (object_size_info *osi, tree expr)
{
  int object_size_type = osi->object_size_type;

  switch (TREE_CODE (expr))
    {
    case SSA_NAME:
      if (bitmap_bit_p (osi->unknowns, SSA_NAME_VERSION (expr)))
	return size_unknown (object_size_type);
      return expr;

    case MIN_EXPR:
    case MAX_EXPR:
	{
	  tree res = propagate_unknowns (osi, TREE_OPERAND (expr, 0));
	  if (size_unknown_p (res, object_size_type))
	    return res;

	  res = propagate_unknowns (osi, TREE_OPERAND (expr, 1));
	  if (size_unknown_p (res, object_size_type))
	    return res;

	  return expr;
	}
    case MODIFY_EXPR:
	{
	  tree res = propagate_unknowns (osi, TREE_OPERAND (expr, 1));
	  if (size_unknown_p (res, object_size_type))
	    return res;
	  return expr;
	}
    case TREE_VEC:
      for (int i = 0; i < TREE_VEC_LENGTH (expr); i++)
	{
	  tree res = propagate_unknowns (osi, TREE_VEC_ELT (expr, i));
	  if (size_unknown_p (res, object_size_type))
	    return res;
	}
      return expr;
    case PLUS_EXPR:
    case MINUS_EXPR:
	{
	  tree res = propagate_unknowns (osi, TREE_OPERAND (expr, 0));
	  if (size_unknown_p (res, object_size_type))
	    return res;

	  return expr;
	}
    default:
      return expr;
    }
}

/* Walk through size expressions that need reexamination and generate
   statements for them.  */

static void
gimplify_size_expressions (object_size_info *osi)
{
  int object_size_type = osi->object_size_type;
  bitmap_iterator bi;
  unsigned int i;
  bool changed;

  /* Step 1: Propagate unknowns into expressions.  */
  bitmap reexamine = BITMAP_ALLOC (NULL);
  bitmap_copy (reexamine, osi->reexamine);
  do
    {
      changed = false;
      EXECUTE_IF_SET_IN_BITMAP (reexamine, 0, i, bi)
	{
	  object_size cur = object_sizes_get_raw (osi, i);

	  if (size_unknown_p (propagate_unknowns (osi, cur.size),
			      object_size_type)
	      || size_unknown_p (propagate_unknowns (osi, cur.wholesize),
				 object_size_type))
	    {
	      object_sizes_set (osi, i,
				size_unknown (object_size_type),
				size_unknown (object_size_type));
	      changed = true;
	    }
	}
      bitmap_copy (reexamine, osi->reexamine);
    }
  while (changed);

  /* Release all unknowns.  */
  EXECUTE_IF_SET_IN_BITMAP (osi->unknowns, 0, i, bi)
    release_ssa_name (ssa_name (i));

  /* Expand all size expressions to put their definitions close to the objects
     for which size is being computed.  */
  EXECUTE_IF_SET_IN_BITMAP (osi->reexamine, 0, i, bi)
    {
      gimple_seq seq = NULL;
      object_size osize = object_sizes_get_raw (osi, i);

      gimple *stmt = SSA_NAME_DEF_STMT (ssa_name (i));
      enum gimple_code code = gimple_code (stmt);

      /* PHI nodes need special attention.  */
      if (code == GIMPLE_PHI)
	emit_phi_nodes (stmt, osize.size, osize.wholesize);
      else
	{
	  tree size_expr = NULL_TREE;

	  /* Bundle wholesize in with the size to gimplify if needed.  */
	  if (osize.wholesize != osize.size
	      && !size_usable_p (osize.wholesize))
	    size_expr = size_binop (COMPOUND_EXPR,
				    osize.wholesize,
				    osize.size);
	  else if (!size_usable_p (osize.size))
	    size_expr = osize.size;

	  if (size_expr)
	    {
	      gimple_stmt_iterator gsi;
	      if (code == GIMPLE_NOP)
		gsi = gsi_start_bb (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
	      else
		gsi = gsi_for_stmt (stmt);

	      force_gimple_operand (size_expr, &seq, true, NULL);
	      gsi_insert_seq_before (&gsi, seq, GSI_CONTINUE_LINKING);
	    }
	}

      /* We're done, so replace the MODIFY_EXPRs with the SSA names.  */
      object_sizes_initialize (osi, i,
			       object_sizes_get (osi, i),
			       object_sizes_get (osi, i, true));
    }
}

/* Compute __builtin_object_size value for PTR and set *PSIZE to
   the resulting value.  If the declared object is known and PDECL
   is nonnull, sets *PDECL to the object's DECL.  OBJECT_SIZE_TYPE
   is the second argument   to __builtin_object_size.
   Returns true on success and false when the object size could not
   be determined.  */

bool
compute_builtin_object_size (tree ptr, int object_size_type,
			     tree *psize)
{
  gcc_assert (object_size_type >= 0 && object_size_type < OST_END);

  /* Set to unknown and overwrite just before returning if the size
     could be determined.  */
  *psize = size_unknown (object_size_type);

  if (! offset_limit)
    init_offset_limit ();

  if (TREE_CODE (ptr) == ADDR_EXPR)
    return addr_object_size (NULL, ptr, object_size_type, psize);

  if (TREE_CODE (ptr) != SSA_NAME
      || !POINTER_TYPE_P (TREE_TYPE (ptr)))
      return false;

  if (computed[object_size_type] == NULL)
    {
      if (optimize || object_size_type & OST_SUBOBJECT)
	return false;

      /* When not optimizing, rather than failing, make a small effort
	 to determine the object size without the full benefit of
	 the (costly) computation below.  */
      gimple *def = SSA_NAME_DEF_STMT (ptr);
      if (gimple_code (def) == GIMPLE_ASSIGN)
	{
	  tree_code code = gimple_assign_rhs_code (def);
	  if (code == POINTER_PLUS_EXPR)
	    {
	      tree offset = gimple_assign_rhs2 (def);
	      ptr = gimple_assign_rhs1 (def);

	      if (((object_size_type & OST_DYNAMIC)
		   || (tree_fits_shwi_p (offset)
		       && compare_tree_int (offset, offset_limit) <= 0))
		  && compute_builtin_object_size (ptr, object_size_type,
						  psize))
		{
		  *psize = size_for_offset (*psize, offset);
		  return true;
		}
	    }
	}
      return false;
    }

  struct object_size_info osi;
  osi.object_size_type = object_size_type;
  if (!bitmap_bit_p (computed[object_size_type], SSA_NAME_VERSION (ptr)))
    {
      bitmap_iterator bi;
      unsigned int i;

      object_sizes_grow (object_size_type);
      if (dump_file)
	{
	  fprintf (dump_file, "Computing %s %s%sobject size for ",
		   (object_size_type & OST_MINIMUM) ? "minimum" : "maximum",
		   (object_size_type & OST_DYNAMIC) ? "dynamic " : "",
		   (object_size_type & OST_SUBOBJECT) ? "sub" : "");
	  print_generic_expr (dump_file, ptr, dump_flags);
	  fprintf (dump_file, ":\n");
	}

      osi.visited = BITMAP_ALLOC (NULL);
      osi.reexamine = BITMAP_ALLOC (NULL);

      if (object_size_type & OST_DYNAMIC)
	osi.unknowns = BITMAP_ALLOC (NULL);
      else
	{
	  osi.depths = NULL;
	  osi.stack = NULL;
	  osi.tos = NULL;
	}

      /* First pass: walk UD chains, compute object sizes that
	 can be computed.  osi.reexamine bitmap at the end will
	 contain what variables were found in dependency cycles
	 and therefore need to be reexamined.  */
      osi.pass = 0;
      osi.changed = false;
      collect_object_sizes_for (&osi, ptr);

      if (object_size_type & OST_DYNAMIC)
	{
	  osi.pass = 1;
	  gimplify_size_expressions (&osi);
	  BITMAP_FREE (osi.unknowns);
	  bitmap_clear (osi.reexamine);
	}

      /* Second pass: keep recomputing object sizes of variables
	 that need reexamination, until no object sizes are
	 increased or all object sizes are computed.  */
      if (! bitmap_empty_p (osi.reexamine))
	{
	  bitmap reexamine = BITMAP_ALLOC (NULL);

	  /* If looking for minimum instead of maximum object size,
	     detect cases where a pointer is increased in a loop.
	     Although even without this detection pass 2 would eventually
	     terminate, it could take a long time.  If a pointer is
	     increasing this way, we need to assume 0 object size.
	     E.g. p = &buf[0]; while (cond) p = p + 4;  */
	  if (object_size_type & OST_MINIMUM)
	    {
	      osi.depths = XCNEWVEC (unsigned int, num_ssa_names);
	      osi.stack = XNEWVEC (unsigned int, num_ssa_names);
	      osi.tos = osi.stack;
	      osi.pass = 1;
	      /* collect_object_sizes_for is changing
		 osi.reexamine bitmap, so iterate over a copy.  */
	      bitmap_copy (reexamine, osi.reexamine);
	      EXECUTE_IF_SET_IN_BITMAP (reexamine, 0, i, bi)
		if (bitmap_bit_p (osi.reexamine, i))
		  check_for_plus_in_loops (&osi, ssa_name (i));

	      free (osi.depths);
	      osi.depths = NULL;
	      free (osi.stack);
	      osi.stack = NULL;
	      osi.tos = NULL;
	    }

	  do
	    {
	      osi.pass = 2;
	      osi.changed = false;
	      /* collect_object_sizes_for is changing
		 osi.reexamine bitmap, so iterate over a copy.  */
	      bitmap_copy (reexamine, osi.reexamine);
	      EXECUTE_IF_SET_IN_BITMAP (reexamine, 0, i, bi)
		if (bitmap_bit_p (osi.reexamine, i))
		  {
		    collect_object_sizes_for (&osi, ssa_name (i));
		    if (dump_file && (dump_flags & TDF_DETAILS))
		      {
			fprintf (dump_file, "Reexamining ");
			print_generic_expr (dump_file, ssa_name (i),
					    dump_flags);
			fprintf (dump_file, "\n");
		      }
		  }
	    }
	  while (osi.changed);

	  BITMAP_FREE (reexamine);
	}
      EXECUTE_IF_SET_IN_BITMAP (osi.reexamine, 0, i, bi)
	bitmap_set_bit (computed[object_size_type], i);

      /* Debugging dumps.  */
      if (dump_file)
	{
	  EXECUTE_IF_SET_IN_BITMAP (osi.visited, 0, i, bi)
	    if (!object_sizes_unknown_p (object_size_type, i))
	      {
		print_generic_expr (dump_file, ssa_name (i),
				    dump_flags);
		fprintf (dump_file,
			 ": %s %s%sobject size ",
			 ((object_size_type & OST_MINIMUM) ? "minimum"
			  : "maximum"),
			 (object_size_type & OST_DYNAMIC) ? "dynamic " : "",
			 (object_size_type & OST_SUBOBJECT) ? "sub" : "");
		print_generic_expr (dump_file, object_sizes_get (&osi, i),
				    dump_flags);
		fprintf (dump_file, "\n");
	      }
	}

      BITMAP_FREE (osi.reexamine);
      BITMAP_FREE (osi.visited);
    }

  *psize = object_sizes_get (&osi, SSA_NAME_VERSION (ptr));
  return !size_unknown_p (*psize, object_size_type);
}

/* Compute object_sizes for PTR, defined to VALUE, which is not an SSA_NAME.  */

static void
expr_object_size (struct object_size_info *osi, tree ptr, tree value)
{
  int object_size_type = osi->object_size_type;
  unsigned int varno = SSA_NAME_VERSION (ptr);
  tree bytes, wholesize;

  gcc_assert (!object_sizes_unknown_p (object_size_type, varno));
  gcc_assert (osi->pass == 0);

  if (TREE_CODE (value) == WITH_SIZE_EXPR)
    value = TREE_OPERAND (value, 0);

  /* Pointer variables should have been handled by merge_object_sizes.  */
  gcc_assert (TREE_CODE (value) != SSA_NAME
	      || !POINTER_TYPE_P (TREE_TYPE (value)));

  if (TREE_CODE (value) == ADDR_EXPR)
    addr_object_size (osi, value, object_size_type, &bytes, &wholesize);
  else
    bytes = wholesize = size_unknown (object_size_type);

  object_sizes_set (osi, varno, bytes, wholesize);
}


/* Compute object_sizes for PTR, defined to the result of a call.  */

static void
call_object_size (struct object_size_info *osi, tree ptr, gcall *call)
{
  int object_size_type = osi->object_size_type;
  unsigned int varno = SSA_NAME_VERSION (ptr);
  tree bytes = NULL_TREE;

  gcc_assert (is_gimple_call (call));

  gcc_assert (!object_sizes_unknown_p (object_size_type, varno));
  gcc_assert (osi->pass == 0);

  bool is_strdup = gimple_call_builtin_p (call, BUILT_IN_STRDUP);
  bool is_strndup = gimple_call_builtin_p (call, BUILT_IN_STRNDUP);
  if (is_strdup || is_strndup)
    bytes = strdup_object_size (call, object_size_type, is_strndup);
  else
    bytes = alloc_object_size (call, object_size_type);

  if (!size_valid_p (bytes, object_size_type))
    bytes = size_unknown (object_size_type);

  object_sizes_set (osi, varno, bytes, bytes);
}


/* Compute object_sizes for PTR, defined to an unknown value.  */

static void
unknown_object_size (struct object_size_info *osi, tree ptr)
{
  int object_size_type = osi->object_size_type;
  unsigned int varno = SSA_NAME_VERSION (ptr);

  gcc_checking_assert (!object_sizes_unknown_p (object_size_type, varno));
  gcc_checking_assert (osi->pass == 0);
  tree bytes = size_unknown (object_size_type);

  object_sizes_set (osi, varno, bytes, bytes);
}


/* Merge object sizes of ORIG + OFFSET into DEST.  Return true if
   the object size might need reexamination later.  */

static bool
merge_object_sizes (struct object_size_info *osi, tree dest, tree orig)
{
  int object_size_type = osi->object_size_type;
  unsigned int varno = SSA_NAME_VERSION (dest);
  tree orig_bytes, wholesize;

  if (object_sizes_unknown_p (object_size_type, varno))
    return false;

  if (osi->pass == 0)
    collect_object_sizes_for (osi, orig);

  orig_bytes = object_sizes_get (osi, SSA_NAME_VERSION (orig));
  wholesize = object_sizes_get (osi, SSA_NAME_VERSION (orig), true);

  if (object_sizes_set (osi, varno, orig_bytes, wholesize))
    osi->changed = true;

  return bitmap_bit_p (osi->reexamine, SSA_NAME_VERSION (orig));
}


/* Compute object_sizes for VAR, defined to the result of an assignment
   with operator POINTER_PLUS_EXPR.  Return true if the object size might
   need reexamination  later.  */

static bool
plus_stmt_object_size (struct object_size_info *osi, tree var, gimple *stmt)
{
  int object_size_type = osi->object_size_type;
  unsigned int varno = SSA_NAME_VERSION (var);
  tree bytes, wholesize;
  tree op0, op1;
  bool reexamine = false;

  if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
    {
      op0 = gimple_assign_rhs1 (stmt);
      op1 = gimple_assign_rhs2 (stmt);
    }
  else if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
    {
      tree rhs = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
      gcc_assert (TREE_CODE (rhs) == MEM_REF);
      op0 = TREE_OPERAND (rhs, 0);
      op1 = TREE_OPERAND (rhs, 1);
    }
  else
    gcc_unreachable ();

  if (object_sizes_unknown_p (object_size_type, varno))
    return false;

  /* Handle PTR + OFFSET here.  */
  if (size_valid_p (op1, object_size_type)
      && (TREE_CODE (op0) == SSA_NAME || TREE_CODE (op0) == ADDR_EXPR))
    {
      if (TREE_CODE (op0) == SSA_NAME)
	{
	  if (osi->pass == 0)
	    collect_object_sizes_for (osi, op0);

	  bytes = object_sizes_get (osi, SSA_NAME_VERSION (op0));
	  wholesize = object_sizes_get (osi, SSA_NAME_VERSION (op0), true);
	  reexamine = bitmap_bit_p (osi->reexamine, SSA_NAME_VERSION (op0));
	}
      else
	{
	  /* op0 will be ADDR_EXPR here.  We should never come here during
	     reexamination.  */
	  gcc_checking_assert (osi->pass == 0);
	  addr_object_size (osi, op0, object_size_type, &bytes, &wholesize);
	}

      /* size_for_offset doesn't make sense for -1 size, but it does for size 0
	 since the wholesize could be non-zero and a negative offset could give
	 a non-zero size.  */
      if (size_unknown_p (bytes, 0))
	;
      else if ((object_size_type & OST_DYNAMIC)
	       || compare_tree_int (op1, offset_limit) <= 0)
	bytes = size_for_offset (bytes, op1, wholesize);
      /* In the static case, with a negative offset, the best estimate for
	 minimum size is size_unknown but for maximum size, the wholesize is a
	 better estimate than size_unknown.  */
      else if (object_size_type & OST_MINIMUM)
	bytes = size_unknown (object_size_type);
      else
	bytes = wholesize;
    }
  else
    bytes = wholesize = size_unknown (object_size_type);

  if (!size_valid_p (bytes, object_size_type)
      || !size_valid_p (wholesize, object_size_type))
    bytes = wholesize = size_unknown (object_size_type);

  if (object_sizes_set (osi, varno, bytes, wholesize))
    osi->changed = true;
  return reexamine;
}

/* Compute the dynamic object size for VAR.  Return the result in SIZE and
   WHOLESIZE.  */

static void
dynamic_object_size (struct object_size_info *osi, tree var,
		     tree *size, tree *wholesize)
{
  int object_size_type = osi->object_size_type;

  if (TREE_CODE (var) == SSA_NAME)
    {
      unsigned varno = SSA_NAME_VERSION (var);

      collect_object_sizes_for (osi, var);
      *size = object_sizes_get (osi, varno);
      *wholesize = object_sizes_get (osi, varno, true);
    }
  else if (TREE_CODE (var) == ADDR_EXPR)
    addr_object_size (osi, var, object_size_type, size, wholesize);
  else
    *size = *wholesize = size_unknown (object_size_type);
}

/* Compute object_sizes for VAR, defined at STMT, which is
   a COND_EXPR.  Return true if the object size might need reexamination
   later.  */

static bool
cond_expr_object_size (struct object_size_info *osi, tree var, gimple *stmt)
{
  tree then_, else_;
  int object_size_type = osi->object_size_type;
  unsigned int varno = SSA_NAME_VERSION (var);
  bool reexamine = false;

  gcc_assert (gimple_assign_rhs_code (stmt) == COND_EXPR);

  if (object_sizes_unknown_p (object_size_type, varno))
    return false;

  then_ = gimple_assign_rhs2 (stmt);
  else_ = gimple_assign_rhs3 (stmt);

  if (object_size_type & OST_DYNAMIC)
    {
      tree then_size, then_wholesize, else_size, else_wholesize;

      dynamic_object_size (osi, then_, &then_size, &then_wholesize);
      if (!size_unknown_p (then_size, object_size_type))
	dynamic_object_size (osi, else_, &else_size, &else_wholesize);

      tree cond_size, cond_wholesize;
      if (size_unknown_p (then_size, object_size_type)
	  || size_unknown_p (else_size, object_size_type))
	cond_size = cond_wholesize = size_unknown (object_size_type);
      else
	{
	  cond_size = fold_build3 (COND_EXPR, sizetype,
				   gimple_assign_rhs1 (stmt),
				   then_size, else_size);
	  cond_wholesize = fold_build3 (COND_EXPR, sizetype,
					gimple_assign_rhs1 (stmt),
					then_wholesize, else_wholesize);
	}

      object_sizes_set (osi, varno, cond_size, cond_wholesize);

      return false;
    }

  if (TREE_CODE (then_) == SSA_NAME)
    reexamine |= merge_object_sizes (osi, var, then_);
  else
    expr_object_size (osi, var, then_);

  if (object_sizes_unknown_p (object_size_type, varno))
    return reexamine;

  if (TREE_CODE (else_) == SSA_NAME)
    reexamine |= merge_object_sizes (osi, var, else_);
  else
    expr_object_size (osi, var, else_);

  return reexamine;
}

/* Find size of an object passed as a parameter to the function.  */

static void
parm_object_size (struct object_size_info *osi, tree var)
{
  int object_size_type = osi->object_size_type;
  tree parm = SSA_NAME_VAR (var);

  if (!(object_size_type & OST_DYNAMIC) || !POINTER_TYPE_P (TREE_TYPE (parm)))
    {
      expr_object_size (osi, var, parm);
      return;
    }

  /* Look for access attribute.  */
  rdwr_map rdwr_idx;

  tree fndecl = cfun->decl;
  const attr_access *access = get_parm_access (rdwr_idx, parm, fndecl);
  tree typesize = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (parm)));
  tree sz = NULL_TREE;

  /* If we have an explicit access attribute with a usable size argument... */
  if (access && access->sizarg != UINT_MAX && !access->internal_p
      /* ... and either PARM is void * or has a type that is complete and has a
	 constant size... */
      && ((typesize && poly_int_tree_p (typesize))
	  || (!typesize && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (parm))))))
    {
      tree fnargs = DECL_ARGUMENTS (fndecl);
      tree arg = NULL_TREE;
      unsigned argpos = 0;

      /* ... then walk through the parameters to pick the size parameter and
	 safely scale it by the type size if needed.  */
      for (arg = fnargs; arg; arg = TREE_CHAIN (arg), ++argpos)
	if (argpos == access->sizarg && INTEGRAL_TYPE_P (TREE_TYPE (arg)))
	  {
	    sz = get_or_create_ssa_default_def (cfun, arg);
	    if (sz != NULL_TREE)
	      {
		sz = fold_convert (sizetype, sz);
		if (typesize)
		  sz = size_binop (MULT_EXPR, sz, typesize);
	      }
	    break;
	  }
    }
  if (!sz)
    sz = size_unknown (object_size_type);

  object_sizes_set (osi, SSA_NAME_VERSION (var), sz, sz);
}

/* Compute an object size expression for VAR, which is the result of a PHI
   node.  */

static void
phi_dynamic_object_size (struct object_size_info *osi, tree var)
{
  int object_size_type = osi->object_size_type;
  unsigned int varno = SSA_NAME_VERSION (var);
  gimple *stmt = SSA_NAME_DEF_STMT (var);
  unsigned i, num_args = gimple_phi_num_args (stmt);
  bool wholesize_needed = false;

  /* The extra space is for the PHI result at the end, which object_sizes_set
     sets for us.  */
  tree sizes = make_tree_vec (num_args + 1);
  tree wholesizes = make_tree_vec (num_args + 1);

  /* Bail out if the size of any of the PHI arguments cannot be
     determined.  */
  for (i = 0; i < num_args; i++)
    {
      edge e = gimple_phi_arg_edge (as_a <gphi *> (stmt), i);
      if (e->flags & EDGE_COMPLEX)
	break;

      tree rhs = gimple_phi_arg_def (stmt, i);
      tree size, wholesize;

      dynamic_object_size (osi, rhs, &size, &wholesize);

      if (size_unknown_p (size, object_size_type))
       break;

      if (size != wholesize)
	wholesize_needed = true;

      TREE_VEC_ELT (sizes, i) = size;
      TREE_VEC_ELT (wholesizes, i) = wholesize;
    }

  if (i < num_args)
    {
      ggc_free (sizes);
      ggc_free (wholesizes);
      sizes = wholesizes = size_unknown (object_size_type);
    }

  /* Point to the same TREE_VEC so that we can avoid emitting two PHI
     nodes.  */
  else if (!wholesize_needed)
    {
      ggc_free (wholesizes);
      wholesizes = sizes;
    }

  object_sizes_set (osi, varno, sizes, wholesizes);
}

/* Compute object sizes for VAR.
   For ADDR_EXPR an object size is the number of remaining bytes
   to the end of the object (where what is considered an object depends on
   OSI->object_size_type).
   For allocation GIMPLE_CALL like malloc or calloc object size is the size
   of the allocation.
   For POINTER_PLUS_EXPR where second operand is a constant integer,
   object size is object size of the first operand minus the constant.
   If the constant is bigger than the number of remaining bytes until the
   end of the object, object size is 0, but if it is instead a pointer
   subtraction, object size is size_unknown (object_size_type).
   To differentiate addition from subtraction, ADDR_EXPR returns
   size_unknown (object_size_type) for all objects bigger than half of the
   address space, and constants less than half of the address space are
   considered addition, while bigger constants subtraction.
   For a memcpy like GIMPLE_CALL that always returns one of its arguments, the
   object size is object size of that argument.
   Otherwise, object size is the maximum of object sizes of variables
   that it might be set to.  */

static void
collect_object_sizes_for (struct object_size_info *osi, tree var)
{
  int object_size_type = osi->object_size_type;
  unsigned int varno = SSA_NAME_VERSION (var);
  gimple *stmt;
  bool reexamine;

  if (bitmap_bit_p (computed[object_size_type], varno))
    return;

  if (osi->pass == 0)
    {
      if (bitmap_set_bit (osi->visited, varno))
	{
	  /* Initialize to 0 for maximum size and M1U for minimum size so that
	     it gets immediately overridden.  */
	  object_sizes_initialize (osi, varno,
				   size_initval (object_size_type),
				   size_initval (object_size_type));
	}
      else
	{
	  /* Found a dependency loop.  Mark the variable for later
	     re-examination.  */
	  if (object_size_type & OST_DYNAMIC)
	    object_sizes_set_temp (osi, varno);

	  bitmap_set_bit (osi->reexamine, varno);
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Found a dependency loop at ");
	      print_generic_expr (dump_file, var, dump_flags);
	      fprintf (dump_file, "\n");
	    }
	  return;
	}
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Visiting use-def links for ");
      print_generic_expr (dump_file, var, dump_flags);
      fprintf (dump_file, "\n");
    }

  stmt = SSA_NAME_DEF_STMT (var);
  reexamine = false;

  switch (gimple_code (stmt))
    {
    case GIMPLE_ASSIGN:
      {
	tree rhs = gimple_assign_rhs1 (stmt);
        if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
	    || (gimple_assign_rhs_code (stmt) == ADDR_EXPR
		&& TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF))
          reexamine = plus_stmt_object_size (osi, var, stmt);
	else if (gimple_assign_rhs_code (stmt) == COND_EXPR)
	  reexamine = cond_expr_object_size (osi, var, stmt);
        else if (gimple_assign_single_p (stmt)
                 || gimple_assign_unary_nop_p (stmt))
          {
            if (TREE_CODE (rhs) == SSA_NAME
                && POINTER_TYPE_P (TREE_TYPE (rhs)))
	      reexamine = merge_object_sizes (osi, var, rhs);
            else
              expr_object_size (osi, var, rhs);
          }
        else
	  unknown_object_size (osi, var);
        break;
      }

    case GIMPLE_CALL:
      {
	gcall *call_stmt = as_a <gcall *> (stmt);
        tree arg = pass_through_call (call_stmt);
        if (arg)
          {
            if (TREE_CODE (arg) == SSA_NAME
                && POINTER_TYPE_P (TREE_TYPE (arg)))
	      reexamine = merge_object_sizes (osi, var, arg);
            else
              expr_object_size (osi, var, arg);
          }
        else
          call_object_size (osi, var, call_stmt);
	break;
      }

    case GIMPLE_ASM:
      /* Pointers defined by __asm__ statements can point anywhere.  */
      unknown_object_size (osi, var);
      break;

    case GIMPLE_NOP:
      if (SSA_NAME_VAR (var)
	  && TREE_CODE (SSA_NAME_VAR (var)) == PARM_DECL)
	parm_object_size (osi, var);
      else
	/* Uninitialized SSA names point nowhere.  */
	unknown_object_size (osi, var);
      break;

    case GIMPLE_PHI:
      {
	unsigned i;

	if (object_size_type & OST_DYNAMIC)
	  {
	    phi_dynamic_object_size (osi, var);
	    break;
	  }

	for (i = 0; i < gimple_phi_num_args (stmt); i++)
	  {
	    tree rhs = gimple_phi_arg (stmt, i)->def;

	    if (object_sizes_unknown_p (object_size_type, varno))
	      break;

	    if (TREE_CODE (rhs) == SSA_NAME)
	      reexamine |= merge_object_sizes (osi, var, rhs);
	    else if (osi->pass == 0)
	      expr_object_size (osi, var, rhs);
	  }
	break;
      }

    default:
      gcc_unreachable ();
    }

  if (! reexamine || object_sizes_unknown_p (object_size_type, varno))
    {
      bitmap_set_bit (computed[object_size_type], varno);
      if (!(object_size_type & OST_DYNAMIC))
	bitmap_clear_bit (osi->reexamine, varno);
    }
  else
    {
      bitmap_set_bit (osi->reexamine, varno);
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Need to reexamine ");
	  print_generic_expr (dump_file, var, dump_flags);
	  fprintf (dump_file, "\n");
	}
    }
}


/* Helper function for check_for_plus_in_loops.  Called recursively
   to detect loops.  */

static void
check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
			   unsigned int depth)
{
  gimple *stmt = SSA_NAME_DEF_STMT (var);
  unsigned int varno = SSA_NAME_VERSION (var);

  if (osi->depths[varno])
    {
      if (osi->depths[varno] != depth)
	{
	  unsigned int *sp;

	  /* Found a loop involving pointer addition.  */
	  for (sp = osi->tos; sp > osi->stack; )
	    {
	      --sp;
	      bitmap_clear_bit (osi->reexamine, *sp);
	      bitmap_set_bit (computed[osi->object_size_type], *sp);
	      object_sizes_set (osi, *sp, size_zero_node,
				object_sizes_get (osi, *sp, true));
	      if (*sp == varno)
		break;
	    }
	}
      return;
    }
  else if (! bitmap_bit_p (osi->reexamine, varno))
    return;

  osi->depths[varno] = depth;
  *osi->tos++ = varno;

  switch (gimple_code (stmt))
    {

    case GIMPLE_ASSIGN:
      {
        if ((gimple_assign_single_p (stmt)
             || gimple_assign_unary_nop_p (stmt))
            && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
          {
            tree rhs = gimple_assign_rhs1 (stmt);

            check_for_plus_in_loops_1 (osi, rhs, depth);
          }
        else if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
          {
            tree basevar = gimple_assign_rhs1 (stmt);
            tree cst = gimple_assign_rhs2 (stmt);

            gcc_assert (TREE_CODE (cst) == INTEGER_CST);

            check_for_plus_in_loops_1 (osi, basevar,
                                       depth + !integer_zerop (cst));
          }
        else
          gcc_unreachable ();
        break;
      }

    case GIMPLE_CALL:
      {
	gcall *call_stmt = as_a <gcall *> (stmt);
        tree arg = pass_through_call (call_stmt);
        if (arg)
          {
            if (TREE_CODE (arg) == SSA_NAME)
              check_for_plus_in_loops_1 (osi, arg, depth);
            else
              gcc_unreachable ();
          }
        break;
      }

    case GIMPLE_PHI:
      {
	unsigned i;

	for (i = 0; i < gimple_phi_num_args (stmt); i++)
	  {
	    tree rhs = gimple_phi_arg (stmt, i)->def;

	    if (TREE_CODE (rhs) == SSA_NAME)
	      check_for_plus_in_loops_1 (osi, rhs, depth);
	  }
	break;
      }

    default:
      gcc_unreachable ();
    }

  osi->depths[varno] = 0;
  osi->tos--;
}


/* Check if some pointer we are computing object size of is being increased
   within a loop.  If yes, assume all the SSA variables participating in
   that loop have minimum object sizes 0.  */

static void
check_for_plus_in_loops (struct object_size_info *osi, tree var)
{
  gimple *stmt = SSA_NAME_DEF_STMT (var);

  /* NOTE: In the pre-tuples code, we handled a CALL_EXPR here,
     and looked for a POINTER_PLUS_EXPR in the pass-through
     argument, if any.  In GIMPLE, however, such an expression
     is not a valid call operand.  */

  if (is_gimple_assign (stmt)
      && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
    {
      tree basevar = gimple_assign_rhs1 (stmt);
      tree cst = gimple_assign_rhs2 (stmt);

      gcc_assert (TREE_CODE (cst) == INTEGER_CST);

      /* Skip non-positive offsets.  */
      if (integer_zerop (cst) || compare_tree_int (cst, offset_limit) > 0)
        return;

      osi->depths[SSA_NAME_VERSION (basevar)] = 1;
      *osi->tos++ = SSA_NAME_VERSION (basevar);
      check_for_plus_in_loops_1 (osi, var, 2);
      osi->depths[SSA_NAME_VERSION (basevar)] = 0;
      osi->tos--;
    }
}


/* Initialize data structures for the object size computation.  */

void
init_object_sizes (void)
{
  int object_size_type;

  if (computed[0])
    return;

  for (object_size_type = 0; object_size_type < OST_END; object_size_type++)
    {
      object_sizes_grow (object_size_type);
      computed[object_size_type] = BITMAP_ALLOC (NULL);
    }

  init_offset_limit ();
}


/* Destroy data structures after the object size computation.  */

void
fini_object_sizes (void)
{
  int object_size_type;

  for (object_size_type = 0; object_size_type < OST_END; object_size_type++)
    {
      object_sizes_release (object_size_type);
      BITMAP_FREE (computed[object_size_type]);
    }
}

/* Dummy valueize function.  */

static tree
do_valueize (tree t)
{
  return t;
}

/* Process a __builtin_object_size or __builtin_dynamic_object_size call in
   CALL early for subobjects before any object information is lost due to
   optimization.  Insert a MIN or MAX expression of the result and
   __builtin_object_size at I so that it may be processed in the second pass.
   __builtin_dynamic_object_size is treated like __builtin_object_size here
   since we're only looking for constant bounds.  */

static void
early_object_sizes_execute_one (gimple_stmt_iterator *i, gimple *call)
{
  tree ost = gimple_call_arg (call, 1);
  tree lhs = gimple_call_lhs (call);
  gcc_assert (lhs != NULL_TREE);

  if (!tree_fits_uhwi_p (ost))
    return;

  unsigned HOST_WIDE_INT object_size_type = tree_to_uhwi (ost);
  tree ptr = gimple_call_arg (call, 0);

  if (object_size_type != 1 && object_size_type != 3)
    return;

  if (TREE_CODE (ptr) != ADDR_EXPR && TREE_CODE (ptr) != SSA_NAME)
    return;

  tree type = TREE_TYPE (lhs);
  tree bytes;
  if (!compute_builtin_object_size (ptr, object_size_type, &bytes)
      || !int_fits_type_p (bytes, type))
    return;

  tree tem = make_ssa_name (type);
  gimple_call_set_lhs (call, tem);
  enum tree_code code = object_size_type & OST_MINIMUM ? MAX_EXPR : MIN_EXPR;
  tree cst = fold_convert (type, bytes);
  gimple *g = gimple_build_assign (lhs, code, tem, cst);
  gsi_insert_after (i, g, GSI_NEW_STMT);
  update_stmt (call);
}

/* Attempt to fold one __builtin_dynamic_object_size call in CALL into an
   expression and insert it at I.  Return true if it succeeds.  */

static bool
dynamic_object_sizes_execute_one (gimple_stmt_iterator *i, gimple *call)
{
  gcc_assert (gimple_call_num_args (call) == 2);

  tree args[2];
  args[0] = gimple_call_arg (call, 0);
  args[1] = gimple_call_arg (call, 1);

  location_t loc = EXPR_LOC_OR_LOC (args[0], input_location);
  tree result_type = gimple_call_return_type (as_a <gcall *> (call));
  tree result = fold_builtin_call_array (loc, result_type,
					 gimple_call_fn (call), 2, args);

  if (!result)
    return false;

  /* fold_builtin_call_array may wrap the result inside a
     NOP_EXPR.  */
  STRIP_NOPS (result);
  gimplify_and_update_call_from_tree (i, result);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Simplified (dynamic)\n  ");
      print_gimple_stmt (dump_file, call, 0, dump_flags);
      fprintf (dump_file, " to ");
      print_generic_expr (dump_file, result);
      fprintf (dump_file, "\n");
    }
  return true;
}

static unsigned int
object_sizes_execute (function *fun, bool early)
{
  todo = 0;

  basic_block bb;
  FOR_EACH_BB_FN (bb, fun)
    {
      gimple_stmt_iterator i;
      for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
	{
	  tree result;
	  bool dynamic = false;

	  gimple *call = gsi_stmt (i);
	  if (gimple_call_builtin_p (call, BUILT_IN_DYNAMIC_OBJECT_SIZE))
	    dynamic = true;
	  else if (!gimple_call_builtin_p (call, BUILT_IN_OBJECT_SIZE))
	    continue;

	  tree lhs = gimple_call_lhs (call);
	  if (!lhs)
	    continue;

	  init_object_sizes ();

	  /* If early, only attempt to fold
	     __builtin_object_size (x, 1) and __builtin_object_size (x, 3),
	     and rather than folding the builtin to the constant if any,
	     create a MIN_EXPR or MAX_EXPR of the __builtin_object_size
	     call result and the computed constant.  Do the same for
	     __builtin_dynamic_object_size too.  */
	  if (early)
	    {
	      early_object_sizes_execute_one (&i, call);
	      continue;
	    }

	  if (dynamic)
	    {
	      if (dynamic_object_sizes_execute_one (&i, call))
		continue;
	      else
		{
		  /* If we could not find a suitable size expression, lower to
		     __builtin_object_size so that we may at least get a
		     constant lower or higher estimate.  */
		  tree bosfn = builtin_decl_implicit (BUILT_IN_OBJECT_SIZE);
		  gimple_call_set_fndecl (call, bosfn);
		  update_stmt (call);

		  if (dump_file && (dump_flags & TDF_DETAILS))
		    {
		      print_generic_expr (dump_file, gimple_call_arg (call, 0),
					  dump_flags);
		      fprintf (dump_file,
			       ": Retrying as __builtin_object_size\n");
		    }
		}
	    }

	  result = gimple_fold_stmt_to_constant (call, do_valueize);
	  if (!result)
	    {
	      tree ost = gimple_call_arg (call, 1);

	      if (tree_fits_uhwi_p (ost))
		{
		  unsigned HOST_WIDE_INT object_size_type = tree_to_uhwi (ost);

		  if (object_size_type & OST_MINIMUM)
		    result = build_zero_cst (size_type_node);
		  else if (object_size_type < OST_END)
		    result = fold_convert (size_type_node,
					   integer_minus_one_node);
		}

	      if (!result)
		continue;
	    }

	  gcc_assert (TREE_CODE (result) == INTEGER_CST);

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Simplified\n  ");
	      print_gimple_stmt (dump_file, call, 0, dump_flags);
	      fprintf (dump_file, " to ");
	      print_generic_expr (dump_file, result);
	      fprintf (dump_file, "\n");
	    }

	  /* Propagate into all uses and fold those stmts.  */
	  if (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
	    replace_uses_by (lhs, result);
	  else
	    replace_call_with_value (&i, result);
	}
    }

  fini_object_sizes ();
  return todo;
}

/* Simple pass to optimize all __builtin_object_size () builtins.  */

namespace {

const pass_data pass_data_object_sizes =
{
  GIMPLE_PASS, /* type */
  "objsz", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  ( PROP_cfg | PROP_ssa ), /* properties_required */
  PROP_objsz, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_object_sizes : public gimple_opt_pass
{
public:
  pass_object_sizes (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_object_sizes, ctxt)
  {}

  /* opt_pass methods: */
  opt_pass * clone () final override { return new pass_object_sizes (m_ctxt); }
  unsigned int execute (function *fun) final override
  {
    return object_sizes_execute (fun, false);
  }
}; // class pass_object_sizes

} // anon namespace

gimple_opt_pass *
make_pass_object_sizes (gcc::context *ctxt)
{
  return new pass_object_sizes (ctxt);
}

/* Early version of pass to optimize all __builtin_object_size () builtins.  */

namespace {

const pass_data pass_data_early_object_sizes =
{
  GIMPLE_PASS, /* type */
  "early_objsz", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  ( PROP_cfg | PROP_ssa ), /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_early_object_sizes : public gimple_opt_pass
{
public:
  pass_early_object_sizes (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_early_object_sizes, ctxt)
  {}

  /* opt_pass methods: */
  unsigned int execute (function *fun) final override
  {
    return object_sizes_execute (fun, true);
  }
}; // class pass_object_sizes

} // anon namespace

gimple_opt_pass *
make_pass_early_object_sizes (gcc::context *ctxt)
{
  return new pass_early_object_sizes (ctxt);
}
