/* Pointer Bounds Checker insrumentation pass.
   Copyright (C) 2014-2015 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 "hash-set.h"
#include "machmode.h"
#include "vec.h"
#include "double-int.h"
#include "input.h"
#include "alias.h"
#include "symtab.h"
#include "options.h"
#include "wide-int.h"
#include "inchash.h"
#include "tree.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "varasm.h"
#include "target.h"
#include "tree-iterator.h"
#include "tree-cfg.h"
#include "langhooks.h"
#include "tree-pass.h"
#include "diagnostic.h"
#include "ggc.h"
#include "is-a.h"
#include "cfgloop.h"
#include "stringpool.h"
#include "tree-ssa-alias.h"
#include "tree-ssanames.h"
#include "tree-ssa-operands.h"
#include "tree-ssa-address.h"
#include "tree-ssa.h"
#include "predict.h"
#include "dominance.h"
#include "cfg.h"
#include "basic-block.h"
#include "tree-ssa-loop-niter.h"
#include "gimple-expr.h"
#include "gimple.h"
#include "tree-phinodes.h"
#include "gimple-ssa.h"
#include "ssa-iterators.h"
#include "gimple-pretty-print.h"
#include "gimple-iterator.h"
#include "gimplify.h"
#include "gimplify-me.h"
#include "print-tree.h"
#include "hashtab.h"
#include "tm.h"
#include "hard-reg-set.h"
#include "function.h"
#include "rtl.h"
#include "flags.h"
#include "statistics.h"
#include "real.h"
#include "fixed-value.h"
#include "insn-config.h"
#include "expmed.h"
#include "dojump.h"
#include "explow.h"
#include "calls.h"
#include "emit-rtl.h"
#include "stmt.h"
#include "expr.h"
#include "tree-ssa-propagate.h"
#include "gimple-fold.h"
#include "tree-chkp.h"
#include "gimple-walk.h"
#include "rtl.h" /* For MEM_P, assign_temp.  */
#include "tree-dfa.h"
#include "ipa-ref.h"
#include "lto-streamer.h"
#include "cgraph.h"
#include "ipa-chkp.h"
#include "params.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);

#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;
  if (is_gimple_call (call)
      && (fndecl = targetm.builtin_chkp_function (code))
      && gimple_call_fndecl (call) == 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, 0);
      fprintf (dump_file, " for address of ");
      print_generic_expr (dump_file, obj, 0);
      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, 0);
      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>;
}

/* 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, 0);
      fprintf (dump_file, " for ");
      print_generic_expr (dump_file, ptr, 0);
      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, 0);
      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;

  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 (TREE_CODE (var) == VAR_DECL);
  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)
{
  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 (ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL)->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, 0);
	      fprintf (dump_file, " for abnormal default def SSA name ");
	      print_generic_expr (dump_file, ptr, 0);
	      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, gimple_build_nop ());
	  else
	    copy = make_temp_ssa_name (pointer_bounds_type_node,
				       gimple_build_nop (),
				       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, 0);
	      fprintf (dump_file, " for abnormal SSA name ");
	      print_generic_expr (dump_file, ptr, 0);
	      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, 0);
      fprintf (dump_file, " for pointer ");
      print_generic_expr (dump_file, ptr, 0);
      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, gimple_build_nop (), "");
	  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);
	}
    }
}

/* 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
	      = 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)
    {
      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 <= 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))
    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);
      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 '%s' "
	       "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 (gimple_build_nop ());
      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 (gimple_build_nop ());
      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))
    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);
  tree lhs = gimple_call_lhs (call);
  unsigned int retflags;

  /* To avoid fixing alloca expands in targets we handle
     it separately.  */
  if (fndecl
      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
      && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA
	  || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA_WITH_ALIGN))
    {
      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, 0);
      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 (gimple_code (USE_STMT (use_p)) == GIMPLE_CALL
	&& gimple_call_fndecl (USE_STMT (use_p)) == chkp_ret_bnd_fndecl)
      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
	       && strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (orig_decl)),
			  "main") == 0)
	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, 0);
	      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, 0);
      fprintf (dump_file, " for parm ");
      print_generic_expr (dump_file, parm, 0);
      fprintf (dump_file, " of type ");
      print_generic_expr (dump_file, TREE_TYPE (parm), 0);
      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, 0);
      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);
    }
}

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

      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, 0);
	    }
	  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,
				    gimple_build_nop (),
				    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 (TREE_CODE (obj) == VAR_DECL)
	{
	  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 (TREE_CODE (obj) == VAR_DECL)
    {
      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);
    }

  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 (TREE_CODE (obj) == VAR_DECL)
    {
      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, 0);
      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 (), gimple_build_nop ());

  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 (TREE_CODE (decl) == VAR_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, 0);
      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
      && TREE_CODE (decl) == VAR_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 (gimple_build_nop ());
      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 (TREE_CODE (decl) == VAR_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 (gimple_build_nop ());
      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.  */
static bool
chkp_may_narrow_to_field (tree field)
{
  return DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST
    && tree_to_uhwi (DECL_SIZE (field)) != 0
    && (!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.  */
static bool
chkp_narrow_bounds_for_field (tree field)
{
  HOST_WIDE_INT offs;
  HOST_WIDE_INT bit_offs;

  if (!chkp_may_narrow_to_field (field))
    return false;

  /* Accesse 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 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)
    {
      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)));
  /* To get bitfield address we will need outer elemnt.  */
  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 (TREE_CODE (var) == VAR_DECL
		  || 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);
    }

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

/* 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:
      {
	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 (TREE_CODE (ptr) == VAR_DECL && 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 (DECL_P (addr)
	  || TREE_CODE (addr) == MEM_REF
	  || TREE_CODE (addr) == TARGET_MEM_REF)
	{
	  if (BOUNDED_P (ptr_src))
	    if (TREE_CODE (ptr) == VAR_DECL && 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:
      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;

  /* 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 offs, rem, bpu;

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

	bpu = fold_convert (size_type_node, bitsize_int (BITS_PER_UNIT));
	offs = fold_convert (size_type_node, TREE_OPERAND (node, 2));
	rem = size_binop_loc (loc, TRUNC_MOD_EXPR, offs, bpu);
	offs = size_binop_loc (loc, TRUNC_DIV_EXPR, offs, bpu);

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

	chkp_process_stmt (iter, TREE_OPERAND (node, 0), loc,
			 dirflag, offs, 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);
    }

  /* 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
      && 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);
	  struct cgraph_edge *new_edge;

	  gcc_assert (fndecl == chkp_bndstx_fndecl
		      || fndecl == chkp_bndldx_fndecl
		      || fndecl == chkp_ret_bnd_fndecl);

	  new_edge = edge->caller->create_edge (callee,
						as_a <gcall *> (stmt),
						edge->count,
						edge->frequency);
	  new_edge->frequency = compute_call_stmt_bb_frequency
	    (edge->caller->decl, gimple_bb (stmt));
	}
      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)
{
  return cgraph_node::get (cfun->decl)->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"
