/* Pointer Bounds Checker insrumentation pass.
   Copyright (C) 2014-2018 Free Software Foundation, Inc.
   Contributed by Ilya Enkovich (ilya.enkovich@intel.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 "target.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "cgraph.h"
#include "diagnostic.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "varasm.h"
#include "tree-iterator.h"
#include "tree-cfg.h"
#include "langhooks.h"
#include "tree-ssa-address.h"
#include "tree-ssa-loop-niter.h"
#include "gimple-pretty-print.h"
#include "gimple-iterator.h"
#include "gimplify.h"
#include "gimplify-me.h"
#include "print-tree.h"
#include "calls.h"
#include "expr.h"
#include "tree-ssa-propagate.h"
#include "tree-chkp.h"
#include "gimple-walk.h"
#include "tree-dfa.h"
#include "ipa-chkp.h"
#include "params.h"
#include "stringpool.h"
#include "attribs.h"

/*  Pointer Bounds Checker instruments code with memory checks to find
    out-of-bounds memory accesses.  Checks are performed by computing
    bounds for each pointer and then comparing address of accessed
    memory before pointer dereferencing.

    1. Function clones.

    See ipa-chkp.c.

    2. Instrumentation.

    There are few things to instrument:

    a) Memory accesses - add checker calls to check address of accessed memory
    against bounds of dereferenced pointer.  Obviously safe memory
    accesses like static variable access does not have to be instrumented
    with checks.

    Example:

      val_2 = *p_1;

      with 4 bytes access is transformed into:

      __builtin___chkp_bndcl (__bound_tmp.1_3, p_1);
      D.1_4 = p_1 + 3;
      __builtin___chkp_bndcu (__bound_tmp.1_3, D.1_4);
      val_2 = *p_1;

      where __bound_tmp.1_3 are bounds computed for pointer p_1,
      __builtin___chkp_bndcl is a lower bound check and
      __builtin___chkp_bndcu is an upper bound check.

    b) Pointer stores.

    When pointer is stored in memory we need to store its bounds.  To
    achieve compatibility of instrumented code with regular codes
    we have to keep data layout and store bounds in special bound tables
    via special checker call.  Implementation of bounds table may vary for
    different platforms.  It has to associate pointer value and its
    location (it is required because we may have two equal pointers
    with different bounds stored in different places) with bounds.
    Another checker builtin allows to get bounds for specified pointer
    loaded from specified location.

    Example:

      buf1[i_1] = &buf2;

      is transformed into:

      buf1[i_1] = &buf2;
      D.1_2 = &buf1[i_1];
      __builtin___chkp_bndstx (D.1_2, &buf2, __bound_tmp.1_2);

      where __bound_tmp.1_2 are bounds of &buf2.

    c) Static initialization.

    The special case of pointer store is static pointer initialization.
    Bounds initialization is performed in a few steps:
      - register all static initializations in front-end using
      chkp_register_var_initializer
      - when file compilation finishes we create functions with special
      attribute 'chkp ctor' and put explicit initialization code
      (assignments) for all statically initialized pointers.
      - when checker constructor is compiled checker pass adds required
      bounds initialization for all statically initialized pointers
      - since we do not actually need excess pointers initialization
      in checker constructor we remove such assignments from them

    d) Calls.

    For each call in the code we add additional arguments to pass
    bounds for pointer arguments.  We determine type of call arguments
    using arguments list from function declaration; if function
    declaration is not available we use function type; otherwise
    (e.g. for unnamed arguments) we use type of passed value. Function
    declaration/type is replaced with the instrumented one.

    Example:

      val_1 = foo (&buf1, &buf2, &buf1, 0);

      is translated into:

      val_1 = foo.chkp (&buf1, __bound_tmp.1_2, &buf2, __bound_tmp.1_3,
                        &buf1, __bound_tmp.1_2, 0);

    e) Returns.

    If function returns a pointer value we have to return bounds also.
    A new operand was added for return statement to hold returned bounds.

    Example:

      return &_buf1;

      is transformed into

      return &_buf1, __bound_tmp.1_1;

    3. Bounds computation.

    Compiler is fully responsible for computing bounds to be used for each
    memory access.  The first step for bounds computation is to find the
    origin of pointer dereferenced for memory access.  Basing on pointer
    origin we define a way to compute its bounds.  There are just few
    possible cases:

    a) Pointer is returned by call.

    In this case we use corresponding checker builtin method to obtain returned
    bounds.

    Example:

      buf_1 = malloc (size_2);
      foo (buf_1);

      is translated into:

      buf_1 = malloc (size_2);
      __bound_tmp.1_3 = __builtin___chkp_bndret (buf_1);
      foo (buf_1, __bound_tmp.1_3);

    b) Pointer is an address of an object.

    In this case compiler tries to compute objects size and create corresponding
    bounds.  If object has incomplete type then special checker builtin is used to
    obtain its size at runtime.

    Example:

      foo ()
      {
        <unnamed type> __bound_tmp.3;
	static int buf[100];

	<bb 3>:
	__bound_tmp.3_2 = __builtin___chkp_bndmk (&buf, 400);

	<bb 2>:
	return &buf, __bound_tmp.3_2;
      }

    Example:

      Address of an object 'extern int buf[]' with incomplete type is
      returned.

      foo ()
      {
        <unnamed type> __bound_tmp.4;
	long unsigned int __size_tmp.3;

	<bb 3>:
	__size_tmp.3_4 = __builtin_ia32_sizeof (buf);
	__bound_tmp.4_3 = __builtin_ia32_bndmk (&buf, __size_tmp.3_4);

	<bb 2>:
	return &buf, __bound_tmp.4_3;
      }

    c) Pointer is the result of object narrowing.

    It happens when we use pointer to an object to compute pointer to a part
    of an object.  E.g. we take pointer to a field of a structure. In this
    case we perform bounds intersection using bounds of original object and
    bounds of object's part (which are computed basing on its type).

    There may be some debatable questions about when narrowing should occur
    and when it should not.  To avoid false bound violations in correct
    programs we do not perform narrowing when address of an array element is
    obtained (it has address of the whole array) and when address of the first
    structure field is obtained (because it is guaranteed to be equal to
    address of the whole structure and it is legal to cast it back to structure).

    Default narrowing behavior may be changed using compiler flags.

    Example:

      In this example address of the second structure field is returned.

      foo (struct A * p, __bounds_type __bounds_of_p)
      {
        <unnamed type> __bound_tmp.3;
	int * _2;
	int * _5;

	<bb 2>:
	_5 = &p_1(D)->second_field;
	__bound_tmp.3_6 = __builtin___chkp_bndmk (_5, 4);
	__bound_tmp.3_8 = __builtin___chkp_intersect (__bound_tmp.3_6,
	                                              __bounds_of_p_3(D));
	_2 = &p_1(D)->second_field;
	return _2, __bound_tmp.3_8;
      }

    Example:

      In this example address of the first field of array element is returned.

      foo (struct A * p, __bounds_type __bounds_of_p, int i)
      {
	long unsigned int _3;
	long unsigned int _4;
	struct A * _6;
	int * _7;

	<bb 2>:
	_3 = (long unsigned int) i_1(D);
	_4 = _3 * 8;
	_6 = p_5(D) + _4;
	_7 = &_6->first_field;
	return _7, __bounds_of_p_2(D);
      }


    d) Pointer is the result of pointer arithmetic or type cast.

    In this case bounds of the base pointer are used.  In case of binary
    operation producing a pointer we are analyzing data flow further
    looking for operand's bounds.  One operand is considered as a base
    if it has some valid bounds.  If we fall into a case when none of
    operands (or both of them) has valid bounds, a default bounds value
    is used.

    Trying to find out bounds for binary operations we may fall into
    cyclic dependencies for pointers.  To avoid infinite recursion all
    walked phi nodes instantly obtain corresponding bounds but created
    bounds are marked as incomplete.  It helps us to stop DF walk during
    bounds search.

    When we reach pointer source, some args of incomplete bounds phi obtain
    valid bounds and those values are propagated further through phi nodes.
    If no valid bounds were found for phi node then we mark its result as
    invalid bounds.  Process stops when all incomplete bounds become either
    valid or invalid and we are able to choose a pointer base.

    e) Pointer is loaded from the memory.

    In this case we just need to load bounds from the bounds table.

    Example:

      foo ()
      {
        <unnamed type> __bound_tmp.3;
	static int * buf;
	int * _2;

	<bb 2>:
	_2 = buf;
	__bound_tmp.3_4 = __builtin___chkp_bndldx (&buf, _2);
	return _2, __bound_tmp.3_4;
      }

*/

typedef void (*assign_handler)(tree, tree, void *);

static tree chkp_get_zero_bounds ();
static tree chkp_find_bounds (tree ptr, gimple_stmt_iterator *iter);
static tree chkp_find_bounds_loaded (tree ptr, tree ptr_src,
				     gimple_stmt_iterator *iter);
static void chkp_parse_array_and_component_ref (tree node, tree *ptr,
						tree *elt, bool *safe,
						bool *bitfield,
						tree *bounds,
						gimple_stmt_iterator *iter,
						bool innermost_bounds);
static void chkp_parse_bit_field_ref (tree node, location_t loc,
				      tree *offset, tree *size);
static tree
chkp_make_addressed_object_bounds (tree obj, gimple_stmt_iterator *iter);

#define chkp_bndldx_fndecl \
  (targetm.builtin_chkp_function (BUILT_IN_CHKP_BNDLDX))
#define chkp_bndstx_fndecl \
  (targetm.builtin_chkp_function (BUILT_IN_CHKP_BNDSTX))
#define chkp_checkl_fndecl \
  (targetm.builtin_chkp_function (BUILT_IN_CHKP_BNDCL))
#define chkp_checku_fndecl \
  (targetm.builtin_chkp_function (BUILT_IN_CHKP_BNDCU))
#define chkp_bndmk_fndecl \
  (targetm.builtin_chkp_function (BUILT_IN_CHKP_BNDMK))
#define chkp_ret_bnd_fndecl \
  (targetm.builtin_chkp_function (BUILT_IN_CHKP_BNDRET))
#define chkp_intersect_fndecl \
  (targetm.builtin_chkp_function (BUILT_IN_CHKP_INTERSECT))
#define chkp_narrow_bounds_fndecl \
  (targetm.builtin_chkp_function (BUILT_IN_CHKP_NARROW))
#define chkp_sizeof_fndecl \
  (targetm.builtin_chkp_function (BUILT_IN_CHKP_SIZEOF))
#define chkp_extract_lower_fndecl \
  (targetm.builtin_chkp_function (BUILT_IN_CHKP_EXTRACT_LOWER))
#define chkp_extract_upper_fndecl \
  (targetm.builtin_chkp_function (BUILT_IN_CHKP_EXTRACT_UPPER))

static GTY (()) tree chkp_uintptr_type;

static GTY (()) tree chkp_zero_bounds_var;
static GTY (()) tree chkp_none_bounds_var;

static GTY (()) basic_block entry_block;
static GTY (()) tree zero_bounds;
static GTY (()) tree none_bounds;
static GTY (()) tree incomplete_bounds;
static GTY (()) tree tmp_var;
static GTY (()) tree size_tmp_var;
static GTY (()) bitmap chkp_abnormal_copies;

struct hash_set<tree> *chkp_invalid_bounds;
struct hash_set<tree> *chkp_completed_bounds_set;
struct hash_map<tree, tree> *chkp_reg_bounds;
struct hash_map<tree, tree> *chkp_bound_vars;
struct hash_map<tree, tree> *chkp_reg_addr_bounds;
struct hash_map<tree, tree> *chkp_incomplete_bounds_map;
struct hash_map<tree, tree> *chkp_bounds_map;
struct hash_map<tree, tree> *chkp_static_var_bounds;

static bool in_chkp_pass;

#define CHKP_BOUND_TMP_NAME "__bound_tmp"
#define CHKP_SIZE_TMP_NAME "__size_tmp"
#define CHKP_BOUNDS_OF_SYMBOL_PREFIX "__chkp_bounds_of_"
#define CHKP_STRING_BOUNDS_PREFIX "__chkp_string_bounds_"
#define CHKP_VAR_BOUNDS_PREFIX "__chkp_var_bounds_"
#define CHKP_ZERO_BOUNDS_VAR_NAME "__chkp_zero_bounds"
#define CHKP_NONE_BOUNDS_VAR_NAME "__chkp_none_bounds"

/* Static checker constructors may become very large and their
   compilation with optimization may take too much time.
   Therefore we put a limit to number of statements in one
   constructor.  Tests with 100 000 statically initialized
   pointers showed following compilation times on Sandy Bridge
   server (used -O2):
   limit    100 => ~18 sec.
   limit    300 => ~22 sec.
   limit   1000 => ~30 sec.
   limit   3000 => ~49 sec.
   limit   5000 => ~55 sec.
   limit  10000 => ~76 sec.
   limit 100000 => ~532 sec.  */
#define MAX_STMTS_IN_STATIC_CHKP_CTOR (PARAM_VALUE (PARAM_CHKP_MAX_CTOR_SIZE))

struct chkp_ctor_stmt_list
{
  tree stmts;
  int avail;
};

/* Return 1 if function FNDECL is instrumented by Pointer
   Bounds Checker.  */
bool
chkp_function_instrumented_p (tree fndecl)
{
  return fndecl
    && lookup_attribute ("chkp instrumented", DECL_ATTRIBUTES (fndecl));
}

/* Mark function FNDECL as instrumented.  */
void
chkp_function_mark_instrumented (tree fndecl)
{
  if (chkp_function_instrumented_p (fndecl))
    return;

  DECL_ATTRIBUTES (fndecl)
    = tree_cons (get_identifier ("chkp instrumented"), NULL,
		 DECL_ATTRIBUTES (fndecl));
}

/* Return true when STMT is builtin call to instrumentation function
   corresponding to CODE.  */

bool
chkp_gimple_call_builtin_p (gimple *call,
			    enum built_in_function code)
{
  tree fndecl;
  /* We are skipping the check for address-spaces, that's
     why we don't use gimple_call_builtin_p directly here.  */
  if (is_gimple_call (call)
      && (fndecl = gimple_call_fndecl (call)) != NULL
      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD
      && (fndecl = targetm.builtin_chkp_function (code))
      && (DECL_FUNCTION_CODE (gimple_call_fndecl (call))
	  == DECL_FUNCTION_CODE (fndecl)))
    return true;
  return false;
}

/* Emit code to build zero bounds and return RTL holding
   the result.  */
rtx
chkp_expand_zero_bounds ()
{
  tree zero_bnd;

  if (flag_chkp_use_static_const_bounds)
    zero_bnd = chkp_get_zero_bounds_var ();
  else
    zero_bnd = chkp_build_make_bounds_call (integer_zero_node,
					    integer_zero_node);
  return expand_normal (zero_bnd);
}

/* Emit code to store zero bounds for PTR located at MEM.  */
void
chkp_expand_bounds_reset_for_mem (tree mem, tree ptr)
{
  tree zero_bnd, bnd, addr, bndstx;

  if (flag_chkp_use_static_const_bounds)
    zero_bnd = chkp_get_zero_bounds_var ();
  else
    zero_bnd = chkp_build_make_bounds_call (integer_zero_node,
					    integer_zero_node);
  bnd = make_tree (pointer_bounds_type_node,
		   assign_temp (pointer_bounds_type_node, 0, 1));
  addr = build1 (ADDR_EXPR,
		 build_pointer_type (TREE_TYPE (mem)), mem);
  bndstx = chkp_build_bndstx_call (addr, ptr, bnd);

  expand_assignment (bnd, zero_bnd, false);
  expand_normal (bndstx);
}

/* Build retbnd call for returned value RETVAL.

   If BNDVAL is not NULL then result is stored
   in it.  Otherwise a temporary is created to
   hold returned value.

   GSI points to a position for a retbnd call
   and is set to created stmt.

   Cgraph edge is created for a new call if
   UPDATE_EDGE is 1.

   Obtained bounds are returned.  */
tree
chkp_insert_retbnd_call (tree bndval, tree retval,
			 gimple_stmt_iterator *gsi)
{
  gimple *call;

  if (!bndval)
    bndval = create_tmp_reg (pointer_bounds_type_node, "retbnd");

  call = gimple_build_call (chkp_ret_bnd_fndecl, 1, retval);
  gimple_call_set_lhs (call, bndval);
  gsi_insert_after (gsi, call, GSI_CONTINUE_LINKING);

  return bndval;
}

/* Build a GIMPLE_CALL identical to CALL but skipping bounds
   arguments.  */

gcall *
chkp_copy_call_skip_bounds (gcall *call)
{
  bitmap bounds;
  unsigned i;

  bitmap_obstack_initialize (NULL);
  bounds = BITMAP_ALLOC (NULL);

  for (i = 0; i < gimple_call_num_args (call); i++)
    if (POINTER_BOUNDS_P (gimple_call_arg (call, i)))
      bitmap_set_bit (bounds, i);

  if (!bitmap_empty_p (bounds))
    call = gimple_call_copy_skip_args (call, bounds);
  gimple_call_set_with_bounds (call, false);

  BITMAP_FREE (bounds);
  bitmap_obstack_release (NULL);

  return call;
}

/* Redirect edge E to the correct node according to call_stmt.
   Return 1 if bounds removal from call_stmt should be done
   instead of redirection.  */

bool
chkp_redirect_edge (cgraph_edge *e)
{
  bool instrumented = false;
  tree decl = e->callee->decl;

  if (e->callee->instrumentation_clone
      || chkp_function_instrumented_p (decl))
    instrumented = true;

  if (instrumented
      && !gimple_call_with_bounds_p (e->call_stmt))
    e->redirect_callee (cgraph_node::get_create (e->callee->orig_decl));
  else if (!instrumented
	   && gimple_call_with_bounds_p (e->call_stmt)
	   && !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDCL)
	   && !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDCU)
	   && !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDSTX))
    {
      if (e->callee->instrumented_version)
	e->redirect_callee (e->callee->instrumented_version);
      else
	{
	  tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
	  /* Avoid bounds removal if all args will be removed.  */
	  if (!args || TREE_VALUE (args) != void_type_node)
	    return true;
	  else
	    gimple_call_set_with_bounds (e->call_stmt, false);
	}
    }

  return false;
}

/* Mark statement S to not be instrumented.  */
static void
chkp_mark_stmt (gimple *s)
{
  gimple_set_plf (s, GF_PLF_1, true);
}

/* Mark statement S to be instrumented.  */
static void
chkp_unmark_stmt (gimple *s)
{
  gimple_set_plf (s, GF_PLF_1, false);
}

/* Return 1 if statement S should not be instrumented.  */
static bool
chkp_marked_stmt_p (gimple *s)
{
  return gimple_plf (s, GF_PLF_1);
}

/* Get var to be used for bound temps.  */
static tree
chkp_get_tmp_var (void)
{
  if (!tmp_var)
    tmp_var = create_tmp_reg (pointer_bounds_type_node, CHKP_BOUND_TMP_NAME);

  return tmp_var;
}

/* Get SSA_NAME to be used as temp.  */
static tree
chkp_get_tmp_reg (gimple *stmt)
{
  if (in_chkp_pass)
    return make_ssa_name (chkp_get_tmp_var (), stmt);

  return make_temp_ssa_name (pointer_bounds_type_node, stmt,
			     CHKP_BOUND_TMP_NAME);
}

/* Get var to be used for size temps.  */
static tree
chkp_get_size_tmp_var (void)
{
  if (!size_tmp_var)
    size_tmp_var = create_tmp_reg (chkp_uintptr_type, CHKP_SIZE_TMP_NAME);

  return size_tmp_var;
}

/* Register bounds BND for address of OBJ.  */
static void
chkp_register_addr_bounds (tree obj, tree bnd)
{
  if (bnd == incomplete_bounds)
    return;

  chkp_reg_addr_bounds->put (obj, bnd);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Regsitered bound ");
      print_generic_expr (dump_file, bnd);
      fprintf (dump_file, " for address of ");
      print_generic_expr (dump_file, obj);
      fprintf (dump_file, "\n");
    }
}

/* Return bounds registered for address of OBJ.  */
static tree
chkp_get_registered_addr_bounds (tree obj)
{
  tree *slot = chkp_reg_addr_bounds->get (obj);
  return slot ? *slot : NULL_TREE;
}

/* Mark BOUNDS as completed.  */
static void
chkp_mark_completed_bounds (tree bounds)
{
  chkp_completed_bounds_set->add (bounds);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Marked bounds ");
      print_generic_expr (dump_file, bounds);
      fprintf (dump_file, " as completed\n");
    }
}

/* Return 1 if BOUNDS were marked as completed and 0 otherwise.  */
static bool
chkp_completed_bounds (tree bounds)
{
  return chkp_completed_bounds_set->contains (bounds);
}

/* Clear comleted bound marks.  */
static void
chkp_erase_completed_bounds (void)
{
  delete chkp_completed_bounds_set;
  chkp_completed_bounds_set = new hash_set<tree>;
}

/* This function is used to provide a base address for
   chkp_get_hard_register_fake_addr_expr.  */
static tree
chkp_get_hard_register_var_fake_base_address ()
{
  int prec = TYPE_PRECISION (ptr_type_node);
  return wide_int_to_tree (ptr_type_node, wi::min_value (prec, SIGNED));
}

/* If we check bounds for a hard register variable, we cannot
   use its address - it is illegal, so instead of that we use
   this fake value.  */
static tree
chkp_get_hard_register_fake_addr_expr (tree obj)
{
  tree addr = chkp_get_hard_register_var_fake_base_address ();
  tree outer = obj;
  while (TREE_CODE (outer) == COMPONENT_REF || TREE_CODE (outer) == ARRAY_REF)
    {
      if (TREE_CODE (outer) == COMPONENT_REF)
	{
	  addr = fold_build_pointer_plus (addr,
					  component_ref_field_offset (outer));
	  outer = TREE_OPERAND (outer, 0);
	}
      else if (TREE_CODE (outer) == ARRAY_REF)
	{
	  tree indx = fold_convert(size_type_node, TREE_OPERAND(outer, 1));
	  tree offset = size_binop (MULT_EXPR,
				    array_ref_element_size (outer), indx);
	  addr = fold_build_pointer_plus (addr, offset);
	  outer = TREE_OPERAND (outer, 0);
	}
    }

  return addr;
}

/* Mark BOUNDS associated with PTR as incomplete.  */
static void
chkp_register_incomplete_bounds (tree bounds, tree ptr)
{
  chkp_incomplete_bounds_map->put (bounds, ptr);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Regsitered incomplete bounds ");
      print_generic_expr (dump_file, bounds);
      fprintf (dump_file, " for ");
      print_generic_expr (dump_file, ptr);
      fprintf (dump_file, "\n");
    }
}

/* Return 1 if BOUNDS are incomplete and 0 otherwise.  */
static bool
chkp_incomplete_bounds (tree bounds)
{
  if (bounds == incomplete_bounds)
    return true;

  if (chkp_completed_bounds (bounds))
    return false;

  return chkp_incomplete_bounds_map->get (bounds) != NULL;
}

/* Clear incomleted bound marks.  */
static void
chkp_erase_incomplete_bounds (void)
{
  delete chkp_incomplete_bounds_map;
  chkp_incomplete_bounds_map = new hash_map<tree, tree>;
}

/* Build and return bndmk call which creates bounds for structure
   pointed by PTR.  Structure should have complete type.  */
tree
chkp_make_bounds_for_struct_addr (tree ptr)
{
  tree type = TREE_TYPE (ptr);
  tree size;

  gcc_assert (POINTER_TYPE_P (type));

  size = TYPE_SIZE (TREE_TYPE (type));

  gcc_assert (size);

  return build_call_nary (pointer_bounds_type_node,
			  build_fold_addr_expr (chkp_bndmk_fndecl),
			  2, ptr, size);
}

/* Traversal function for chkp_may_finish_incomplete_bounds.
   Set RES to 0 if at least one argument of phi statement
   defining bounds (passed in KEY arg) is unknown.
   Traversal stops when first unknown phi argument is found.  */
bool
chkp_may_complete_phi_bounds (tree const &bounds, tree *slot ATTRIBUTE_UNUSED,
			      bool *res)
{
  gimple *phi;
  unsigned i;

  gcc_assert (TREE_CODE (bounds) == SSA_NAME);

  phi = SSA_NAME_DEF_STMT (bounds);

  gcc_assert (phi && gimple_code (phi) == GIMPLE_PHI);

  for (i = 0; i < gimple_phi_num_args (phi); i++)
    {
      tree phi_arg = gimple_phi_arg_def (phi, i);
      if (!phi_arg)
	{
	  *res = false;
	  /* Do not need to traverse further.  */
	  return false;
	}
    }

  return true;
}

/* Return 1 if all phi nodes created for bounds have their
   arguments computed.  */
static bool
chkp_may_finish_incomplete_bounds (void)
{
  bool res = true;

  chkp_incomplete_bounds_map
    ->traverse<bool *, chkp_may_complete_phi_bounds> (&res);

  return res;
}

/* Helper function for chkp_finish_incomplete_bounds.
   Recompute args for bounds phi node.  */
bool
chkp_recompute_phi_bounds (tree const &bounds, tree *slot,
			   void *res ATTRIBUTE_UNUSED)
{
  tree ptr = *slot;
  gphi *bounds_phi;
  gphi *ptr_phi;
  unsigned i;

  gcc_assert (TREE_CODE (bounds) == SSA_NAME);
  gcc_assert (TREE_CODE (ptr) == SSA_NAME);

  bounds_phi = as_a <gphi *> (SSA_NAME_DEF_STMT (bounds));
  ptr_phi = as_a <gphi *> (SSA_NAME_DEF_STMT (ptr));

  for (i = 0; i < gimple_phi_num_args (bounds_phi); i++)
    {
      tree ptr_arg = gimple_phi_arg_def (ptr_phi, i);
      tree bound_arg = chkp_find_bounds (ptr_arg, NULL);

      add_phi_arg (bounds_phi, bound_arg,
		   gimple_phi_arg_edge (ptr_phi, i),
		   UNKNOWN_LOCATION);
    }

  return true;
}

/* Mark BOUNDS as invalid.  */
static void
chkp_mark_invalid_bounds (tree bounds)
{
  chkp_invalid_bounds->add (bounds);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Marked bounds ");
      print_generic_expr (dump_file, bounds);
      fprintf (dump_file, " as invalid\n");
    }
}

/* Return 1 if BOUNDS were marked as invalid and 0 otherwise.  */
static bool
chkp_valid_bounds (tree bounds)
{
  if (bounds == zero_bounds || bounds == none_bounds)
    return false;

  return !chkp_invalid_bounds->contains (bounds);
}

/* Helper function for chkp_finish_incomplete_bounds.
   Check all arguments of phi nodes trying to find
   valid completed bounds.  If there is at least one
   such arg then bounds produced by phi node are marked
   as valid completed bounds and all phi args are
   recomputed.  */
bool
chkp_find_valid_phi_bounds (tree const &bounds, tree *slot, bool *res)
{
  gimple *phi;
  unsigned i;

  gcc_assert (TREE_CODE (bounds) == SSA_NAME);

  if (chkp_completed_bounds (bounds))
    return true;

  phi = SSA_NAME_DEF_STMT (bounds);

  gcc_assert (phi && gimple_code (phi) == GIMPLE_PHI);

  for (i = 0; i < gimple_phi_num_args (phi); i++)
    {
      tree phi_arg = gimple_phi_arg_def (phi, i);

      gcc_assert (phi_arg);

      if (chkp_valid_bounds (phi_arg) && !chkp_incomplete_bounds (phi_arg))
	{
	  *res = true;
	  chkp_mark_completed_bounds (bounds);
	  chkp_recompute_phi_bounds (bounds, slot, NULL);
	  return true;
	}
    }

  return true;
}

/* Helper function for chkp_finish_incomplete_bounds.
   Marks all incompleted bounds as invalid.  */
bool
chkp_mark_invalid_bounds_walker (tree const &bounds,
				 tree *slot ATTRIBUTE_UNUSED,
				 void *res ATTRIBUTE_UNUSED)
{
  if (!chkp_completed_bounds (bounds))
    {
      chkp_mark_invalid_bounds (bounds);
      chkp_mark_completed_bounds (bounds);
    }
  return true;
}

/* When all bound phi nodes have all their args computed
   we have enough info to find valid bounds.  We iterate
   through all incompleted bounds searching for valid
   bounds.  Found valid bounds are marked as completed
   and all remaining incompleted bounds are recomputed.
   Process continues until no new valid bounds may be
   found.  All remained incompleted bounds are marked as
   invalid (i.e. have no valid source of bounds).  */
static void
chkp_finish_incomplete_bounds (void)
{
  bool found_valid = true;

  while (found_valid)
    {
      found_valid = false;

      chkp_incomplete_bounds_map->
	traverse<bool *, chkp_find_valid_phi_bounds> (&found_valid);

      if (found_valid)
	chkp_incomplete_bounds_map->
	  traverse<void *, chkp_recompute_phi_bounds> (NULL);
    }

  chkp_incomplete_bounds_map->
    traverse<void *, chkp_mark_invalid_bounds_walker> (NULL);
  chkp_incomplete_bounds_map->
    traverse<void *, chkp_recompute_phi_bounds> (NULL);

  chkp_erase_completed_bounds ();
  chkp_erase_incomplete_bounds ();
}

/* Return 1 if type TYPE is a pointer type or a
   structure having a pointer type as one of its fields.
   Otherwise return 0.  */
bool
chkp_type_has_pointer (const_tree type)
{
  bool res = false;

  if (BOUNDED_TYPE_P (type))
    res = true;
  else if (RECORD_OR_UNION_TYPE_P (type))
    {
      tree field;

      for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
	if (TREE_CODE (field) == FIELD_DECL)
	  res = res || chkp_type_has_pointer (TREE_TYPE (field));
    }
  else if (TREE_CODE (type) == ARRAY_TYPE)
    res = chkp_type_has_pointer (TREE_TYPE (type));

  return res;
}

unsigned
chkp_type_bounds_count (const_tree type)
{
  unsigned res = 0;

  if (!type)
    res = 0;
  else if (BOUNDED_TYPE_P (type))
    res = 1;
  else if (RECORD_OR_UNION_TYPE_P (type))
    {
      bitmap have_bound;

      bitmap_obstack_initialize (NULL);
      have_bound = BITMAP_ALLOC (NULL);
      chkp_find_bound_slots (type, have_bound);
      res = bitmap_count_bits (have_bound);
      BITMAP_FREE (have_bound);
      bitmap_obstack_release (NULL);
    }

  return res;
}

/* Get bounds associated with NODE via
   chkp_set_bounds call.  */
tree
chkp_get_bounds (tree node)
{
  tree *slot;

  if (!chkp_bounds_map)
    return NULL_TREE;

  slot = chkp_bounds_map->get (node);
  return slot ? *slot : NULL_TREE;
}

/* Associate bounds VAL with NODE.  */
void
chkp_set_bounds (tree node, tree val)
{
  if (!chkp_bounds_map)
    chkp_bounds_map = new hash_map<tree, tree>;

  chkp_bounds_map->put (node, val);
}

/* Check if statically initialized variable VAR require
   static bounds initialization.  If VAR is added into
   bounds initlization list then 1 is returned. Otherwise
   return 0.  */
extern bool
chkp_register_var_initializer (tree var)
{
  if (!flag_check_pointer_bounds
      || DECL_INITIAL (var) == error_mark_node)
    return false;

  gcc_assert (VAR_P (var));
  gcc_assert (DECL_INITIAL (var));

  if (TREE_STATIC (var)
      && chkp_type_has_pointer (TREE_TYPE (var)))
    {
      varpool_node::get_create (var)->need_bounds_init = 1;
      return true;
    }

  return false;
}

/* Helper function for chkp_finish_file.

   Add new modification statement (RHS is assigned to LHS)
   into list of static initializer statementes (passed in ARG).
   If statements list becomes too big, emit checker constructor
   and start the new one.  */
static void
chkp_add_modification_to_stmt_list (tree lhs,
				    tree rhs,
				    void *arg)
{
  struct chkp_ctor_stmt_list *stmts = (struct chkp_ctor_stmt_list *)arg;
  tree modify;

  if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
    rhs = build1 (CONVERT_EXPR, TREE_TYPE (lhs), rhs);

  modify = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs);
  append_to_statement_list (modify, &stmts->stmts);

  stmts->avail--;
}

/* Build and return ADDR_EXPR for specified object OBJ.  */
static tree
chkp_build_addr_expr (tree obj)
{
  /* We first check whether it is a "hard reg case".  */
  tree base = get_base_address (obj);
  if (VAR_P (base) && DECL_HARD_REGISTER (base))
    return chkp_get_hard_register_fake_addr_expr (obj);

  /* If not - return regular ADDR_EXPR.  */
  return TREE_CODE (obj) == TARGET_MEM_REF
    ? tree_mem_ref_addr (ptr_type_node, obj)
    : build_fold_addr_expr (obj);
}

/* Helper function for chkp_finish_file.
   Initialize bound variable BND_VAR with bounds of variable
   VAR to statements list STMTS.  If statements list becomes
   too big, emit checker constructor and start the new one.  */
static void
chkp_output_static_bounds (tree bnd_var, tree var,
			   struct chkp_ctor_stmt_list *stmts)
{
  tree lb, ub, size;

  if (TREE_CODE (var) == STRING_CST)
    {
      lb = build1 (CONVERT_EXPR, size_type_node, chkp_build_addr_expr (var));
      size = build_int_cst (size_type_node, TREE_STRING_LENGTH (var) - 1);
    }
  else if (DECL_SIZE (var)
	   && !chkp_variable_size_type (TREE_TYPE (var)))
    {
      /* Compute bounds using statically known size.  */
      lb = build1 (CONVERT_EXPR, size_type_node, chkp_build_addr_expr (var));
      size = size_binop (MINUS_EXPR, DECL_SIZE_UNIT (var), size_one_node);
    }
  else
    {
      /* Compute bounds using dynamic size.  */
      tree call;

      lb = build1 (CONVERT_EXPR, size_type_node, chkp_build_addr_expr (var));
      call = build1 (ADDR_EXPR,
		     build_pointer_type (TREE_TYPE (chkp_sizeof_fndecl)),
		     chkp_sizeof_fndecl);
      size = build_call_nary (TREE_TYPE (TREE_TYPE (chkp_sizeof_fndecl)),
			      call, 1, var);

      if (flag_chkp_zero_dynamic_size_as_infinite)
	{
	  tree max_size, cond;

	  max_size = build2 (MINUS_EXPR, size_type_node, size_zero_node, lb);
	  cond = build2 (NE_EXPR, boolean_type_node, size, size_zero_node);
	  size = build3 (COND_EXPR, size_type_node, cond, size, max_size);
	}

      size = size_binop (MINUS_EXPR, size, size_one_node);
    }

  ub = size_binop (PLUS_EXPR, lb, size);
  stmts->avail -= targetm.chkp_initialize_bounds (bnd_var, lb, ub,
						  &stmts->stmts);
  if (stmts->avail <= 0)
    {
      cgraph_build_static_cdtor ('B', stmts->stmts,
				 MAX_RESERVED_INIT_PRIORITY + 2);
      stmts->avail = MAX_STMTS_IN_STATIC_CHKP_CTOR;
      stmts->stmts = NULL;
    }
}

/* Return entry block to be used for checker initilization code.
   Create new block if required.  */
static basic_block
chkp_get_entry_block (void)
{
  if (!entry_block)
    entry_block
      = split_block_after_labels (ENTRY_BLOCK_PTR_FOR_FN (cfun))->dest;

  return entry_block;
}

/* Return a bounds var to be used for pointer var PTR_VAR.  */
static tree
chkp_get_bounds_var (tree ptr_var)
{
  tree bnd_var;
  tree *slot;

  slot = chkp_bound_vars->get (ptr_var);
  if (slot)
    bnd_var = *slot;
  else
    {
      bnd_var = create_tmp_reg (pointer_bounds_type_node,
				CHKP_BOUND_TMP_NAME);
      chkp_bound_vars->put (ptr_var, bnd_var);
    }

  return bnd_var;
}

/* If BND is an abnormal bounds copy, return a copied value.
   Otherwise return BND.  */
static tree
chkp_get_orginal_bounds_for_abnormal_copy (tree bnd)
{
  if (bitmap_bit_p (chkp_abnormal_copies, SSA_NAME_VERSION (bnd)))
    {
      gimple *bnd_def = SSA_NAME_DEF_STMT (bnd);
      gcc_checking_assert (gimple_code (bnd_def) == GIMPLE_ASSIGN);
      bnd = gimple_assign_rhs1 (bnd_def);
    }

  return bnd;
}

/* Register bounds BND for object PTR in global bounds table.
   A copy of bounds may be created for abnormal ssa names.
   Returns bounds to use for PTR.  */
static tree
chkp_maybe_copy_and_register_bounds (tree ptr, tree bnd)
{
  bool abnormal_ptr;

  if (!chkp_reg_bounds)
    return bnd;

  /* Do nothing if bounds are incomplete_bounds
     because it means bounds will be recomputed.  */
  if (bnd == incomplete_bounds)
    return bnd;

  abnormal_ptr = (TREE_CODE (ptr) == SSA_NAME
		  && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr)
		  && gimple_code (SSA_NAME_DEF_STMT (ptr)) != GIMPLE_PHI);

  /* A single bounds value may be reused multiple times for
     different pointer values.  It may cause coalescing issues
     for abnormal SSA names.  To avoid it we create a bounds
     copy in case it is computed for abnormal SSA name.

     We also cannot reuse such created copies for other pointers  */
  if (abnormal_ptr
      || bitmap_bit_p (chkp_abnormal_copies, SSA_NAME_VERSION (bnd)))
    {
      tree bnd_var = NULL_TREE;

      if (abnormal_ptr)
	{
	  if (SSA_NAME_VAR (ptr))
	    bnd_var = chkp_get_bounds_var (SSA_NAME_VAR (ptr));
	}
      else
	bnd_var = chkp_get_tmp_var ();

      /* For abnormal copies we may just find original
	 bounds and use them.  */
      if (!abnormal_ptr && !SSA_NAME_IS_DEFAULT_DEF (bnd))
	bnd = chkp_get_orginal_bounds_for_abnormal_copy (bnd);
      /* For undefined values we usually use none bounds
	 value but in case of abnormal edge it may cause
	 coalescing failures.  Use default definition of
	 bounds variable instead to avoid it.  */
      else if (SSA_NAME_IS_DEFAULT_DEF (ptr)
	       && TREE_CODE (SSA_NAME_VAR (ptr)) != PARM_DECL)
	{
	  bnd = get_or_create_ssa_default_def (cfun, bnd_var);

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Using default def bounds ");
	      print_generic_expr (dump_file, bnd);
	      fprintf (dump_file, " for abnormal default def SSA name ");
	      print_generic_expr (dump_file, ptr);
	      fprintf (dump_file, "\n");
	    }
	}
      else
	{
	  tree copy;
	  gimple *def = SSA_NAME_DEF_STMT (ptr);
	  gimple *assign;
	  gimple_stmt_iterator gsi;

	  if (bnd_var)
	    copy = make_ssa_name (bnd_var);
	  else
	    copy = make_temp_ssa_name (pointer_bounds_type_node,
				       NULL,
				       CHKP_BOUND_TMP_NAME);
	  bnd = chkp_get_orginal_bounds_for_abnormal_copy (bnd);
	  assign = gimple_build_assign (copy, bnd);

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Creating a copy of bounds ");
	      print_generic_expr (dump_file, bnd);
	      fprintf (dump_file, " for abnormal SSA name ");
	      print_generic_expr (dump_file, ptr);
	      fprintf (dump_file, "\n");
	    }

	  if (gimple_code (def) == GIMPLE_NOP)
	    {
	      gsi = gsi_last_bb (chkp_get_entry_block ());
	      if (!gsi_end_p (gsi) && is_ctrl_stmt (gsi_stmt (gsi)))
		gsi_insert_before (&gsi, assign, GSI_CONTINUE_LINKING);
	      else
		gsi_insert_after (&gsi, assign, GSI_CONTINUE_LINKING);
	    }
	  else
	    {
	      gimple *bnd_def = SSA_NAME_DEF_STMT (bnd);
	      /* Sometimes (e.g. when we load a pointer from a
		 memory) bounds are produced later than a pointer.
		 We need to insert bounds copy appropriately.  */
	      if (gimple_code (bnd_def) != GIMPLE_NOP
		  && stmt_dominates_stmt_p (def, bnd_def))
		gsi = gsi_for_stmt (bnd_def);
	      else
		gsi = gsi_for_stmt (def);
	      gsi_insert_after (&gsi, assign, GSI_CONTINUE_LINKING);
	    }

	  bnd = copy;
	}

      if (abnormal_ptr)
	bitmap_set_bit (chkp_abnormal_copies, SSA_NAME_VERSION (bnd));
    }

  chkp_reg_bounds->put (ptr, bnd);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Regsitered bound ");
      print_generic_expr (dump_file, bnd);
      fprintf (dump_file, " for pointer ");
      print_generic_expr (dump_file, ptr);
      fprintf (dump_file, "\n");
    }

  return bnd;
}

/* Get bounds registered for object PTR in global bounds table.  */
static tree
chkp_get_registered_bounds (tree ptr)
{
  tree *slot;

  if (!chkp_reg_bounds)
    return NULL_TREE;

  slot = chkp_reg_bounds->get (ptr);
  return slot ? *slot : NULL_TREE;
}

/* Add bound retvals to return statement pointed by GSI.  */

static void
chkp_add_bounds_to_ret_stmt (gimple_stmt_iterator *gsi)
{
  greturn *ret = as_a <greturn *> (gsi_stmt (*gsi));
  tree retval = gimple_return_retval (ret);
  tree ret_decl = DECL_RESULT (cfun->decl);
  tree bounds;

  if (!retval)
    return;

  if (BOUNDED_P (ret_decl))
    {
      bounds = chkp_find_bounds (retval, gsi);
      bounds = chkp_maybe_copy_and_register_bounds (ret_decl, bounds);
      gimple_return_set_retbnd (ret, bounds);
    }

  update_stmt (ret);
}

/* Force OP to be suitable for using as an argument for call.
   New statements (if any) go to SEQ.  */
static tree
chkp_force_gimple_call_op (tree op, gimple_seq *seq)
{
  gimple_seq stmts;
  gimple_stmt_iterator si;

  op = force_gimple_operand (unshare_expr (op), &stmts, true, NULL_TREE);

  for (si = gsi_start (stmts); !gsi_end_p (si); gsi_next (&si))
    chkp_mark_stmt (gsi_stmt (si));

  gimple_seq_add_seq (seq, stmts);

  return op;
}

/* Generate lower bound check for memory access by ADDR.
   Check is inserted before the position pointed by ITER.
   DIRFLAG indicates whether memory access is load or store.  */
static void
chkp_check_lower (tree addr, tree bounds,
		  gimple_stmt_iterator iter,
		  location_t location,
		  tree dirflag)
{
  gimple_seq seq;
  gimple *check;
  tree node;

  if (!chkp_function_instrumented_p (current_function_decl)
      && bounds == chkp_get_zero_bounds ())
    return;

  if (dirflag == integer_zero_node
      && !flag_chkp_check_read)
    return;

  if (dirflag == integer_one_node
      && !flag_chkp_check_write)
    return;

  seq = NULL;

  node = chkp_force_gimple_call_op (addr, &seq);

  check = gimple_build_call (chkp_checkl_fndecl, 2, node, bounds);
  chkp_mark_stmt (check);
  gimple_call_set_with_bounds (check, true);
  gimple_set_location (check, location);
  gimple_seq_add_stmt (&seq, check);

  gsi_insert_seq_before (&iter, seq, GSI_SAME_STMT);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      gimple *before = gsi_stmt (iter);
      fprintf (dump_file, "Generated lower bound check for statement ");
      print_gimple_stmt (dump_file, before, 0, TDF_VOPS|TDF_MEMSYMS);
      fprintf (dump_file, "  ");
      print_gimple_stmt (dump_file, check, 0, TDF_VOPS|TDF_MEMSYMS);
    }
}

/* Generate upper bound check for memory access by ADDR.
   Check is inserted before the position pointed by ITER.
   DIRFLAG indicates whether memory access is load or store.  */
static void
chkp_check_upper (tree addr, tree bounds,
		  gimple_stmt_iterator iter,
		  location_t location,
		  tree dirflag)
{
  gimple_seq seq;
  gimple *check;
  tree node;

  if (!chkp_function_instrumented_p (current_function_decl)
      && bounds == chkp_get_zero_bounds ())
    return;

  if (dirflag == integer_zero_node
      && !flag_chkp_check_read)
    return;

  if (dirflag == integer_one_node
      && !flag_chkp_check_write)
    return;

  seq = NULL;

  node = chkp_force_gimple_call_op (addr, &seq);

  check = gimple_build_call (chkp_checku_fndecl, 2, node, bounds);
  chkp_mark_stmt (check);
  gimple_call_set_with_bounds (check, true);
  gimple_set_location (check, location);
  gimple_seq_add_stmt (&seq, check);

  gsi_insert_seq_before (&iter, seq, GSI_SAME_STMT);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      gimple *before = gsi_stmt (iter);
      fprintf (dump_file, "Generated upper bound check for statement ");
      print_gimple_stmt (dump_file, before, 0, TDF_VOPS|TDF_MEMSYMS);
      fprintf (dump_file, "  ");
      print_gimple_stmt (dump_file, check, 0, TDF_VOPS|TDF_MEMSYMS);
    }
}

/* Generate lower and upper bound checks for memory access
   to memory slot [FIRST, LAST] againsr BOUNDS.  Checks
   are inserted before the position pointed by ITER.
   DIRFLAG indicates whether memory access is load or store.  */
void
chkp_check_mem_access (tree first, tree last, tree bounds,
		       gimple_stmt_iterator iter,
		       location_t location,
		       tree dirflag)
{
  chkp_check_lower (first, bounds, iter, location, dirflag);
  chkp_check_upper (last, bounds, iter, location, dirflag);
}

/* Replace call to _bnd_chk_* pointed by GSI with
   bndcu and bndcl calls.  DIRFLAG determines whether
   check is for read or write.  */

void
chkp_replace_address_check_builtin (gimple_stmt_iterator *gsi,
				    tree dirflag)
{
  gimple_stmt_iterator call_iter = *gsi;
  gimple *call = gsi_stmt (*gsi);
  tree fndecl = gimple_call_fndecl (call);
  tree addr = gimple_call_arg (call, 0);
  tree bounds = chkp_find_bounds (addr, gsi);

  if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_CHECK_PTR_LBOUNDS
      || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_CHECK_PTR_BOUNDS)
    chkp_check_lower (addr, bounds, *gsi, gimple_location (call), dirflag);

  if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_CHECK_PTR_UBOUNDS)
    chkp_check_upper (addr, bounds, *gsi, gimple_location (call), dirflag);

  if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_CHECK_PTR_BOUNDS)
    {
      tree size = gimple_call_arg (call, 1);
      addr = fold_build_pointer_plus (addr, size);
      addr = fold_build_pointer_plus_hwi (addr, -1);
      chkp_check_upper (addr, bounds, *gsi, gimple_location (call), dirflag);
    }

  gsi_remove (&call_iter, true);
}

/* Replace call to _bnd_get_ptr_* pointed by GSI with
   corresponding bounds extract call.  */

void
chkp_replace_extract_builtin (gimple_stmt_iterator *gsi)
{
  gimple *call = gsi_stmt (*gsi);
  tree fndecl = gimple_call_fndecl (call);
  tree addr = gimple_call_arg (call, 0);
  tree bounds = chkp_find_bounds (addr, gsi);
  gimple *extract;

  if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_GET_PTR_LBOUND)
    fndecl = chkp_extract_lower_fndecl;
  else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_GET_PTR_UBOUND)
    fndecl = chkp_extract_upper_fndecl;
  else
    gcc_unreachable ();

  extract = gimple_build_call (fndecl, 1, bounds);
  gimple_call_set_lhs (extract, gimple_call_lhs (call));
  chkp_mark_stmt (extract);

  gsi_replace (gsi, extract, false);
}

/* Return COMPONENT_REF accessing FIELD in OBJ.  */
static tree
chkp_build_component_ref (tree obj, tree field)
{
  tree res;

  /* If object is TMR then we do not use component_ref but
     add offset instead.  We need it to be able to get addr
     of the reasult later.  */
  if (TREE_CODE (obj) == TARGET_MEM_REF)
    {
      tree offs = TMR_OFFSET (obj);
      offs = fold_binary_to_constant (PLUS_EXPR, TREE_TYPE (offs),
				      offs, DECL_FIELD_OFFSET (field));

      gcc_assert (offs);

      res = copy_node (obj);
      TREE_TYPE (res) = TREE_TYPE (field);
      TMR_OFFSET (res) = offs;
    }
  else
    res = build3 (COMPONENT_REF, TREE_TYPE (field), obj, field, NULL_TREE);

  return res;
}

/* Return ARRAY_REF for array ARR and index IDX with
   specified element type ETYPE and element size ESIZE.  */
static tree
chkp_build_array_ref (tree arr, tree etype, tree esize,
		      unsigned HOST_WIDE_INT idx)
{
  tree index = build_int_cst (size_type_node, idx);
  tree res;

  /* If object is TMR then we do not use array_ref but
     add offset instead.  We need it to be able to get addr
     of the reasult later.  */
  if (TREE_CODE (arr) == TARGET_MEM_REF)
    {
      tree offs = TMR_OFFSET (arr);

      esize = fold_binary_to_constant (MULT_EXPR, TREE_TYPE (esize),
				     esize, index);
      gcc_assert(esize);

      offs = fold_binary_to_constant (PLUS_EXPR, TREE_TYPE (offs),
				    offs, esize);
      gcc_assert (offs);

      res = copy_node (arr);
      TREE_TYPE (res) = etype;
      TMR_OFFSET (res) = offs;
    }
  else
    res = build4 (ARRAY_REF, etype, arr, index, NULL_TREE, NULL_TREE);

  return res;
}

/* Helper function for chkp_add_bounds_to_call_stmt.
   Fill ALL_BOUNDS output array with created bounds.

   OFFS is used for recursive calls and holds basic
   offset of TYPE in outer structure in bits.

   ITER points a position where bounds are searched.

   ALL_BOUNDS[i] is filled with elem bounds if there
   is a field in TYPE which has pointer type and offset
   equal to i * POINTER_SIZE in bits.  */
static void
chkp_find_bounds_for_elem (tree elem, tree *all_bounds,
			   HOST_WIDE_INT offs,
			   gimple_stmt_iterator *iter)
{
  tree type = TREE_TYPE (elem);

  if (BOUNDED_TYPE_P (type))
    {
      if (!all_bounds[offs / POINTER_SIZE])
	{
	  tree temp = make_temp_ssa_name (type, NULL, "");
	  gimple *assign = gimple_build_assign (temp, elem);
	  gimple_stmt_iterator gsi;

	  gsi_insert_before (iter, assign, GSI_SAME_STMT);
	  gsi = gsi_for_stmt (assign);

	  all_bounds[offs / POINTER_SIZE] = chkp_find_bounds (temp, &gsi);
	}
    }
  else if (RECORD_OR_UNION_TYPE_P (type))
    {
      tree field;

      for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
	if (TREE_CODE (field) == FIELD_DECL)
	  {
	    tree base = unshare_expr (elem);
	    tree field_ref = chkp_build_component_ref (base, field);
	    HOST_WIDE_INT field_offs
	      = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field));
	    if (DECL_FIELD_OFFSET (field))
	      field_offs += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field)) * 8;

	    chkp_find_bounds_for_elem (field_ref, all_bounds,
				       offs + field_offs, iter);
	  }
    }
  else if (TREE_CODE (type) == ARRAY_TYPE)
    {
      tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
      tree etype = TREE_TYPE (type);
      HOST_WIDE_INT esize = TREE_INT_CST_LOW (TYPE_SIZE (etype));
      unsigned HOST_WIDE_INT cur;

      if (!maxval || integer_minus_onep (maxval))
	return;

      for (cur = 0; cur <= TREE_INT_CST_LOW (maxval); cur++)
	{
	  tree base = unshare_expr (elem);
	  tree arr_elem = chkp_build_array_ref (base, etype,
						TYPE_SIZE (etype),
						cur);
	  chkp_find_bounds_for_elem (arr_elem, all_bounds, offs + cur * esize,
				     iter);
	}
    }
}

/* Maximum number of elements to check in an array.  */

#define CHKP_ARRAY_MAX_CHECK_STEPS    4096

/* Fill HAVE_BOUND output bitmap with information about
   bounds requred for object of type TYPE.

   OFFS is used for recursive calls and holds basic
   offset of TYPE in outer structure in bits.

   HAVE_BOUND[i] is set to 1 if there is a field
   in TYPE which has pointer type and offset
   equal to i * POINTER_SIZE - OFFS in bits.  */
void
chkp_find_bound_slots_1 (const_tree type, bitmap have_bound,
			 HOST_WIDE_INT offs)
{
  if (BOUNDED_TYPE_P (type))
    bitmap_set_bit (have_bound, offs / POINTER_SIZE);
  else if (RECORD_OR_UNION_TYPE_P (type))
    {
      tree field;

      for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
	if (TREE_CODE (field) == FIELD_DECL)
	  {
	    HOST_WIDE_INT field_offs = 0;
	    if (DECL_FIELD_BIT_OFFSET (field))
	      field_offs += TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field));
	    if (DECL_FIELD_OFFSET (field))
	      field_offs += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field)) * 8;
	    chkp_find_bound_slots_1 (TREE_TYPE (field), have_bound,
				     offs + field_offs);
	  }
    }
  else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
    {
      /* The object type is an array of complete type, i.e., other
	 than a flexible array.  */
      tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
      tree etype = TREE_TYPE (type);
      HOST_WIDE_INT esize = TREE_INT_CST_LOW (TYPE_SIZE (etype));
      unsigned HOST_WIDE_INT cur;

      if (!maxval
	  || TREE_CODE (maxval) != INTEGER_CST
	  || integer_minus_onep (maxval))
	return;

      for (cur = 0;
	  cur <= MIN (CHKP_ARRAY_MAX_CHECK_STEPS, TREE_INT_CST_LOW (maxval));
	  cur++)
	chkp_find_bound_slots_1 (etype, have_bound, offs + cur * esize);
    }
}

/* Fill bitmap RES with information about bounds for
   type TYPE.  See chkp_find_bound_slots_1 for more
   details.  */
void
chkp_find_bound_slots (const_tree type, bitmap res)
{
  bitmap_clear (res);
  chkp_find_bound_slots_1 (type, res, 0);
}

/* Return 1 if call to FNDECL should be instrumented
   and 0 otherwise.  */

static bool
chkp_instrument_normal_builtin (tree fndecl)
{
  switch (DECL_FUNCTION_CODE (fndecl))
    {
    case BUILT_IN_STRLEN:
    case BUILT_IN_STRCPY:
    case BUILT_IN_STRNCPY:
    case BUILT_IN_STPCPY:
    case BUILT_IN_STPNCPY:
    case BUILT_IN_STRCAT:
    case BUILT_IN_STRNCAT:
    case BUILT_IN_MEMCPY:
    case BUILT_IN_MEMPCPY:
    case BUILT_IN_MEMSET:
    case BUILT_IN_MEMMOVE:
    case BUILT_IN_BZERO:
    case BUILT_IN_STRCMP:
    case BUILT_IN_STRNCMP:
    case BUILT_IN_BCMP:
    case BUILT_IN_MEMCMP:
    case BUILT_IN_MEMCPY_CHK:
    case BUILT_IN_MEMPCPY_CHK:
    case BUILT_IN_MEMMOVE_CHK:
    case BUILT_IN_MEMSET_CHK:
    case BUILT_IN_STRCPY_CHK:
    case BUILT_IN_STRNCPY_CHK:
    case BUILT_IN_STPCPY_CHK:
    case BUILT_IN_STPNCPY_CHK:
    case BUILT_IN_STRCAT_CHK:
    case BUILT_IN_STRNCAT_CHK:
    case BUILT_IN_MALLOC:
    case BUILT_IN_CALLOC:
    case BUILT_IN_REALLOC:
      return 1;

    default:
      return 0;
    }
}

/* Add bound arguments to call statement pointed by GSI.
   Also performs a replacement of user checker builtins calls
   with internal ones.  */

static void
chkp_add_bounds_to_call_stmt (gimple_stmt_iterator *gsi)
{
  gcall *call = as_a <gcall *> (gsi_stmt (*gsi));
  unsigned arg_no = 0;
  tree fndecl = gimple_call_fndecl (call);
  tree fntype;
  tree first_formal_arg;
  tree arg;
  bool use_fntype = false;
  tree op;
  ssa_op_iter iter;
  gcall *new_call;

  /* Do nothing for internal functions.  */
  if (gimple_call_internal_p (call))
    return;

  fntype = TREE_TYPE (TREE_TYPE (gimple_call_fn (call)));

  /* Do nothing if back-end builtin is called.  */
  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
    return;

  /* Do nothing for some middle-end builtins.  */
  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_OBJECT_SIZE)
    return;

  /* Do nothing for calls to not instrumentable functions.  */
  if (fndecl && !chkp_instrumentable_p (fndecl))
    return;

  /* Ignore CHKP_INIT_PTR_BOUNDS, CHKP_NULL_PTR_BOUNDS
     and CHKP_COPY_PTR_BOUNDS.  */
  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
      && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_INIT_PTR_BOUNDS
	  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_NULL_PTR_BOUNDS
	  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_COPY_PTR_BOUNDS
	  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_SET_PTR_BOUNDS))
    return;

  /* Check user builtins are replaced with checks.  */
  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
      && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_CHECK_PTR_LBOUNDS
	  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_CHECK_PTR_UBOUNDS
	  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_CHECK_PTR_BOUNDS))
    {
      chkp_replace_address_check_builtin (gsi, integer_minus_one_node);
      return;
    }

  /* Check user builtins are replaced with bound extract.  */
  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
      && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_GET_PTR_LBOUND
	  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_GET_PTR_UBOUND))
    {
      chkp_replace_extract_builtin (gsi);
      return;
    }

  /* BUILT_IN_CHKP_NARROW_PTR_BOUNDS call is replaced with
     target narrow bounds call.  */
  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_NARROW_PTR_BOUNDS)
    {
      tree arg = gimple_call_arg (call, 1);
      tree bounds = chkp_find_bounds (arg, gsi);

      gimple_call_set_fndecl (call, chkp_narrow_bounds_fndecl);
      gimple_call_set_arg (call, 1, bounds);
      update_stmt (call);

      return;
    }

  /* BUILT_IN_CHKP_STORE_PTR_BOUNDS call is replaced with
     bndstx call.  */
  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_STORE_PTR_BOUNDS)
    {
      tree addr = gimple_call_arg (call, 0);
      tree ptr = gimple_call_arg (call, 1);
      tree bounds = chkp_find_bounds (ptr, gsi);
      gimple_stmt_iterator iter = gsi_for_stmt (call);

      chkp_build_bndstx (addr, ptr, bounds, gsi);
      gsi_remove (&iter, true);

      return;
    }

  if (!flag_chkp_instrument_calls)
    return;

  /* We instrument only some subset of builtins.  We also instrument
     builtin calls to be inlined.  */
  if (fndecl
      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
      && !chkp_instrument_normal_builtin (fndecl))
    {
      if (!lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)))
	return;

      struct cgraph_node *clone = chkp_maybe_create_clone (fndecl);
      if (!clone
	  || !gimple_has_body_p (clone->decl))
	return;
    }

  /* If function decl is available then use it for
     formal arguments list.  Otherwise use function type.  */
  if (fndecl
      && DECL_ARGUMENTS (fndecl)
      && gimple_call_fntype (call) == TREE_TYPE (fndecl))
    first_formal_arg = DECL_ARGUMENTS (fndecl);
  else
    {
      first_formal_arg = TYPE_ARG_TYPES (fntype);
      use_fntype = true;
    }

  /* Fill vector of new call args.  */
  vec<tree> new_args = vNULL;
  new_args.create (gimple_call_num_args (call));
  arg = first_formal_arg;
  for (arg_no = 0; arg_no < gimple_call_num_args (call); arg_no++)
    {
      tree call_arg = gimple_call_arg (call, arg_no);
      tree type;

      /* Get arg type using formal argument description
	 or actual argument type.  */
      if (arg)
	if (use_fntype)
	  if (TREE_VALUE (arg) != void_type_node)
	    {
	      type = TREE_VALUE (arg);
	      arg = TREE_CHAIN (arg);
	    }
	  else
	    type = TREE_TYPE (call_arg);
	else
	  {
	    type = TREE_TYPE (arg);
	    arg = TREE_CHAIN (arg);
	  }
      else
	type = TREE_TYPE (call_arg);

      new_args.safe_push (call_arg);

      if (BOUNDED_TYPE_P (type)
	  || pass_by_reference (NULL, TYPE_MODE (type), type, true))
	new_args.safe_push (chkp_find_bounds (call_arg, gsi));
      else if (chkp_type_has_pointer (type))
	{
	  HOST_WIDE_INT max_bounds
	    = TREE_INT_CST_LOW (TYPE_SIZE (type)) / POINTER_SIZE;
	  tree *all_bounds = (tree *)xmalloc (sizeof (tree) * max_bounds);
	  HOST_WIDE_INT bnd_no;

	  memset (all_bounds, 0, sizeof (tree) * max_bounds);

	  chkp_find_bounds_for_elem (call_arg, all_bounds, 0, gsi);

	  for (bnd_no = 0; bnd_no < max_bounds; bnd_no++)
	    if (all_bounds[bnd_no])
	      new_args.safe_push (all_bounds[bnd_no]);

           free (all_bounds);
	}
    }

  if (new_args.length () == gimple_call_num_args (call))
    new_call = call;
  else
    {
      new_call = gimple_build_call_vec (gimple_op (call, 1), new_args);
      gimple_call_set_lhs (new_call, gimple_call_lhs (call));
      gimple_call_copy_flags (new_call, call);
      gimple_call_set_chain (new_call, gimple_call_chain (call));
    }
  new_args.release ();

  /* For direct calls fndecl is replaced with instrumented version.  */
  if (fndecl)
    {
      tree new_decl = chkp_maybe_create_clone (fndecl)->decl;
      gimple_call_set_fndecl (new_call, new_decl);
      /* In case of a type cast we should modify used function
	 type instead of using type of new fndecl.  */
      if (gimple_call_fntype (call) != TREE_TYPE (fndecl))
	{
	  tree type = gimple_call_fntype (call);
	  type = chkp_copy_function_type_adding_bounds (type);
	  gimple_call_set_fntype (new_call, type);
	}
      else
	gimple_call_set_fntype (new_call, TREE_TYPE (new_decl));
    }
  /* For indirect call we should fix function pointer type if
     pass some bounds.  */
  else if (new_call != call)
    {
      tree type = gimple_call_fntype (call);
      type = chkp_copy_function_type_adding_bounds (type);
      gimple_call_set_fntype (new_call, type);
    }

  /* replace old call statement with the new one.  */
  if (call != new_call)
    {
      FOR_EACH_SSA_TREE_OPERAND (op, call, iter, SSA_OP_ALL_DEFS)
	{
	  SSA_NAME_DEF_STMT (op) = new_call;
	}
      gsi_replace (gsi, new_call, true);
    }
  else
    update_stmt (new_call);

  gimple_call_set_with_bounds (new_call, true);
}

/* Return constant static bounds var with specified bounds LB and UB.
   If such var does not exists then new var is created with specified NAME.  */
static tree
chkp_make_static_const_bounds (HOST_WIDE_INT lb,
			       HOST_WIDE_INT ub,
			       const char *name)
{
  tree id = get_identifier (name);
  tree var;
  varpool_node *node;
  symtab_node *snode;

  var  = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
		     pointer_bounds_type_node);
  TREE_STATIC (var) = 1;
  TREE_PUBLIC (var) = 1;

  /* With LTO we may have constant bounds already in varpool.
     Try to find it.  */
  if ((snode = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (var))))
    {
      /* We don't allow this symbol usage for non bounds.  */
      if (snode->type != SYMTAB_VARIABLE
	  || !POINTER_BOUNDS_P (snode->decl))
	sorry ("-fcheck-pointer-bounds requires %qs "
	       "name for internal usage",
	       IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (var)));

      return snode->decl;
    }

  TREE_USED (var) = 1;
  TREE_READONLY (var) = 1;
  TREE_ADDRESSABLE (var) = 0;
  DECL_ARTIFICIAL (var) = 1;
  DECL_READ_P (var) = 1;
  DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
  make_decl_one_only (var, DECL_ASSEMBLER_NAME (var));
  /* We may use this symbol during ctors generation in chkp_finish_file
     when all symbols are emitted.  Force output to avoid undefined
     symbols in ctors.  */
  node = varpool_node::get_create (var);
  node->force_output = 1;

  varpool_node::finalize_decl (var);

  return var;
}

/* Generate code to make bounds with specified lower bound LB and SIZE.
   if AFTER is 1 then code is inserted after position pointed by ITER
   otherwise code is inserted before position pointed by ITER.
   If ITER is NULL then code is added to entry block.  */
static tree
chkp_make_bounds (tree lb, tree size, gimple_stmt_iterator *iter, bool after)
{
  gimple_seq seq;
  gimple_stmt_iterator gsi;
  gimple *stmt;
  tree bounds;

  if (iter)
    gsi = *iter;
  else
    gsi = gsi_start_bb (chkp_get_entry_block ());

  seq = NULL;

  lb = chkp_force_gimple_call_op (lb, &seq);
  size = chkp_force_gimple_call_op (size, &seq);

  stmt = gimple_build_call (chkp_bndmk_fndecl, 2, lb, size);
  chkp_mark_stmt (stmt);

  bounds = chkp_get_tmp_reg (stmt);
  gimple_call_set_lhs (stmt, bounds);

  gimple_seq_add_stmt (&seq, stmt);

  if (iter && after)
    gsi_insert_seq_after (&gsi, seq, GSI_SAME_STMT);
  else
    gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Made bounds: ");
      print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS|TDF_MEMSYMS);
      if (iter)
	{
	  fprintf (dump_file, "  inserted before statement: ");
	  print_gimple_stmt (dump_file, gsi_stmt (*iter), 0, TDF_VOPS|TDF_MEMSYMS);
	}
      else
	fprintf (dump_file, "  at function entry\n");
    }

  /* update_stmt (stmt); */

  return bounds;
}

/* Return var holding zero bounds.  */
tree
chkp_get_zero_bounds_var (void)
{
  if (!chkp_zero_bounds_var)
    chkp_zero_bounds_var
      = chkp_make_static_const_bounds (0, -1,
				       CHKP_ZERO_BOUNDS_VAR_NAME);
  return chkp_zero_bounds_var;
}

/* Return var holding none bounds.  */
tree
chkp_get_none_bounds_var (void)
{
  if (!chkp_none_bounds_var)
    chkp_none_bounds_var
      = chkp_make_static_const_bounds (-1, 0,
				       CHKP_NONE_BOUNDS_VAR_NAME);
  return chkp_none_bounds_var;
}

/* Return SSA_NAME used to represent zero bounds.  */
static tree
chkp_get_zero_bounds (void)
{
  if (zero_bounds)
    return zero_bounds;

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Creating zero bounds...");

  if ((flag_chkp_use_static_bounds && flag_chkp_use_static_const_bounds)
      || flag_chkp_use_static_const_bounds > 0)
    {
      gimple_stmt_iterator gsi = gsi_start_bb (chkp_get_entry_block ());
      gimple *stmt;

      zero_bounds = chkp_get_tmp_reg (NULL);
      stmt = gimple_build_assign (zero_bounds, chkp_get_zero_bounds_var ());
      gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
    }
  else
    zero_bounds = chkp_make_bounds (integer_zero_node,
				    integer_zero_node,
				    NULL,
				    false);

  return zero_bounds;
}

/* Return SSA_NAME used to represent none bounds.  */
static tree
chkp_get_none_bounds (void)
{
  if (none_bounds)
    return none_bounds;

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Creating none bounds...");


  if ((flag_chkp_use_static_bounds && flag_chkp_use_static_const_bounds)
      || flag_chkp_use_static_const_bounds > 0)
    {
      gimple_stmt_iterator gsi = gsi_start_bb (chkp_get_entry_block ());
      gimple *stmt;

      none_bounds = chkp_get_tmp_reg (NULL);
      stmt = gimple_build_assign (none_bounds, chkp_get_none_bounds_var ());
      gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
    }
  else
    none_bounds = chkp_make_bounds (integer_minus_one_node,
				    build_int_cst (size_type_node, 2),
				    NULL,
				    false);

  return none_bounds;
}

/* Return bounds to be used as a result of operation which
   should not create poiunter (e.g. MULT_EXPR).  */
static tree
chkp_get_invalid_op_bounds (void)
{
  return chkp_get_zero_bounds ();
}

/* Return bounds to be used for loads of non-pointer values.  */
static tree
chkp_get_nonpointer_load_bounds (void)
{
  return chkp_get_zero_bounds ();
}

/* Return 1 if may use bndret call to get bounds for pointer
   returned by CALL.  */
static bool
chkp_call_returns_bounds_p (gcall *call)
{
  if (gimple_call_internal_p (call))
    {
      if (gimple_call_internal_fn (call) == IFN_VA_ARG)
	return true;
      return false;
    }

  if (gimple_call_builtin_p (call, BUILT_IN_CHKP_NARROW_PTR_BOUNDS)
      || chkp_gimple_call_builtin_p (call, BUILT_IN_CHKP_NARROW))
    return true;

  if (gimple_call_with_bounds_p (call))
    return true;

  tree fndecl = gimple_call_fndecl (call);

  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
    return false;

  if (fndecl && !chkp_instrumentable_p (fndecl))
    return false;

  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
    {
      if (chkp_instrument_normal_builtin (fndecl))
	return true;

      if (!lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)))
	return false;

      struct cgraph_node *clone = chkp_maybe_create_clone (fndecl);
      return (clone && gimple_has_body_p (clone->decl));
    }

  return true;
}

/* Build bounds returned by CALL.  */
static tree
chkp_build_returned_bound (gcall *call)
{
  gimple_stmt_iterator gsi;
  tree bounds;
  gimple *stmt;
  tree fndecl = gimple_call_fndecl (call);
  unsigned int retflags;
  tree lhs = gimple_call_lhs (call);

  /* To avoid fixing alloca expands in targets we handle
     it separately.  */
  if (fndecl
      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
      && ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (fndecl)))
    {
      tree size = gimple_call_arg (call, 0);
      gimple_stmt_iterator iter = gsi_for_stmt (call);
      bounds = chkp_make_bounds (lhs, size, &iter, true);
    }
  /* We know bounds returned by set_bounds builtin call.  */
  else if (fndecl
	   && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
	   && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_SET_PTR_BOUNDS)
    {
      tree lb = gimple_call_arg (call, 0);
      tree size = gimple_call_arg (call, 1);
      gimple_stmt_iterator iter = gsi_for_stmt (call);
      bounds = chkp_make_bounds (lb, size, &iter, true);
    }
  /* Detect bounds initialization calls.  */
  else if (fndecl
      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_INIT_PTR_BOUNDS)
    bounds = chkp_get_zero_bounds ();
  /* Detect bounds nullification calls.  */
  else if (fndecl
      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_NULL_PTR_BOUNDS)
    bounds = chkp_get_none_bounds ();
  /* Detect bounds copy calls.  */
  else if (fndecl
      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_COPY_PTR_BOUNDS)
    {
      gimple_stmt_iterator iter = gsi_for_stmt (call);
      bounds = chkp_find_bounds (gimple_call_arg (call, 1), &iter);
    }
  /* Do not use retbnd when returned bounds are equal to some
     of passed bounds.  */
  else if (((retflags = gimple_call_return_flags (call)) & ERF_RETURNS_ARG)
	   && (retflags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (call))
    {
      gimple_stmt_iterator iter = gsi_for_stmt (call);
      unsigned int retarg = retflags & ERF_RETURN_ARG_MASK, argno;
      if (gimple_call_with_bounds_p (call))
	{
	  for (argno = 0; argno < gimple_call_num_args (call); argno++)
	    if (!POINTER_BOUNDS_P (gimple_call_arg (call, argno)))
	      {
		if (retarg)
		  retarg--;
		else
		  break;
	      }
	}
      else
	argno = retarg;

      bounds = chkp_find_bounds (gimple_call_arg (call, argno), &iter);
    }
  else if (chkp_call_returns_bounds_p (call)
	   && BOUNDED_P (lhs))
    {
      gcc_assert (TREE_CODE (lhs) == SSA_NAME);

      /* In general case build checker builtin call to
	 obtain returned bounds.  */
      stmt = gimple_build_call (chkp_ret_bnd_fndecl, 1,
				gimple_call_lhs (call));
      chkp_mark_stmt (stmt);

      gsi = gsi_for_stmt (call);
      gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);

      bounds = chkp_get_tmp_reg (stmt);
      gimple_call_set_lhs (stmt, bounds);

      update_stmt (stmt);
    }
  else
    bounds = chkp_get_zero_bounds ();

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Built returned bounds (");
      print_generic_expr (dump_file, bounds);
      fprintf (dump_file, ") for call: ");
      print_gimple_stmt (dump_file, call, 0, TDF_VOPS | TDF_MEMSYMS);
    }

  bounds = chkp_maybe_copy_and_register_bounds (lhs, bounds);

  return bounds;
}

/* Return bounds used as returned by call
   which produced SSA name VAL.  */
gcall *
chkp_retbnd_call_by_val (tree val)
{
  if (TREE_CODE (val) != SSA_NAME)
    return NULL;

  gcc_assert (gimple_code (SSA_NAME_DEF_STMT (val)) == GIMPLE_CALL);

  imm_use_iterator use_iter;
  use_operand_p use_p;
  FOR_EACH_IMM_USE_FAST (use_p, use_iter, val)
    if (chkp_gimple_call_builtin_p (USE_STMT (use_p), BUILT_IN_CHKP_BNDRET))
      return as_a <gcall *> (USE_STMT (use_p));

  return NULL;
}

/* Check the next parameter for the given PARM is bounds
   and return it's default SSA_NAME (create if required).  */
static tree
chkp_get_next_bounds_parm (tree parm)
{
  tree bounds = TREE_CHAIN (parm);
  gcc_assert (POINTER_BOUNDS_P (bounds));
  bounds = ssa_default_def (cfun, bounds);
  if (!bounds)
    {
      bounds = make_ssa_name (TREE_CHAIN (parm), gimple_build_nop ());
      set_ssa_default_def (cfun, TREE_CHAIN (parm), bounds);
    }
  return bounds;
}

/* Return bounds to be used for input argument PARM.  */
static tree
chkp_get_bound_for_parm (tree parm)
{
  tree decl = SSA_NAME_VAR (parm);
  tree bounds;

  gcc_assert (TREE_CODE (decl) == PARM_DECL);

  bounds = chkp_get_registered_bounds (parm);

  if (!bounds)
    bounds = chkp_get_registered_bounds (decl);

  if (!bounds)
    {
      tree orig_decl = cgraph_node::get (cfun->decl)->orig_decl;

      /* For static chain param we return zero bounds
	 because currently we do not check dereferences
	 of this pointer.  */
      if (cfun->static_chain_decl == decl)
	bounds = chkp_get_zero_bounds ();
      /* If non instrumented runtime is used then it may be useful
	 to use zero bounds for input arguments of main
	 function.  */
      else if (flag_chkp_zero_input_bounds_for_main
	       && id_equal (DECL_ASSEMBLER_NAME (orig_decl), "main"))
	bounds = chkp_get_zero_bounds ();
      else if (BOUNDED_P (parm))
	{
	  bounds = chkp_get_next_bounds_parm (decl);
	  bounds = chkp_maybe_copy_and_register_bounds (decl, bounds);

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Built arg bounds (");
	      print_generic_expr (dump_file, bounds);
	      fprintf (dump_file, ") for arg: ");
	      print_node (dump_file, "", decl, 0);
	    }
	}
      else
	bounds = chkp_get_zero_bounds ();
    }

  if (!chkp_get_registered_bounds (parm))
    bounds = chkp_maybe_copy_and_register_bounds (parm, bounds);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Using bounds ");
      print_generic_expr (dump_file, bounds);
      fprintf (dump_file, " for parm ");
      print_generic_expr (dump_file, parm);
      fprintf (dump_file, " of type ");
      print_generic_expr (dump_file, TREE_TYPE (parm));
      fprintf (dump_file, ".\n");
    }

  return bounds;
}

/* Build and return CALL_EXPR for bndstx builtin with specified
   arguments.  */
tree
chkp_build_bndldx_call (tree addr, tree ptr)
{
  tree fn = build1 (ADDR_EXPR,
		    build_pointer_type (TREE_TYPE (chkp_bndldx_fndecl)),
		    chkp_bndldx_fndecl);
  tree call = build_call_nary (TREE_TYPE (TREE_TYPE (chkp_bndldx_fndecl)),
			       fn, 2, addr, ptr);
  CALL_WITH_BOUNDS_P (call) = true;
  return call;
}

/* Insert code to load bounds for PTR located by ADDR.
   Code is inserted after position pointed by GSI.
   Loaded bounds are returned.  */
static tree
chkp_build_bndldx (tree addr, tree ptr, gimple_stmt_iterator *gsi)
{
  gimple_seq seq;
  gimple *stmt;
  tree bounds;

  seq = NULL;

  addr = chkp_force_gimple_call_op (addr, &seq);
  ptr = chkp_force_gimple_call_op (ptr, &seq);

  stmt = gimple_build_call (chkp_bndldx_fndecl, 2, addr, ptr);
  chkp_mark_stmt (stmt);
  bounds = chkp_get_tmp_reg (stmt);
  gimple_call_set_lhs (stmt, bounds);

  gimple_seq_add_stmt (&seq, stmt);

  gsi_insert_seq_after (gsi, seq, GSI_CONTINUE_LINKING);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Generated bndldx for pointer ");
      print_generic_expr (dump_file, ptr);
      fprintf (dump_file, ": ");
      print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS | TDF_MEMSYMS);
    }

  return bounds;
}

/* Build and return CALL_EXPR for bndstx builtin with specified
   arguments.  */
tree
chkp_build_bndstx_call (tree addr, tree ptr, tree bounds)
{
  tree fn = build1 (ADDR_EXPR,
		    build_pointer_type (TREE_TYPE (chkp_bndstx_fndecl)),
		    chkp_bndstx_fndecl);
  tree call = build_call_nary (TREE_TYPE (TREE_TYPE (chkp_bndstx_fndecl)),
			       fn, 3, ptr, bounds, addr);
  CALL_WITH_BOUNDS_P (call) = true;
  return call;
}

/* Insert code to store BOUNDS for PTR stored by ADDR.
   New statements are inserted after position pointed
   by GSI.  */
void
chkp_build_bndstx (tree addr, tree ptr, tree bounds,
		   gimple_stmt_iterator *gsi)
{
  gimple_seq seq;
  gimple *stmt;

  seq = NULL;

  addr = chkp_force_gimple_call_op (addr, &seq);
  ptr = chkp_force_gimple_call_op (ptr, &seq);

  stmt = gimple_build_call (chkp_bndstx_fndecl, 3, ptr, bounds, addr);
  chkp_mark_stmt (stmt);
  gimple_call_set_with_bounds (stmt, true);

  gimple_seq_add_stmt (&seq, stmt);

  gsi_insert_seq_after (gsi, seq, GSI_CONTINUE_LINKING);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Generated bndstx for pointer store ");
      print_gimple_stmt (dump_file, gsi_stmt (*gsi), 0, TDF_VOPS|TDF_MEMSYMS);
      print_gimple_stmt (dump_file, stmt, 2, TDF_VOPS|TDF_MEMSYMS);
    }
}

/* This function is called when call statement
   is inlined and therefore we can't use bndret
   for its LHS anymore.  Function fixes bndret
   call using new RHS value if possible.  */
void
chkp_fixup_inlined_call (tree lhs, tree rhs)
{
  tree addr, bounds;
  gcall *retbnd, *bndldx;

  if (!BOUNDED_P (lhs))
    return;

  /* Search for retbnd call.  */
  retbnd = chkp_retbnd_call_by_val (lhs);
  if (!retbnd)
    return;

  /* Currently only handle cases when call is replaced
     with a memory access.  In this case bndret call
     may be replaced with bndldx call.  Otherwise we
     have to search for bounds which may cause wrong
     result due to various optimizations applied.  */
  switch (TREE_CODE (rhs))
    {
    case VAR_DECL:
      if (DECL_REGISTER (rhs))
	return;
      break;

    case MEM_REF:
      break;

    case ARRAY_REF:
    case COMPONENT_REF:
      addr = get_base_address (rhs);
      if (!DECL_P (addr)
	  && TREE_CODE (addr) != MEM_REF)
	return;
      if (DECL_P (addr) && DECL_REGISTER (addr))
	return;
      break;

    default:
      return;
    }

  /* Create a new statements sequence with bndldx call.  */
  gimple_stmt_iterator gsi = gsi_for_stmt (retbnd);
  addr = build_fold_addr_expr (rhs);
  chkp_build_bndldx (addr, lhs, &gsi);
  bndldx = as_a <gcall *> (gsi_stmt (gsi));

  /* Remove bndret call.  */
  bounds = gimple_call_lhs (retbnd);
  gsi = gsi_for_stmt (retbnd);
  gsi_remove (&gsi, true);

  /* Link new bndldx call.  */
  gimple_call_set_lhs (bndldx, bounds);
  update_stmt (bndldx);
}

/* Compute bounds for pointer NODE which was assigned in
   assignment statement ASSIGN.  Return computed bounds.  */
static tree
chkp_compute_bounds_for_assignment (tree node, gimple *assign)
{
  enum tree_code rhs_code = gimple_assign_rhs_code (assign);
  tree rhs1 = gimple_assign_rhs1 (assign);
  tree bounds = NULL_TREE;
  gimple_stmt_iterator iter = gsi_for_stmt (assign);
  tree base = NULL;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Computing bounds for assignment: ");
      print_gimple_stmt (dump_file, assign, 0, TDF_VOPS|TDF_MEMSYMS);
    }

  switch (rhs_code)
    {
    case MEM_REF:
    case TARGET_MEM_REF:
    case COMPONENT_REF:
    case ARRAY_REF:
      /* We need to load bounds from the bounds table.  */
      bounds = chkp_find_bounds_loaded (node, rhs1, &iter);
      break;

    case VAR_DECL:
    case SSA_NAME:
    case ADDR_EXPR:
    case POINTER_PLUS_EXPR:
    case NOP_EXPR:
    case CONVERT_EXPR:
    case INTEGER_CST:
      /* Bounds are just propagated from RHS.  */
      bounds = chkp_find_bounds (rhs1, &iter);
      base = rhs1;
      break;

    case VIEW_CONVERT_EXPR:
      /* Bounds are just propagated from RHS.  */
      bounds = chkp_find_bounds (TREE_OPERAND (rhs1, 0), &iter);
      break;

    case PARM_DECL:
      if (BOUNDED_P (rhs1))
	{
	  /* We need to load bounds from the bounds table.  */
	  bounds = chkp_build_bndldx (chkp_build_addr_expr (rhs1),
				      node, &iter);
	  TREE_ADDRESSABLE (rhs1) = 1;
	}
      else
	bounds = chkp_get_nonpointer_load_bounds ();
      break;

    case MINUS_EXPR:
    case PLUS_EXPR:
    case BIT_AND_EXPR:
    case BIT_IOR_EXPR:
    case BIT_XOR_EXPR:
      {
	tree rhs2 = gimple_assign_rhs2 (assign);
	tree bnd1 = chkp_find_bounds (rhs1, &iter);
	tree bnd2 = chkp_find_bounds (rhs2, &iter);

	/* First we try to check types of operands.  If it
	   does not help then look at bound values.

	   If some bounds are incomplete and other are
	   not proven to be valid (i.e. also incomplete
	   or invalid because value is not pointer) then
	   resulting value is incomplete and will be
	   recomputed later in chkp_finish_incomplete_bounds.  */
	if (BOUNDED_P (rhs1)
	    && !BOUNDED_P (rhs2))
	  bounds = bnd1;
	else if (BOUNDED_P (rhs2)
		 && !BOUNDED_P (rhs1)
		 && rhs_code != MINUS_EXPR)
	  bounds = bnd2;
	else if (chkp_incomplete_bounds (bnd1))
	  if (chkp_valid_bounds (bnd2) && rhs_code != MINUS_EXPR
	      && !chkp_incomplete_bounds (bnd2))
	    bounds = bnd2;
	  else
	    bounds = incomplete_bounds;
	else if (chkp_incomplete_bounds (bnd2))
	  if (chkp_valid_bounds (bnd1)
	      && !chkp_incomplete_bounds (bnd1))
	    bounds = bnd1;
	  else
	    bounds = incomplete_bounds;
	else if (!chkp_valid_bounds (bnd1))
	  if (chkp_valid_bounds (bnd2) && rhs_code != MINUS_EXPR)
	    bounds = bnd2;
	  else if (bnd2 == chkp_get_zero_bounds ())
	    bounds = bnd2;
	  else
	    bounds = bnd1;
	else if (!chkp_valid_bounds (bnd2))
	  bounds = bnd1;
	else
	  /* Seems both operands may have valid bounds
	     (e.g. pointer minus pointer).  In such case
	     use default invalid op bounds.  */
	  bounds = chkp_get_invalid_op_bounds ();

	base = (bounds == bnd1) ? rhs1 : (bounds == bnd2) ? rhs2 : NULL;
      }
      break;

    case BIT_NOT_EXPR:
    case NEGATE_EXPR:
    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
    case LROTATE_EXPR:
    case RROTATE_EXPR:
    case EQ_EXPR:
    case NE_EXPR:
    case LT_EXPR:
    case LE_EXPR:
    case GT_EXPR:
    case GE_EXPR:
    case MULT_EXPR:
    case RDIV_EXPR:
    case TRUNC_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case TRUNC_MOD_EXPR:
    case FLOOR_MOD_EXPR:
    case CEIL_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case EXACT_DIV_EXPR:
    case FIX_TRUNC_EXPR:
    case FLOAT_EXPR:
    case REALPART_EXPR:
    case IMAGPART_EXPR:
    case POINTER_DIFF_EXPR:
      /* No valid bounds may be produced by these exprs.  */
      bounds = chkp_get_invalid_op_bounds ();
      break;

    case COND_EXPR:
      {
	tree val1 = gimple_assign_rhs2 (assign);
	tree val2 = gimple_assign_rhs3 (assign);
	tree bnd1 = chkp_find_bounds (val1, &iter);
	tree bnd2 = chkp_find_bounds (val2, &iter);
	gimple *stmt;

	if (chkp_incomplete_bounds (bnd1) || chkp_incomplete_bounds (bnd2))
	  bounds = incomplete_bounds;
	else if (bnd1 == bnd2)
	  bounds = bnd1;
	else
	  {
	    rhs1 = unshare_expr (rhs1);

	    bounds = chkp_get_tmp_reg (assign);
	    stmt = gimple_build_assign (bounds, COND_EXPR, rhs1, bnd1, bnd2);
	    gsi_insert_after (&iter, stmt, GSI_SAME_STMT);

	    if (!chkp_valid_bounds (bnd1) && !chkp_valid_bounds (bnd2))
	      chkp_mark_invalid_bounds (bounds);
	  }
      }
      break;

    case MAX_EXPR:
    case MIN_EXPR:
      {
	tree rhs2 = gimple_assign_rhs2 (assign);
	tree bnd1 = chkp_find_bounds (rhs1, &iter);
	tree bnd2 = chkp_find_bounds (rhs2, &iter);

	if (chkp_incomplete_bounds (bnd1) || chkp_incomplete_bounds (bnd2))
	  bounds = incomplete_bounds;
	else if (bnd1 == bnd2)
	  bounds = bnd1;
	else
	  {
	    gimple *stmt;
	    tree cond = build2 (rhs_code == MAX_EXPR ? GT_EXPR : LT_EXPR,
				boolean_type_node, rhs1, rhs2);
	    bounds = chkp_get_tmp_reg (assign);
	    stmt = gimple_build_assign (bounds, COND_EXPR, cond, bnd1, bnd2);

	    gsi_insert_after (&iter, stmt, GSI_SAME_STMT);

	    if (!chkp_valid_bounds (bnd1) && !chkp_valid_bounds (bnd2))
	      chkp_mark_invalid_bounds (bounds);
	  }
      }
      break;

    default:
      bounds = chkp_get_zero_bounds ();
      warning (0, "pointer bounds were lost due to unexpected expression %s",
	       get_tree_code_name (rhs_code));
    }

  gcc_assert (bounds);

  /* We may reuse bounds of other pointer we copy/modify.  But it is not
     allowed for abnormal ssa names.  If we produced a pointer using
     abnormal ssa name, we better make a bounds copy to avoid coalescing
     issues.  */
  if (base
      && TREE_CODE (base) == SSA_NAME
      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (base))
    {
      gimple *stmt = gimple_build_assign (chkp_get_tmp_reg (NULL), bounds);
      gsi_insert_after (&iter, stmt, GSI_SAME_STMT);
      bounds = gimple_assign_lhs (stmt);
    }

  if (node)
    bounds = chkp_maybe_copy_and_register_bounds (node, bounds);

  return bounds;
}

/* Compute bounds for ssa name NODE defined by DEF_STMT pointed by ITER.

   There are just few statement codes allowed: NOP (for default ssa names),
   ASSIGN, CALL, PHI, ASM.

   Return computed bounds.  */
static tree
chkp_get_bounds_by_definition (tree node, gimple *def_stmt,
			       gphi_iterator *iter)
{
  tree var, bounds;
  enum gimple_code code = gimple_code (def_stmt);
  gphi *stmt;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Searching for bounds for node: ");
      print_generic_expr (dump_file, node);

      fprintf (dump_file, " using its definition: ");
      print_gimple_stmt (dump_file, def_stmt, 0, TDF_VOPS | TDF_MEMSYMS);
    }

  switch (code)
    {
    case GIMPLE_NOP:
      var = SSA_NAME_VAR (node);
      switch (TREE_CODE (var))
	{
	case PARM_DECL:
	  bounds = chkp_get_bound_for_parm (node);
	  break;

	case VAR_DECL:
	  /* For uninitialized pointers use none bounds.  */
	  bounds = chkp_get_none_bounds ();
	  bounds = chkp_maybe_copy_and_register_bounds (node, bounds);
	  break;

	case RESULT_DECL:
	  {
	    tree base_type;

	    gcc_assert (TREE_CODE (TREE_TYPE (node)) == REFERENCE_TYPE);

	    base_type = TREE_TYPE (TREE_TYPE (node));

	    gcc_assert (TYPE_SIZE (base_type)
			&& TREE_CODE (TYPE_SIZE (base_type)) == INTEGER_CST
			&& tree_to_uhwi (TYPE_SIZE (base_type)) != 0);

	    bounds = chkp_make_bounds (node, TYPE_SIZE_UNIT (base_type),
				       NULL, false);
	    bounds = chkp_maybe_copy_and_register_bounds (node, bounds);
	  }
	  break;

	default:
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Unexpected var with no definition\n");
	      print_generic_expr (dump_file, var);
	    }
	  internal_error ("chkp_get_bounds_by_definition: Unexpected var of type %s",
			  get_tree_code_name (TREE_CODE (var)));
	}
      break;

    case GIMPLE_ASSIGN:
      bounds = chkp_compute_bounds_for_assignment (node, def_stmt);
      break;

    case GIMPLE_CALL:
      bounds = chkp_build_returned_bound (as_a <gcall *> (def_stmt));
      break;

    case GIMPLE_PHI:
      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
	if (SSA_NAME_VAR (node))
	  var = chkp_get_bounds_var (SSA_NAME_VAR (node));
	else
	  var = make_temp_ssa_name (pointer_bounds_type_node,
				    NULL,
				    CHKP_BOUND_TMP_NAME);
      else
	var = chkp_get_tmp_var ();
      stmt = create_phi_node (var, gimple_bb (def_stmt));
      bounds = gimple_phi_result (stmt);
      *iter = gsi_for_phi (stmt);

      bounds = chkp_maybe_copy_and_register_bounds (node, bounds);

      /* Created bounds do not have all phi args computed and
	 therefore we do not know if there is a valid source
	 of bounds for that node.  Therefore we mark bounds
	 as incomplete and then recompute them when all phi
	 args are computed.  */
      chkp_register_incomplete_bounds (bounds, node);
      break;

    case GIMPLE_ASM:
      bounds = chkp_get_zero_bounds ();
      bounds = chkp_maybe_copy_and_register_bounds (node, bounds);
      break;

    default:
      internal_error ("chkp_get_bounds_by_definition: Unexpected GIMPLE code %s",
		      gimple_code_name[code]);
    }

  return bounds;
}

/* Return CALL_EXPR for bndmk with specified LOWER_BOUND and SIZE.  */
tree
chkp_build_make_bounds_call (tree lower_bound, tree size)
{
  tree call = build1 (ADDR_EXPR,
		      build_pointer_type (TREE_TYPE (chkp_bndmk_fndecl)),
		      chkp_bndmk_fndecl);
  return build_call_nary (TREE_TYPE (TREE_TYPE (chkp_bndmk_fndecl)),
			  call, 2, lower_bound, size);
}

/* Create static bounds var of specfified OBJ which is
   is either VAR_DECL or string constant.  */
static tree
chkp_make_static_bounds (tree obj)
{
  static int string_id = 1;
  static int var_id = 1;
  tree *slot;
  const char *var_name;
  char *bnd_var_name;
  tree bnd_var;

  /* First check if we already have required var.  */
  if (chkp_static_var_bounds)
    {
      /* For vars we use assembler name as a key in
	 chkp_static_var_bounds map.  It allows to
	 avoid duplicating bound vars for decls
	 sharing assembler name.  */
      if (VAR_P (obj))
	{
	  tree name = DECL_ASSEMBLER_NAME (obj);
	  slot = chkp_static_var_bounds->get (name);
	  if (slot)
	    return *slot;
	}
      else
	{
	  slot = chkp_static_var_bounds->get (obj);
	  if (slot)
	    return *slot;
	}
    }

  /* Build decl for bounds var.  */
  if (VAR_P (obj))
    {
      if (DECL_IGNORED_P (obj))
	{
	  bnd_var_name = (char *) xmalloc (strlen (CHKP_VAR_BOUNDS_PREFIX) + 10);
	  sprintf (bnd_var_name, "%s%d", CHKP_VAR_BOUNDS_PREFIX, var_id++);
	}
      else
	{
	  var_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (obj));

	  /* For hidden symbols we want to skip first '*' char.  */
	  if (*var_name == '*')
	    var_name++;

	  bnd_var_name = (char *) xmalloc (strlen (var_name)
					   + strlen (CHKP_BOUNDS_OF_SYMBOL_PREFIX) + 1);
	  strcpy (bnd_var_name, CHKP_BOUNDS_OF_SYMBOL_PREFIX);
	  strcat (bnd_var_name, var_name);
	}

      bnd_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
			    get_identifier (bnd_var_name),
			    pointer_bounds_type_node);

      /* Address of the obj will be used as lower bound.  */
      TREE_ADDRESSABLE (obj) = 1;
    }
  else
    {
      bnd_var_name = (char *) xmalloc (strlen (CHKP_STRING_BOUNDS_PREFIX) + 10);
      sprintf (bnd_var_name, "%s%d", CHKP_STRING_BOUNDS_PREFIX, string_id++);

      bnd_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
			    get_identifier (bnd_var_name),
			    pointer_bounds_type_node);
    }

  free (bnd_var_name);

  TREE_PUBLIC (bnd_var) = 0;
  TREE_USED (bnd_var) = 1;
  TREE_READONLY (bnd_var) = 0;
  TREE_STATIC (bnd_var) = 1;
  TREE_ADDRESSABLE (bnd_var) = 0;
  DECL_ARTIFICIAL (bnd_var) = 1;
  DECL_COMMON (bnd_var) = 1;
  DECL_COMDAT (bnd_var) = 1;
  DECL_READ_P (bnd_var) = 1;
  DECL_INITIAL (bnd_var) = chkp_build_addr_expr (obj);
  /* Force output similar to constant bounds.
     See chkp_make_static_const_bounds. */
  varpool_node::get_create (bnd_var)->force_output = 1;
  /* Mark symbol as requiring bounds initialization.  */
  varpool_node::get_create (bnd_var)->need_bounds_init = 1;
  varpool_node::finalize_decl (bnd_var);

  /* Add created var to the map to use it for other references
     to obj.  */
  if (!chkp_static_var_bounds)
    chkp_static_var_bounds = new hash_map<tree, tree>;

  if (VAR_P (obj))
    {
      tree name = DECL_ASSEMBLER_NAME (obj);
      chkp_static_var_bounds->put (name, bnd_var);
    }
  else
    chkp_static_var_bounds->put (obj, bnd_var);

  return bnd_var;
}

/* When var has incomplete type we cannot get size to
   compute its bounds.  In such cases we use checker
   builtin call which determines object size at runtime.  */
static tree
chkp_generate_extern_var_bounds (tree var)
{
  tree bounds, size_reloc, lb, size, max_size, cond;
  gimple_stmt_iterator gsi;
  gimple_seq seq = NULL;
  gimple *stmt;

  /* If instrumentation is not enabled for vars having
     incomplete type then just return zero bounds to avoid
     checks for this var.  */
  if (!flag_chkp_incomplete_type)
    return chkp_get_zero_bounds ();

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Generating bounds for extern symbol '");
      print_generic_expr (dump_file, var);
      fprintf (dump_file, "'\n");
    }

  stmt = gimple_build_call (chkp_sizeof_fndecl, 1, var);

  size_reloc = create_tmp_reg (chkp_uintptr_type, CHKP_SIZE_TMP_NAME);
  gimple_call_set_lhs (stmt, size_reloc);

  gimple_seq_add_stmt (&seq, stmt);

  lb = chkp_build_addr_expr (var);
  size = make_ssa_name (chkp_get_size_tmp_var ());

  if (flag_chkp_zero_dynamic_size_as_infinite)
    {
      /* We should check that size relocation was resolved.
	 If it was not then use maximum possible size for the var.  */
      max_size = build2 (MINUS_EXPR, chkp_uintptr_type, integer_zero_node,
			 fold_convert (chkp_uintptr_type, lb));
      max_size = chkp_force_gimple_call_op (max_size, &seq);

      cond = build2 (NE_EXPR, boolean_type_node,
		     size_reloc, integer_zero_node);
      stmt = gimple_build_assign (size, COND_EXPR, cond, size_reloc, max_size);
      gimple_seq_add_stmt (&seq, stmt);
    }
  else
    {
      stmt = gimple_build_assign (size, size_reloc);
      gimple_seq_add_stmt (&seq, stmt);
    }

  gsi = gsi_start_bb (chkp_get_entry_block ());
  gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);

  bounds = chkp_make_bounds (lb, size, &gsi, true);

  return bounds;
}

/* Return 1 if TYPE has fields with zero size or fields
   marked with chkp_variable_size attribute.  */
bool
chkp_variable_size_type (tree type)
{
  bool res = false;
  tree field;

  if (RECORD_OR_UNION_TYPE_P (type))
    for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
      {
	if (TREE_CODE (field) == FIELD_DECL)
	  res = res
	    || lookup_attribute ("bnd_variable_size", DECL_ATTRIBUTES (field))
	    || chkp_variable_size_type (TREE_TYPE (field));
      }
  else
    res = !TYPE_SIZE (type)
      || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
      || tree_to_uhwi (TYPE_SIZE (type)) == 0;

  return res;
}

/* Compute and return bounds for address of DECL which is
   one of VAR_DECL, PARM_DECL, RESULT_DECL.  */
static tree
chkp_get_bounds_for_decl_addr (tree decl)
{
  tree bounds;

  gcc_assert (VAR_P (decl)
	      || TREE_CODE (decl) == PARM_DECL
	      || TREE_CODE (decl) == RESULT_DECL);

  bounds = chkp_get_registered_addr_bounds (decl);

  if (bounds)
    return bounds;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Building bounds for address of decl ");
      print_generic_expr (dump_file, decl);
      fprintf (dump_file, "\n");
    }

  /* Use zero bounds if size is unknown and checks for
     unknown sizes are restricted.  */
  if ((!DECL_SIZE (decl)
       || (chkp_variable_size_type (TREE_TYPE (decl))
	   && (TREE_STATIC (decl)
	       || DECL_EXTERNAL (decl)
	       || TREE_PUBLIC (decl))))
      && !flag_chkp_incomplete_type)
      return chkp_get_zero_bounds ();

  if (VOID_TYPE_P (TREE_TYPE (decl)))
    return chkp_get_zero_bounds ();

  if (flag_chkp_use_static_bounds
      && VAR_P (decl)
      && (TREE_STATIC (decl)
	      || DECL_EXTERNAL (decl)
	      || TREE_PUBLIC (decl))
      && !DECL_THREAD_LOCAL_P (decl))
    {
      tree bnd_var = chkp_make_static_bounds (decl);
      gimple_stmt_iterator gsi = gsi_start_bb (chkp_get_entry_block ());
      gimple *stmt;

      bounds = chkp_get_tmp_reg (NULL);
      stmt = gimple_build_assign (bounds, bnd_var);
      gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
    }
  else if (!DECL_SIZE (decl)
      || (chkp_variable_size_type (TREE_TYPE (decl))
	  && (TREE_STATIC (decl)
	      || DECL_EXTERNAL (decl)
	      || TREE_PUBLIC (decl))))
    {
      gcc_assert (VAR_P (decl));
      bounds = chkp_generate_extern_var_bounds (decl);
    }
  else
    {
      tree lb = chkp_build_addr_expr (decl);
      bounds = chkp_make_bounds (lb, DECL_SIZE_UNIT (decl), NULL, false);
    }

  return bounds;
}

/* Compute and return bounds for constant string.  */
static tree
chkp_get_bounds_for_string_cst (tree cst)
{
  tree bounds;
  tree lb;
  tree size;

  gcc_assert (TREE_CODE (cst) == STRING_CST);

  bounds = chkp_get_registered_bounds (cst);

  if (bounds)
    return bounds;

  if ((flag_chkp_use_static_bounds && flag_chkp_use_static_const_bounds)
      || flag_chkp_use_static_const_bounds > 0)
    {
      tree bnd_var = chkp_make_static_bounds (cst);
      gimple_stmt_iterator gsi = gsi_start_bb (chkp_get_entry_block ());
      gimple *stmt;

      bounds = chkp_get_tmp_reg (NULL);
      stmt = gimple_build_assign (bounds, bnd_var);
      gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
    }
  else
    {
      lb = chkp_build_addr_expr (cst);
      size = build_int_cst (chkp_uintptr_type, TREE_STRING_LENGTH (cst));
      bounds = chkp_make_bounds (lb, size, NULL, false);
    }

  bounds = chkp_maybe_copy_and_register_bounds (cst, bounds);

  return bounds;
}

/* Generate code to instersect bounds BOUNDS1 and BOUNDS2 and
   return the result.  if ITER is not NULL then Code is inserted
   before position pointed by ITER.  Otherwise code is added to
   entry block.  */
static tree
chkp_intersect_bounds (tree bounds1, tree bounds2, gimple_stmt_iterator *iter)
{
  if (!bounds1 || bounds1 == chkp_get_zero_bounds ())
    return bounds2 ? bounds2 : bounds1;
  else if (!bounds2 || bounds2 == chkp_get_zero_bounds ())
    return bounds1;
  else
    {
      gimple_seq seq;
      gimple *stmt;
      tree bounds;

      seq = NULL;

      stmt = gimple_build_call (chkp_intersect_fndecl, 2, bounds1, bounds2);
      chkp_mark_stmt (stmt);

      bounds = chkp_get_tmp_reg (stmt);
      gimple_call_set_lhs (stmt, bounds);

      gimple_seq_add_stmt (&seq, stmt);

      /* We are probably doing narrowing for constant expression.
	 In such case iter may be undefined.  */
      if (!iter)
	{
	  gimple_stmt_iterator gsi = gsi_last_bb (chkp_get_entry_block ());
	  iter = &gsi;
	  gsi_insert_seq_after (iter, seq, GSI_SAME_STMT);
	}
      else
	gsi_insert_seq_before (iter, seq, GSI_SAME_STMT);

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Bounds intersection: ");
	  print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS|TDF_MEMSYMS);
	  fprintf (dump_file, "  inserted before statement: ");
	  print_gimple_stmt (dump_file, gsi_stmt (*iter), 0,
			     TDF_VOPS|TDF_MEMSYMS);
	}

      return bounds;
    }
}

/* Return 1 if we are allowed to narrow bounds for addressed FIELD
   and 0 othersize.  REF is reference to the field.  */

static bool
chkp_may_narrow_to_field (tree ref, tree field)
{
  return DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST
    && tree_to_uhwi (DECL_SIZE (field)) != 0
    && !(flag_chkp_flexible_struct_trailing_arrays
	 && array_at_struct_end_p (ref))
    && (!DECL_FIELD_OFFSET (field)
	|| TREE_CODE (DECL_FIELD_OFFSET (field)) == INTEGER_CST)
    && (!DECL_FIELD_BIT_OFFSET (field)
	|| TREE_CODE (DECL_FIELD_BIT_OFFSET (field)) == INTEGER_CST)
    && !lookup_attribute ("bnd_variable_size", DECL_ATTRIBUTES (field))
    && !chkp_variable_size_type (TREE_TYPE (field));
}

/* Return 1 if bounds for FIELD should be narrowed to
   field's own size.  REF is reference to the field.  */

static bool
chkp_narrow_bounds_for_field (tree ref, tree field)
{
  HOST_WIDE_INT offs;
  HOST_WIDE_INT bit_offs;

  if (!chkp_may_narrow_to_field (ref, field))
    return false;

  /* Access to compiler generated fields should not cause
     bounds narrowing.  */
  if (DECL_ARTIFICIAL (field))
    return false;

  offs = tree_to_uhwi (DECL_FIELD_OFFSET (field));
  bit_offs = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field));

  return (flag_chkp_narrow_bounds
	  && (flag_chkp_first_field_has_own_bounds
	      || offs
	      || bit_offs));
}

/* Perform narrowing for BOUNDS of an INNER reference.  Shift boundary
   by OFFSET bytes and limit to SIZE bytes.  Newly created statements are
   added to ITER.  */

static tree
chkp_narrow_size_and_offset (tree bounds, tree inner, tree offset,
			     tree size, gimple_stmt_iterator *iter)
{
  tree addr = chkp_build_addr_expr (unshare_expr (inner));
  tree t = TREE_TYPE (addr);

  gimple *stmt = gimple_build_assign (NULL_TREE, addr);
  addr = make_temp_ssa_name (t, stmt, CHKP_BOUND_TMP_NAME);
  gimple_assign_set_lhs (stmt, addr);
  gsi_insert_seq_before (iter, stmt, GSI_SAME_STMT);

  stmt = gimple_build_assign (NULL_TREE, POINTER_PLUS_EXPR, addr, offset);
  tree shifted = make_temp_ssa_name (t, stmt, CHKP_BOUND_TMP_NAME);
  gimple_assign_set_lhs (stmt, shifted);
  gsi_insert_seq_before (iter, stmt, GSI_SAME_STMT);

  tree bounds2 = chkp_make_bounds (shifted, size, iter, false);

  return chkp_intersect_bounds (bounds, bounds2, iter);
}

/* Perform narrowing for BOUNDS using bounds computed for field
   access COMPONENT.  ITER meaning is the same as for
   chkp_intersect_bounds.  */

static tree
chkp_narrow_bounds_to_field (tree bounds, tree component,
			    gimple_stmt_iterator *iter)
{
  tree field = TREE_OPERAND (component, 1);
  tree size = DECL_SIZE_UNIT (field);
  tree field_ptr = chkp_build_addr_expr (component);
  tree field_bounds;

  field_bounds = chkp_make_bounds (field_ptr, size, iter, false);

  return chkp_intersect_bounds (field_bounds, bounds, iter);
}

/* Parse field or array access NODE.

   PTR ouput parameter holds a pointer to the outermost
   object.

   BITFIELD output parameter is set to 1 if bitfield is
   accessed and to 0 otherwise.  If it is 1 then ELT holds
   outer component for accessed bit field.

   SAFE outer parameter is set to 1 if access is safe and
   checks are not required.

   BOUNDS outer parameter holds bounds to be used to check
   access (may be NULL).

   If INNERMOST_BOUNDS is 1 then try to narrow bounds to the
   innermost accessed component.  */
static void
chkp_parse_array_and_component_ref (tree node, tree *ptr,
				    tree *elt, bool *safe,
				    bool *bitfield,
				    tree *bounds,
				    gimple_stmt_iterator *iter,
				    bool innermost_bounds)
{
  tree comp_to_narrow = NULL_TREE;
  tree last_comp = NULL_TREE;
  bool array_ref_found = false;
  tree *nodes;
  tree var;
  int len;
  int i;

  /* Compute tree height for expression.  */
  var = node;
  len = 1;
  while (TREE_CODE (var) == COMPONENT_REF
	 || TREE_CODE (var) == ARRAY_REF
	 || TREE_CODE (var) == VIEW_CONVERT_EXPR
	 || TREE_CODE (var) == BIT_FIELD_REF)
    {
      var = TREE_OPERAND (var, 0);
      len++;
    }

  gcc_assert (len > 1);

  /* It is more convenient for us to scan left-to-right,
     so walk tree again and put all node to nodes vector
     in reversed order.  */
  nodes = XALLOCAVEC (tree, len);
  nodes[len - 1] = node;
  for (i = len - 2; i >= 0; i--)
    nodes[i] = TREE_OPERAND (nodes[i + 1], 0);

  if (bounds)
    *bounds = NULL;
  *safe = true;
  *bitfield = ((TREE_CODE (node) == COMPONENT_REF
	       && DECL_BIT_FIELD_TYPE (TREE_OPERAND (node, 1)))
	       || TREE_CODE (node) == BIT_FIELD_REF);
  /* To get bitfield address we will need outer element.  */
  if (*bitfield)
    *elt = nodes[len - 2];
  else
    *elt = NULL_TREE;

  /* If we have indirection in expression then compute
     outermost structure bounds.  Computed bounds may be
     narrowed later.  */
  if (TREE_CODE (nodes[0]) == MEM_REF || INDIRECT_REF_P (nodes[0]))
    {
      *safe = false;
      *ptr = TREE_OPERAND (nodes[0], 0);
      if (bounds)
	*bounds = chkp_find_bounds (*ptr, iter);
    }
  else
    {
      gcc_assert (VAR_P (var)
		  || TREE_CODE (var) == PARM_DECL
		  || TREE_CODE (var) == RESULT_DECL
		  || TREE_CODE (var) == STRING_CST
		  || TREE_CODE (var) == SSA_NAME);

      *ptr = chkp_build_addr_expr (var);

      /* For hard register cases chkp_build_addr_expr returns INTEGER_CST
	 and later on chkp_find_bounds will fail to find proper bounds.
	 In order to avoid that, we find/create bounds right aways using
	 the var itself.  */
      if (VAR_P (var) && DECL_HARD_REGISTER (var))
	*bounds = chkp_make_addressed_object_bounds (var, iter);
    }

  /* In this loop we are trying to find a field access
     requiring narrowing.  There are two simple rules
     for search:
     1.  Leftmost array_ref is chosen if any.
     2.  Rightmost suitable component_ref is chosen if innermost
     bounds are required and no array_ref exists.  */
  for (i = 1; i < len; i++)
    {
      var = nodes[i];

      if (TREE_CODE (var) == ARRAY_REF)
	{
	  *safe = false;
	  array_ref_found = true;
	  if (flag_chkp_narrow_bounds
	      && !flag_chkp_narrow_to_innermost_arrray
	      && (!last_comp
		  || chkp_may_narrow_to_field (var,
					       TREE_OPERAND (last_comp, 1))))
	    {
	      comp_to_narrow = last_comp;
	      break;
	    }
	}
      else if (TREE_CODE (var) == COMPONENT_REF)
	{
	  tree field = TREE_OPERAND (var, 1);

	  if (innermost_bounds
	      && !array_ref_found
	      && chkp_narrow_bounds_for_field (var, field))
	    comp_to_narrow = var;
	  last_comp = var;

	  if (flag_chkp_narrow_bounds
	      && flag_chkp_narrow_to_innermost_arrray
	      && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
	    {
	      if (bounds)
		*bounds = chkp_narrow_bounds_to_field (*bounds, var, iter);
	      comp_to_narrow = NULL;
	    }
	}
      else if (TREE_CODE (var) == BIT_FIELD_REF)
	{
	  if (flag_chkp_narrow_bounds && bounds)
	    {
	      tree offset, size;
	      chkp_parse_bit_field_ref (var, UNKNOWN_LOCATION, &offset, &size);
	      *bounds
		= chkp_narrow_size_and_offset (*bounds, TREE_OPERAND (var, 0),
					       offset, size, iter);
	    }
	}
      else if (TREE_CODE (var) == VIEW_CONVERT_EXPR)
	/* Nothing to do for it.  */
	;
      else
	gcc_unreachable ();
    }

  if (comp_to_narrow && DECL_SIZE (TREE_OPERAND (comp_to_narrow, 1)) && bounds)
    *bounds = chkp_narrow_bounds_to_field (*bounds, comp_to_narrow, iter);

  if (innermost_bounds && bounds && !*bounds)
    *bounds = chkp_find_bounds (*ptr, iter);
}

/* Parse BIT_FIELD_REF to a NODE for a given location LOC.  Return OFFSET
   and SIZE in bytes.  */

static
void chkp_parse_bit_field_ref (tree node, location_t loc, tree *offset,
			       tree *size)
{
  tree bpu = fold_convert (size_type_node, bitsize_int (BITS_PER_UNIT));
  tree offs = fold_convert (size_type_node, TREE_OPERAND (node, 2));
  tree rem = size_binop_loc (loc, TRUNC_MOD_EXPR, offs, bpu);
  offs = size_binop_loc (loc, TRUNC_DIV_EXPR, offs, bpu);

  tree s = fold_convert (size_type_node, TREE_OPERAND (node, 1));
  s = size_binop_loc (loc, PLUS_EXPR, s, rem);
  s = size_binop_loc (loc, CEIL_DIV_EXPR, s, bpu);
  s = fold_convert (size_type_node, s);

  *offset = offs;
  *size = s;
}

/* Compute and return bounds for address of OBJ.  */
static tree
chkp_make_addressed_object_bounds (tree obj, gimple_stmt_iterator *iter)
{
  tree bounds = chkp_get_registered_addr_bounds (obj);

  if (bounds)
    return bounds;

  switch (TREE_CODE (obj))
    {
    case VAR_DECL:
    case PARM_DECL:
    case RESULT_DECL:
      bounds = chkp_get_bounds_for_decl_addr (obj);
      break;

    case STRING_CST:
      bounds = chkp_get_bounds_for_string_cst (obj);
      break;

    case ARRAY_REF:
    case COMPONENT_REF:
    case BIT_FIELD_REF:
      {
	tree elt;
	tree ptr;
	bool safe;
	bool bitfield;

	chkp_parse_array_and_component_ref (obj, &ptr, &elt, &safe,
					    &bitfield, &bounds, iter, true);

	gcc_assert (bounds);
      }
      break;

    case FUNCTION_DECL:
    case LABEL_DECL:
      bounds = chkp_get_zero_bounds ();
      break;

    case MEM_REF:
      bounds = chkp_find_bounds (TREE_OPERAND (obj, 0), iter);
      break;

    case REALPART_EXPR:
    case IMAGPART_EXPR:
      bounds = chkp_make_addressed_object_bounds (TREE_OPERAND (obj, 0), iter);
      break;

    default:
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "chkp_make_addressed_object_bounds: "
		   "unexpected object of type %s\n",
		   get_tree_code_name (TREE_CODE (obj)));
	  print_node (dump_file, "", obj, 0);
	}
      internal_error ("chkp_make_addressed_object_bounds: "
		      "Unexpected tree code %s",
		      get_tree_code_name (TREE_CODE (obj)));
    }

  chkp_register_addr_bounds (obj, bounds);

  return bounds;
}

/* Compute bounds for pointer PTR loaded from PTR_SRC.  Generate statements
   to compute bounds if required.  Computed bounds should be available at
   position pointed by ITER.

   If PTR_SRC is NULL_TREE then pointer definition is identified.

   If PTR_SRC is not NULL_TREE then ITER points to statements which loads
   PTR.  If PTR is a any memory reference then ITER points to a statement
   after which bndldx will be inserterd.  In both cases ITER will be updated
   to point to the inserted bndldx statement.  */

static tree
chkp_find_bounds_1 (tree ptr, tree ptr_src, gimple_stmt_iterator *iter)
{
  tree addr = NULL_TREE;
  tree bounds = NULL_TREE;

  if (!ptr_src)
    ptr_src = ptr;

  bounds = chkp_get_registered_bounds (ptr_src);

  if (bounds)
    return bounds;

  switch (TREE_CODE (ptr_src))
    {
    case MEM_REF:
    case VAR_DECL:
      if (BOUNDED_P (ptr_src))
	if (VAR_P (ptr) && DECL_REGISTER (ptr))
	  bounds = chkp_get_zero_bounds ();
	else
	  {
	    addr = chkp_build_addr_expr (ptr_src);
	    bounds = chkp_build_bndldx (addr, ptr, iter);
	  }
      else
	bounds = chkp_get_nonpointer_load_bounds ();
      break;

    case ARRAY_REF:
    case COMPONENT_REF:
      addr = get_base_address (ptr_src);
      if (VAR_P (addr) && DECL_HARD_REGISTER (addr))
	{
	  bounds = chkp_get_zero_bounds ();
	  break;
	}
      if (DECL_P (addr)
	  || TREE_CODE (addr) == MEM_REF
	  || TREE_CODE (addr) == TARGET_MEM_REF)
	{
	  if (BOUNDED_P (ptr_src))
	    if (VAR_P (ptr) && DECL_REGISTER (ptr))
	      bounds = chkp_get_zero_bounds ();
	    else
	      {
		addr = chkp_build_addr_expr (ptr_src);
		bounds = chkp_build_bndldx (addr, ptr, iter);
	      }
	  else
	    bounds = chkp_get_nonpointer_load_bounds ();
	}
      else
	{
	  gcc_assert (TREE_CODE (addr) == SSA_NAME);
	  bounds = chkp_find_bounds (addr, iter);
	}
      break;

    case PARM_DECL:
      /* Handled above but failed.  */
      bounds = chkp_get_invalid_op_bounds ();
      break;

    case TARGET_MEM_REF:
      addr = chkp_build_addr_expr (ptr_src);
      bounds = chkp_build_bndldx (addr, ptr, iter);
      break;

    case SSA_NAME:
      bounds = chkp_get_registered_bounds (ptr_src);
      if (!bounds)
	{
	  gimple *def_stmt = SSA_NAME_DEF_STMT (ptr_src);
	  gphi_iterator phi_iter;

	  bounds = chkp_get_bounds_by_definition (ptr_src, def_stmt, &phi_iter);

	  gcc_assert (bounds);

	  if (gphi *def_phi = dyn_cast <gphi *> (def_stmt))
	    {
	      unsigned i;

	      for (i = 0; i < gimple_phi_num_args (def_phi); i++)
		{
		  tree arg = gimple_phi_arg_def (def_phi, i);
		  tree arg_bnd;
		  gphi *phi_bnd;

		  arg_bnd = chkp_find_bounds (arg, NULL);

		  /* chkp_get_bounds_by_definition created new phi
		     statement and phi_iter points to it.

		     Previous call to chkp_find_bounds could create
		     new basic block and therefore change phi statement
		     phi_iter points to.  */
		  phi_bnd = phi_iter.phi ();

		  add_phi_arg (phi_bnd, arg_bnd,
			       gimple_phi_arg_edge (def_phi, i),
			       UNKNOWN_LOCATION);
		}

	      /* If all bound phi nodes have their arg computed
		 then we may finish its computation.  See
		 chkp_finish_incomplete_bounds for more details.  */
	      if (chkp_may_finish_incomplete_bounds ())
		chkp_finish_incomplete_bounds ();
	    }

	  gcc_assert (bounds == chkp_get_registered_bounds (ptr_src)
		      || chkp_incomplete_bounds (bounds));
	}
      break;

    case ADDR_EXPR:
    case WITH_SIZE_EXPR:
      bounds = chkp_make_addressed_object_bounds (TREE_OPERAND (ptr_src, 0), iter);
      break;

    case INTEGER_CST:
    case COMPLEX_CST:
    case VECTOR_CST:
      if (integer_zerop (ptr_src))
	bounds = chkp_get_none_bounds ();
      else
	bounds = chkp_get_invalid_op_bounds ();
      break;

    default:
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "chkp_find_bounds: unexpected ptr of type %s\n",
		   get_tree_code_name (TREE_CODE (ptr_src)));
	  print_node (dump_file, "", ptr_src, 0);
	}
      internal_error ("chkp_find_bounds: Unexpected tree code %s",
		      get_tree_code_name (TREE_CODE (ptr_src)));
    }

  if (!bounds)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (stderr, "chkp_find_bounds: cannot find bounds for pointer\n");
	  print_node (dump_file, "", ptr_src, 0);
	}
      internal_error ("chkp_find_bounds: Cannot find bounds for pointer");
    }

  return bounds;
}

/* Normal case for bounds search without forced narrowing.  */
static tree
chkp_find_bounds (tree ptr, gimple_stmt_iterator *iter)
{
  return chkp_find_bounds_1 (ptr, NULL_TREE, iter);
}

/* Search bounds for pointer PTR loaded from PTR_SRC
   by statement *ITER points to.  */
static tree
chkp_find_bounds_loaded (tree ptr, tree ptr_src, gimple_stmt_iterator *iter)
{
  return chkp_find_bounds_1 (ptr, ptr_src, iter);
}

/* Helper function which checks type of RHS and finds all pointers in
   it.  For each found pointer we build it's accesses in LHS and RHS
   objects and then call HANDLER for them.  Function is used to copy
   or initilize bounds for copied object.  */
static void
chkp_walk_pointer_assignments (tree lhs, tree rhs, void *arg,
			       assign_handler handler)
{
  tree type = TREE_TYPE (lhs);

  /* We have nothing to do with clobbers.  */
  if (TREE_CLOBBER_P (rhs))
    return;

  if (BOUNDED_TYPE_P (type))
    handler (lhs, rhs, arg);
  else if (RECORD_OR_UNION_TYPE_P (type))
    {
      tree field;

      if (TREE_CODE (rhs) == CONSTRUCTOR)
	{
	  unsigned HOST_WIDE_INT cnt;
	  tree val;

	  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (rhs), cnt, field, val)
	    {
	      if (field && chkp_type_has_pointer (TREE_TYPE (field)))
		{
		  tree lhs_field = chkp_build_component_ref (lhs, field);
		  chkp_walk_pointer_assignments (lhs_field, val, arg, handler);
		}
	    }
	}
      else
	for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
	  if (TREE_CODE (field) == FIELD_DECL
	      && chkp_type_has_pointer (TREE_TYPE (field)))
	    {
	      tree rhs_field = chkp_build_component_ref (rhs, field);
	      tree lhs_field = chkp_build_component_ref (lhs, field);
	      chkp_walk_pointer_assignments (lhs_field, rhs_field, arg, handler);
	    }
    }
  else if (TREE_CODE (type) == ARRAY_TYPE)
    {
      unsigned HOST_WIDE_INT cur = 0;
      tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
      tree etype = TREE_TYPE (type);
      tree esize = TYPE_SIZE (etype);

      if (TREE_CODE (rhs) == CONSTRUCTOR)
	{
	  unsigned HOST_WIDE_INT cnt;
	  tree purp, val, lhs_elem;

	  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (rhs), cnt, purp, val)
	    {
	      if (purp && TREE_CODE (purp) == RANGE_EXPR)
		{
		  tree lo_index = TREE_OPERAND (purp, 0);
		  tree hi_index = TREE_OPERAND (purp, 1);

		  for (cur = (unsigned)tree_to_uhwi (lo_index);
		       cur <= (unsigned)tree_to_uhwi (hi_index);
		       cur++)
		    {
		      lhs_elem = chkp_build_array_ref (lhs, etype, esize, cur);
		      chkp_walk_pointer_assignments (lhs_elem, val, arg, handler);
		    }
		}
	      else
		{
		  if (purp)
		    {
		      gcc_assert (TREE_CODE (purp) == INTEGER_CST);
		      cur = tree_to_uhwi (purp);
		    }

		  lhs_elem = chkp_build_array_ref (lhs, etype, esize, cur++);

		  chkp_walk_pointer_assignments (lhs_elem, val, arg, handler);
		}
	    }
	}
      /* Copy array only when size is known.  */
      else if (maxval && !integer_minus_onep (maxval))
	for (cur = 0; cur <= TREE_INT_CST_LOW (maxval); cur++)
	  {
	    tree lhs_elem = chkp_build_array_ref (lhs, etype, esize, cur);
	    tree rhs_elem = chkp_build_array_ref (rhs, etype, esize, cur);
	    chkp_walk_pointer_assignments (lhs_elem, rhs_elem, arg, handler);
	  }
    }
  else
    internal_error("chkp_walk_pointer_assignments: unexpected RHS type: %s",
		   get_tree_code_name (TREE_CODE (type)));
}

/* Add code to copy bounds for assignment of RHS to LHS.
   ARG is an iterator pointing ne code position.  */
static void
chkp_copy_bounds_for_elem (tree lhs, tree rhs, void *arg)
{
  gimple_stmt_iterator *iter = (gimple_stmt_iterator *)arg;
  tree bounds = chkp_find_bounds (rhs, iter);
  tree addr = chkp_build_addr_expr(lhs);

  chkp_build_bndstx (addr, rhs, bounds, iter);
}

/* Emit static bound initilizers and size vars.  */
void
chkp_finish_file (void)
{
  struct varpool_node *node;
  struct chkp_ctor_stmt_list stmts;

  if (seen_error ())
    return;

  /* Iterate through varpool and generate bounds initialization
     constructors for all statically initialized pointers.  */
  stmts.avail = MAX_STMTS_IN_STATIC_CHKP_CTOR;
  stmts.stmts = NULL;
  FOR_EACH_VARIABLE (node)
    /* Check that var is actually emitted and we need and may initialize
       its bounds.  */
    if (node->need_bounds_init
	&& !POINTER_BOUNDS_P (node->decl)
	&& DECL_RTL (node->decl)
	&& MEM_P (DECL_RTL (node->decl))
	&& TREE_ASM_WRITTEN (node->decl))
      {
	chkp_walk_pointer_assignments (node->decl,
				       DECL_INITIAL (node->decl),
				       &stmts,
				       chkp_add_modification_to_stmt_list);

	if (stmts.avail <= 0)
	  {
	    cgraph_build_static_cdtor ('P', stmts.stmts,
				       MAX_RESERVED_INIT_PRIORITY + 3);
	    stmts.avail = MAX_STMTS_IN_STATIC_CHKP_CTOR;
	    stmts.stmts = NULL;
	  }
      }

  if (stmts.stmts)
    cgraph_build_static_cdtor ('P', stmts.stmts,
			       MAX_RESERVED_INIT_PRIORITY + 3);

  /* Iterate through varpool and generate bounds initialization
     constructors for all static bounds vars.  */
  stmts.avail = MAX_STMTS_IN_STATIC_CHKP_CTOR;
  stmts.stmts = NULL;
  FOR_EACH_VARIABLE (node)
    if (node->need_bounds_init
	&& POINTER_BOUNDS_P (node->decl)
	&& TREE_ASM_WRITTEN (node->decl))
      {
	tree bnd = node->decl;
	tree var;

	gcc_assert (DECL_INITIAL (bnd)
		    && TREE_CODE (DECL_INITIAL (bnd)) == ADDR_EXPR);

	var = TREE_OPERAND (DECL_INITIAL (bnd), 0);
	chkp_output_static_bounds (bnd, var, &stmts);
      }

  if (stmts.stmts)
    cgraph_build_static_cdtor ('B', stmts.stmts,
			       MAX_RESERVED_INIT_PRIORITY + 2);

  delete chkp_static_var_bounds;
  delete chkp_bounds_map;
}

/* An instrumentation function which is called for each statement
   having memory access we want to instrument.  It inserts check
   code and bounds copy code.

   ITER points to statement to instrument.

   NODE holds memory access in statement to check.

   LOC holds the location information for statement.

   DIRFLAGS determines whether access is read or write.

   ACCESS_OFFS should be added to address used in NODE
   before check.

   ACCESS_SIZE holds size of checked access.

   SAFE indicates if NODE access is safe and should not be
   checked.  */
static void
chkp_process_stmt (gimple_stmt_iterator *iter, tree node,
		   location_t loc, tree dirflag,
		   tree access_offs, tree access_size,
		   bool safe)
{
  tree node_type = TREE_TYPE (node);
  tree size = access_size ? access_size : TYPE_SIZE_UNIT (node_type);
  tree addr_first = NULL_TREE; /* address of the first accessed byte */
  tree addr_last = NULL_TREE; /* address of the last accessed byte */
  tree ptr = NULL_TREE; /* a pointer used for dereference */
  tree bounds = NULL_TREE;
  bool reg_store = false;

  /* We do not need instrumentation for clobbers.  */
  if (dirflag == integer_one_node
      && gimple_code (gsi_stmt (*iter)) == GIMPLE_ASSIGN
      && TREE_CLOBBER_P (gimple_assign_rhs1 (gsi_stmt (*iter))))
    return;

  switch (TREE_CODE (node))
    {
    case ARRAY_REF:
    case COMPONENT_REF:
      {
	bool bitfield;
	tree elt;

	if (safe)
	  {
	    /* We are not going to generate any checks, so do not
	       generate bounds as well.  */
	    addr_first = chkp_build_addr_expr (node);
	    break;
	  }

	chkp_parse_array_and_component_ref (node, &ptr, &elt, &safe,
					    &bitfield, &bounds, iter, false);

	/* Break if there is no dereference and operation is safe.  */

	if (bitfield)
          {
            tree field = TREE_OPERAND (node, 1);

            if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST)
              size = DECL_SIZE_UNIT (field);

	    if (elt)
	      elt = chkp_build_addr_expr (elt);
            addr_first = fold_convert_loc (loc, ptr_type_node, elt ? elt : ptr);
            addr_first = fold_build_pointer_plus_loc (loc,
						      addr_first,
						      byte_position (field));
          }
        else
          addr_first = chkp_build_addr_expr (node);
      }
      break;

    case INDIRECT_REF:
      ptr = TREE_OPERAND (node, 0);
      addr_first = ptr;
      break;

    case MEM_REF:
      ptr = TREE_OPERAND (node, 0);
      addr_first = chkp_build_addr_expr (node);
      break;

    case TARGET_MEM_REF:
      ptr = TMR_BASE (node);
      addr_first = chkp_build_addr_expr (node);
      break;

    case ARRAY_RANGE_REF:
      printf("ARRAY_RANGE_REF\n");
      debug_gimple_stmt(gsi_stmt(*iter));
      debug_tree(node);
      gcc_unreachable ();
      break;

    case BIT_FIELD_REF:
      {
	tree offset, size;

	gcc_assert (!access_offs);
	gcc_assert (!access_size);

	chkp_parse_bit_field_ref (node, loc, &offset, &size);

	chkp_process_stmt (iter, TREE_OPERAND (node, 0), loc,
			   dirflag, offset, size, safe);
	return;
      }
      break;

    case VAR_DECL:
    case RESULT_DECL:
    case PARM_DECL:
      if (dirflag != integer_one_node
	  || DECL_REGISTER (node))
	return;

      safe = true;
      addr_first = chkp_build_addr_expr (node);
      break;

    default:
      return;
    }

  /* If addr_last was not computed then use (addr_first + size - 1)
     expression to compute it.  */
  if (!addr_last)
    {
      addr_last = fold_build_pointer_plus_loc (loc, addr_first, size);
      addr_last = fold_build_pointer_plus_hwi_loc (loc, addr_last, -1);
    }

  /* Shift both first_addr and last_addr by access_offs if specified.  */
  if (access_offs)
    {
      addr_first = fold_build_pointer_plus_loc (loc, addr_first, access_offs);
      addr_last = fold_build_pointer_plus_loc (loc, addr_last, access_offs);
    }

  if (dirflag == integer_one_node)
    {
      tree base = get_base_address (node);
      if (VAR_P (base) && DECL_HARD_REGISTER (base))
	reg_store = true;
    }

  /* Generate bndcl/bndcu checks if memory access is not safe.  */
  if (!safe)
    {
      gimple_stmt_iterator stmt_iter = *iter;

      if (!bounds)
	bounds = chkp_find_bounds (ptr, iter);

      chkp_check_mem_access (addr_first, addr_last, bounds,
			     stmt_iter, loc, dirflag);
    }

  /* We need to store bounds in case pointer is stored.  */
  if (dirflag == integer_one_node
      && !reg_store
      && chkp_type_has_pointer (node_type)
      && flag_chkp_store_bounds)
    {
      gimple *stmt = gsi_stmt (*iter);
      tree rhs1 = gimple_assign_rhs1 (stmt);
      enum tree_code rhs_code = gimple_assign_rhs_code (stmt);

      if (get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS)
	chkp_walk_pointer_assignments (node, rhs1, iter,
				       chkp_copy_bounds_for_elem);
      else
	{
	  bounds = chkp_compute_bounds_for_assignment (NULL_TREE, stmt);
	  chkp_build_bndstx (addr_first, rhs1, bounds, iter);
	}
    }
}

/* Add code to copy bounds for all pointers copied
   in ASSIGN created during inline of EDGE.  */
void
chkp_copy_bounds_for_assign (gimple *assign, struct cgraph_edge *edge)
{
  tree lhs = gimple_assign_lhs (assign);
  tree rhs = gimple_assign_rhs1 (assign);
  gimple_stmt_iterator iter = gsi_for_stmt (assign);

  if (!flag_chkp_store_bounds)
    return;

  chkp_walk_pointer_assignments (lhs, rhs, &iter, chkp_copy_bounds_for_elem);

  /* We should create edges for all created calls to bndldx and bndstx.  */
  while (gsi_stmt (iter) != assign)
    {
      gimple *stmt = gsi_stmt (iter);
      if (gimple_code (stmt) == GIMPLE_CALL)
	{
	  tree fndecl = gimple_call_fndecl (stmt);
	  struct cgraph_node *callee = cgraph_node::get_create (fndecl);

	  gcc_assert (chkp_gimple_call_builtin_p (stmt, BUILT_IN_CHKP_BNDSTX)
		      || chkp_gimple_call_builtin_p (stmt, BUILT_IN_CHKP_BNDLDX)
		      || chkp_gimple_call_builtin_p (stmt, BUILT_IN_CHKP_BNDRET));

	  edge->caller->create_edge (callee, as_a <gcall *> (stmt), edge->count);
	}
      gsi_prev (&iter);
    }
}

/* Some code transformation made during instrumentation pass
   may put code into inconsistent state.  Here we find and fix
   such flaws.  */
void
chkp_fix_cfg ()
{
  basic_block bb;
  gimple_stmt_iterator i;

  /* We could insert some code right after stmt which ends bb.
     We wanted to put this code on fallthru edge but did not
     add new edges from the beginning because it may cause new
     phi node creation which may be incorrect due to incomplete
     bound phi nodes.  */
  FOR_ALL_BB_FN (bb, cfun)
    for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
      {
	gimple *stmt = gsi_stmt (i);
	gimple_stmt_iterator next = i;

	gsi_next (&next);

	if (stmt_ends_bb_p (stmt)
	    && !gsi_end_p (next))
	  {
	    edge fall = find_fallthru_edge (bb->succs);
	    basic_block dest = NULL;
	    int flags = 0;

	    gcc_assert (fall);

	    /* We cannot split abnormal edge.  Therefore we
	       store its params, make it regular and then
	       rebuild abnormal edge after split.  */
	    if (fall->flags & EDGE_ABNORMAL)
	      {
		flags = fall->flags & ~EDGE_FALLTHRU;
		dest = fall->dest;

		fall->flags &= ~EDGE_COMPLEX;
	      }

	    while (!gsi_end_p (next))
	      {
		gimple *next_stmt = gsi_stmt (next);
		gsi_remove (&next, false);
		gsi_insert_on_edge (fall, next_stmt);
	      }

	    gsi_commit_edge_inserts ();

	    /* Re-create abnormal edge.  */
	    if (dest)
	      make_edge (bb, dest, flags);
	  }
      }
}

/* Walker callback for chkp_replace_function_pointers.  Replaces
   function pointer in the specified operand with pointer to the
   instrumented function version.  */
static tree
chkp_replace_function_pointer (tree *op, int *walk_subtrees,
			       void *data ATTRIBUTE_UNUSED)
{
  if (TREE_CODE (*op) == FUNCTION_DECL
      && chkp_instrumentable_p (*op)
      && (DECL_BUILT_IN_CLASS (*op) == NOT_BUILT_IN
	  /* For builtins we replace pointers only for selected
	     function and functions having definitions.  */
	  || (DECL_BUILT_IN_CLASS (*op) == BUILT_IN_NORMAL
	      && (chkp_instrument_normal_builtin (*op)
		  || gimple_has_body_p (*op)))))
    {
      struct cgraph_node *node = cgraph_node::get_create (*op);
      struct cgraph_node *clone = NULL;

      if (!node->instrumentation_clone)
	clone = chkp_maybe_create_clone (*op);

      if (clone)
	*op = clone->decl;
      *walk_subtrees = 0;
    }

  return NULL;
}

/* This function searches for function pointers in statement
   pointed by GSI and replaces them with pointers to instrumented
   function versions.  */
static void
chkp_replace_function_pointers (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  /* For calls we want to walk call args only.  */
  if (gimple_code (stmt) == GIMPLE_CALL)
    {
      unsigned i;
      for (i = 0; i < gimple_call_num_args (stmt); i++)
	walk_tree (gimple_call_arg_ptr (stmt, i),
		   chkp_replace_function_pointer, NULL, NULL);
    }
  else
    walk_gimple_stmt (gsi, NULL, chkp_replace_function_pointer, NULL);
}

/* This function instruments all statements working with memory,
   calls and rets.

   It also removes excess statements from static initializers.  */
static void
chkp_instrument_function (void)
{
  basic_block bb, next;
  gimple_stmt_iterator i;
  enum gimple_rhs_class grhs_class;
  bool safe = lookup_attribute ("chkp ctor", DECL_ATTRIBUTES (cfun->decl));

  bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
  do
    {
      next = bb->next_bb;
      for (i = gsi_start_bb (bb); !gsi_end_p (i); )
        {
	  gimple *s = gsi_stmt (i);

	  /* Skip statement marked to not be instrumented.  */
	  if (chkp_marked_stmt_p (s))
	    {
	      gsi_next (&i);
	      continue;
	    }

	  chkp_replace_function_pointers (&i);

          switch (gimple_code (s))
            {
            case GIMPLE_ASSIGN:
	      chkp_process_stmt (&i, gimple_assign_lhs (s),
				 gimple_location (s), integer_one_node,
				 NULL_TREE, NULL_TREE, safe);
	      chkp_process_stmt (&i, gimple_assign_rhs1 (s),
				 gimple_location (s), integer_zero_node,
				 NULL_TREE, NULL_TREE, safe);
	      grhs_class = get_gimple_rhs_class (gimple_assign_rhs_code (s));
	      if (grhs_class == GIMPLE_BINARY_RHS)
		chkp_process_stmt (&i, gimple_assign_rhs2 (s),
				   gimple_location (s), integer_zero_node,
				   NULL_TREE, NULL_TREE, safe);
              break;

            case GIMPLE_RETURN:
	      {
		greturn *r = as_a <greturn *> (s);
		if (gimple_return_retval (r) != NULL_TREE)
		  {
		    chkp_process_stmt (&i, gimple_return_retval (r),
				       gimple_location (r),
				       integer_zero_node,
				       NULL_TREE, NULL_TREE, safe);

		    /* Additionally we need to add bounds
		       to return statement.  */
		    chkp_add_bounds_to_ret_stmt (&i);
		  }
	      }
	      break;

	    case GIMPLE_CALL:
	      chkp_add_bounds_to_call_stmt (&i);
	      break;

            default:
              ;
            }

	  gsi_next (&i);

	  /* We do not need any actual pointer stores in checker
	     static initializer.  */
	  if (lookup_attribute ("chkp ctor", DECL_ATTRIBUTES (cfun->decl))
	      && gimple_code (s) == GIMPLE_ASSIGN
	      && gimple_store_p (s))
	    {
	      gimple_stmt_iterator del_iter = gsi_for_stmt (s);
	      gsi_remove (&del_iter, true);
	      unlink_stmt_vdef (s);
	      release_defs(s);
	    }
        }
      bb = next;
    }
  while (bb);

  /* Some input params may have bounds and be address taken.  In this case
     we should store incoming bounds into bounds table.  */
  tree arg;
  if (flag_chkp_store_bounds)
    for (arg = DECL_ARGUMENTS (cfun->decl); arg; arg = DECL_CHAIN (arg))
      if (TREE_ADDRESSABLE (arg))
	{
	  if (BOUNDED_P (arg))
	    {
	      tree bounds = chkp_get_next_bounds_parm (arg);
	      tree def_ptr = ssa_default_def (cfun, arg);
	      gimple_stmt_iterator iter
		= gsi_start_bb (chkp_get_entry_block ());
	      chkp_build_bndstx (chkp_build_addr_expr (arg),
				 def_ptr ? def_ptr : arg,
				 bounds, &iter);

	      /* Skip bounds arg.  */
	      arg = TREE_CHAIN (arg);
	    }
	  else if (chkp_type_has_pointer (TREE_TYPE (arg)))
	    {
	      tree orig_arg = arg;
	      bitmap slots = BITMAP_ALLOC (NULL);
	      gimple_stmt_iterator iter
		= gsi_start_bb (chkp_get_entry_block ());
	      bitmap_iterator bi;
	      unsigned bnd_no;

	      chkp_find_bound_slots (TREE_TYPE (arg), slots);

	      EXECUTE_IF_SET_IN_BITMAP (slots, 0, bnd_no, bi)
		{
		  tree bounds = chkp_get_next_bounds_parm (arg);
		  HOST_WIDE_INT offs = bnd_no * POINTER_SIZE / BITS_PER_UNIT;
		  tree addr = chkp_build_addr_expr (orig_arg);
		  tree ptr = build2 (MEM_REF, ptr_type_node, addr,
				     build_int_cst (ptr_type_node, offs));
		  chkp_build_bndstx (chkp_build_addr_expr (ptr), ptr,
				     bounds, &iter);

		  arg = DECL_CHAIN (arg);
		}
	      BITMAP_FREE (slots);
	    }
	}
}

/* Find init/null/copy_ptr_bounds calls and replace them
   with assignments.  It should allow better code
   optimization.  */

static void
chkp_remove_useless_builtins ()
{
  basic_block bb;
  gimple_stmt_iterator gsi;

  FOR_EACH_BB_FN (bb, cfun)
    {
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        {
	  gimple *stmt = gsi_stmt (gsi);
	  tree fndecl;
	  enum built_in_function fcode;

	  /* Find builtins returning first arg and replace
	     them with assignments.  */
	  if (gimple_code (stmt) == GIMPLE_CALL
	      && (fndecl = gimple_call_fndecl (stmt))
	      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
	      && (fcode = DECL_FUNCTION_CODE (fndecl))
	      && (fcode == BUILT_IN_CHKP_INIT_PTR_BOUNDS
		  || fcode == BUILT_IN_CHKP_NULL_PTR_BOUNDS
		  || fcode == BUILT_IN_CHKP_COPY_PTR_BOUNDS
		  || fcode == BUILT_IN_CHKP_SET_PTR_BOUNDS))
	    {
	      tree res = gimple_call_arg (stmt, 0);
	      update_call_from_tree (&gsi, res);
	      stmt = gsi_stmt (gsi);
	      update_stmt (stmt);
	    }
        }
    }
}

/* Initialize pass.  */
static void
chkp_init (void)
{
  basic_block bb;
  gimple_stmt_iterator i;

  in_chkp_pass = true;

  for (bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; bb; bb = bb->next_bb)
    for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
      chkp_unmark_stmt (gsi_stmt (i));

  chkp_invalid_bounds = new hash_set<tree>;
  chkp_completed_bounds_set = new hash_set<tree>;
  delete chkp_reg_bounds;
  chkp_reg_bounds = new hash_map<tree, tree>;
  delete chkp_bound_vars;
  chkp_bound_vars = new hash_map<tree, tree>;
  chkp_reg_addr_bounds = new hash_map<tree, tree>;
  chkp_incomplete_bounds_map = new hash_map<tree, tree>;
  delete chkp_bounds_map;
  chkp_bounds_map = new hash_map<tree, tree>;
  chkp_abnormal_copies = BITMAP_GGC_ALLOC ();

  entry_block = NULL;
  zero_bounds = NULL_TREE;
  none_bounds = NULL_TREE;
  incomplete_bounds = integer_zero_node;
  tmp_var = NULL_TREE;
  size_tmp_var = NULL_TREE;

  chkp_uintptr_type = lang_hooks.types.type_for_mode (ptr_mode, true);

  /* We create these constant bounds once for each object file.
     These symbols go to comdat section and result in single copy
     of each one in the final binary.  */
  chkp_get_zero_bounds_var ();
  chkp_get_none_bounds_var ();

  calculate_dominance_info (CDI_DOMINATORS);
  calculate_dominance_info (CDI_POST_DOMINATORS);

  bitmap_obstack_initialize (NULL);
}

/* Finalize instrumentation pass.  */
static void
chkp_fini (void)
{
  in_chkp_pass = false;

  delete chkp_invalid_bounds;
  delete chkp_completed_bounds_set;
  delete chkp_reg_addr_bounds;
  delete chkp_incomplete_bounds_map;

  free_dominance_info (CDI_DOMINATORS);
  free_dominance_info (CDI_POST_DOMINATORS);

  bitmap_obstack_release (NULL);

  entry_block = NULL;
  zero_bounds = NULL_TREE;
  none_bounds = NULL_TREE;
}

/* Main instrumentation pass function.  */
static unsigned int
chkp_execute (void)
{
  chkp_init ();

  chkp_instrument_function ();

  chkp_remove_useless_builtins ();

  chkp_function_mark_instrumented (cfun->decl);

  chkp_fix_cfg ();

  chkp_fini ();

  return 0;
}

/* Instrumentation pass gate.  */
static bool
chkp_gate (void)
{
  cgraph_node *node = cgraph_node::get (cfun->decl);
  return ((node != NULL
	   && node->instrumentation_clone)
	   || lookup_attribute ("chkp ctor", DECL_ATTRIBUTES (cfun->decl)));
}

namespace {

const pass_data pass_data_chkp =
{
  GIMPLE_PASS, /* type */
  "chkp", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  PROP_ssa | PROP_cfg, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_verify_il
  | TODO_update_ssa /* todo_flags_finish */
};

class pass_chkp : public gimple_opt_pass
{
public:
  pass_chkp (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_chkp, ctxt)
  {}

  /* opt_pass methods: */
  virtual opt_pass * clone ()
    {
      return new pass_chkp (m_ctxt);
    }

  virtual bool gate (function *)
    {
      return chkp_gate ();
    }

  virtual unsigned int execute (function *)
    {
      return chkp_execute ();
    }

}; // class pass_chkp

} // anon namespace

gimple_opt_pass *
make_pass_chkp (gcc::context *ctxt)
{
  return new pass_chkp (ctxt);
}

#include "gt-tree-chkp.h"
