/* Tree lowering pass.  This pass gimplifies the tree representation built
   by the C-based front ends.  The structure of gimplified, or
   language-independent, trees is dictated by the grammar described in this
   file.
   Copyright (C) 2002-2021 Free Software Foundation, Inc.
   Lowering of expressions contributed by Sebastian Pop <s.pop@laposte.net>
   Re-written to support lowering of whole function trees, documentation
   and miscellaneous cleanups by Diego Novillo <dnovillo@redhat.com>

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "function.h"
#include "basic-block.h"
#include "tree.h"
#include "tree-iterator.h"
#include "predict.h"
#include "gimple.h"
#include "cgraph.h"
#include "c-pretty-print.h"
#include "gimplify.h"
#include "langhooks.h"
#include "dumpfile.h"
#include "c-ubsan.h"
#include "tree-nested.h"

/*  The gimplification pass converts the language-dependent trees
    (ld-trees) emitted by the parser into language-independent trees
    (li-trees) that are the target of SSA analysis and transformations.

    Language-independent trees are based on the SIMPLE intermediate
    representation used in the McCAT compiler framework:

    "Designing the McCAT Compiler Based on a Family of Structured
    Intermediate Representations,"
    L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
    Proceedings of the 5th International Workshop on Languages and
    Compilers for Parallel Computing, no. 757 in Lecture Notes in
    Computer Science, New Haven, Connecticut, pp. 406-420,
    Springer-Verlag, August 3-5, 1992.

    http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html

    Basically, we walk down gimplifying the nodes that we encounter.  As we
    walk back up, we check that they fit our constraints, and copy them
    into temporaries if not.  */

/* Callback for c_genericize.  */

static tree
ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
{
  hash_set<tree> *pset = (hash_set<tree> *) data;

  if (TREE_CODE (*tp) == BIND_EXPR)
    {
      /* Since walk_tree doesn't call the callback function on the decls
	 in BIND_EXPR_VARS, we have to walk them manually, so we can avoid
	 instrumenting DECL_INITIAL of TREE_STATIC vars.  */
      *walk_subtrees = 0;
      for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
	{
	  if (TREE_STATIC (decl))
	    continue;
	  walk_tree (&DECL_INITIAL (decl), ubsan_walk_array_refs_r, pset,
		     pset);
	  walk_tree (&DECL_SIZE (decl), ubsan_walk_array_refs_r, pset, pset);
	  walk_tree (&DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, pset,
		     pset);
	}
      walk_tree (&BIND_EXPR_BODY (*tp), ubsan_walk_array_refs_r, pset, pset);
    }
  else if (TREE_CODE (*tp) == ADDR_EXPR
	   && TREE_CODE (TREE_OPERAND (*tp, 0)) == ARRAY_REF)
    {
      ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), true);
      /* Make sure ubsan_maybe_instrument_array_ref is not called again
	 on the ARRAY_REF, the above call might not instrument anything
	 as the index might be constant or masked, so ensure it is not
	 walked again and walk its subtrees manually.  */
      tree aref = TREE_OPERAND (*tp, 0);
      pset->add (aref);
      *walk_subtrees = 0;
      walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
      walk_tree (&TREE_OPERAND (aref, 1), ubsan_walk_array_refs_r, pset, pset);
      walk_tree (&TREE_OPERAND (aref, 2), ubsan_walk_array_refs_r, pset, pset);
      walk_tree (&TREE_OPERAND (aref, 3), ubsan_walk_array_refs_r, pset, pset);
    }
  else if (TREE_CODE (*tp) == ARRAY_REF)
    ubsan_maybe_instrument_array_ref (tp, false);
  return NULL_TREE;
}

/* Gimplification of statement trees.  */

/* Local declarations.  */

enum bc_t { bc_break = 0, bc_continue = 1 };

/* Stack of labels which are targets for "break" or "continue",
   linked through TREE_CHAIN.  */
static tree bc_label[2];

/* Begin a scope which can be exited by a break or continue statement.  BC
   indicates which.

   Just creates a label with location LOCATION and pushes it into the current
   context.  */

static tree
begin_bc_block (enum bc_t bc, location_t location)
{
  tree label = create_artificial_label (location);
  DECL_CHAIN (label) = bc_label[bc];
  bc_label[bc] = label;
  if (bc == bc_break)
    LABEL_DECL_BREAK (label) = true;
  else
    LABEL_DECL_CONTINUE (label) = true;
  return label;
}

/* Finish a scope which can be exited by a break or continue statement.
   LABEL was returned from the most recent call to begin_bc_block.  BLOCK is
   an expression for the contents of the scope.

   If we saw a break (or continue) in the scope, append a LABEL_EXPR to
   BLOCK.  Otherwise, just forget the label.  */

static void
finish_bc_block (tree *block, enum bc_t bc, tree label)
{
  gcc_assert (label == bc_label[bc]);

  if (TREE_USED (label))
    append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label),
			      block);

  bc_label[bc] = DECL_CHAIN (label);
  DECL_CHAIN (label) = NULL_TREE;
}

/* Allow saving and restoring break/continue state.  */

void
save_bc_state (bc_state_t *state)
{
  state->bc_label[bc_break] = bc_label[bc_break];
  state->bc_label[bc_continue] = bc_label[bc_continue];
  bc_label[bc_break] = NULL_TREE;
  bc_label[bc_continue] = NULL_TREE;
}

void
restore_bc_state (bc_state_t *state)
{
  gcc_assert (bc_label[bc_break] == NULL);
  gcc_assert (bc_label[bc_continue] == NULL);
  bc_label[bc_break] = state->bc_label[bc_break];
  bc_label[bc_continue] = state->bc_label[bc_continue];
}

/* Get the LABEL_EXPR to represent a break or continue statement
   in the current block scope.  BC indicates which.  */

static tree
get_bc_label (enum bc_t bc)
{
  tree label = bc_label[bc];
  gcc_assert (label);

  /* Mark the label used for finish_bc_block.  */
  TREE_USED (label) = 1;
  return label;
}

/* Return the location from EXPR, or OR_LOC if the former is unknown.  */

location_t
expr_loc_or_loc (const_tree expr, location_t or_loc)
{
  tree t = CONST_CAST_TREE (expr);
  location_t loc = UNKNOWN_LOCATION;
  if (t)
    loc = EXPR_LOCATION (t);
  if (loc == UNKNOWN_LOCATION)
    loc = or_loc;
  return loc;
}

/* Build a generic representation of one of the C loop forms.  COND is the
   loop condition or NULL_TREE.  BODY is the (possibly compound) statement
   controlled by the loop.  INCR is the increment expression of a for-loop,
   or NULL_TREE.  COND_IS_FIRST indicates whether the condition is
   evaluated before the loop body as in while and for loops, or after the
   loop body as in do-while loops.  */

static void
genericize_c_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
		   tree incr, bool cond_is_first, int *walk_subtrees,
		   void *data, walk_tree_fn func, walk_tree_lh lh)
{
  tree blab, clab;
  tree entry = NULL, exit = NULL, t;
  tree stmt_list = NULL;
  location_t cond_locus = expr_loc_or_loc (cond, start_locus);
  location_t incr_locus = expr_loc_or_loc (incr, start_locus);

  protected_set_expr_location_if_unset (incr, start_locus);

  walk_tree_1 (&cond, func, data, NULL, lh);
  walk_tree_1 (&incr, func, data, NULL, lh);

  blab = begin_bc_block (bc_break, start_locus);
  clab = begin_bc_block (bc_continue, start_locus);

  walk_tree_1 (&body, func, data, NULL, lh);
  *walk_subtrees = 0;

  /* If condition is zero don't generate a loop construct.  */
  if (cond && integer_zerop (cond))
    {
      if (cond_is_first)
	{
	  t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
			  get_bc_label (bc_break));
	  append_to_statement_list (t, &stmt_list);
	}
    }
  else
    {
      /* Expand to gotos.  */
      tree top = build1 (LABEL_EXPR, void_type_node,
			 create_artificial_label (start_locus));

      /* If we have an exit condition, then we build an IF with gotos either
	 out of the loop, or to the top of it.  If there's no exit condition,
	 then we just build a jump back to the top.  */
      exit = build1 (GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL (top));

      if (cond && !integer_nonzerop (cond))
	{
	  /* Canonicalize the loop condition to the end.  This means
	     generating a branch to the loop condition.  Reuse the
	     continue label, if there is no incr expression.  */
	  if (cond_is_first)
	    {
	      if (incr)
		{
		  entry = build1 (LABEL_EXPR, void_type_node,
				  create_artificial_label (start_locus));
		  t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
				  LABEL_EXPR_LABEL (entry));
		}
	      else
		t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
				get_bc_label (bc_continue));
	      append_to_statement_list (t, &stmt_list);
	    }

	  t = build1 (GOTO_EXPR, void_type_node, get_bc_label (bc_break));
	  exit = fold_build3_loc (cond_locus,
				  COND_EXPR, void_type_node, cond, exit, t);
	}
      else
	{
	  /* For the backward-goto's location of an unconditional loop
	     use the beginning of the body, or, if there is none, the
	     top of the loop.  */
	  location_t loc = expr_loc_or_loc (expr_first (body),
					    start_locus);
	  SET_EXPR_LOCATION (exit, loc);
	}
      append_to_statement_list (top, &stmt_list);
    }

  append_to_statement_list (body, &stmt_list);
  finish_bc_block (&stmt_list, bc_continue, clab);
  if (incr)
    {
      if (MAY_HAVE_DEBUG_MARKER_STMTS && incr_locus != UNKNOWN_LOCATION)
	{
	  tree d = build0 (DEBUG_BEGIN_STMT, void_type_node);
	  SET_EXPR_LOCATION (d, expr_loc_or_loc (incr, start_locus));
	  append_to_statement_list (d, &stmt_list);
	}
      append_to_statement_list (incr, &stmt_list);
    }
  append_to_statement_list (entry, &stmt_list);

  if (MAY_HAVE_DEBUG_MARKER_STMTS && cond_locus != UNKNOWN_LOCATION)
    {
      tree d = build0 (DEBUG_BEGIN_STMT, void_type_node);
      SET_EXPR_LOCATION (d, cond_locus);
      append_to_statement_list (d, &stmt_list);
    }
  append_to_statement_list (exit, &stmt_list);
  finish_bc_block (&stmt_list, bc_break, blab);
  if (!stmt_list)
    stmt_list = build_empty_stmt (start_locus);

  *stmt_p = stmt_list;
}

/* Genericize a FOR_STMT node *STMT_P.  */

static void
genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data,
		     walk_tree_fn func, walk_tree_lh lh)
{
  tree stmt = *stmt_p;
  tree expr = NULL;
  tree loop;
  tree init = FOR_INIT_STMT (stmt);

  if (init)
    {
      walk_tree_1 (&init, func, data, NULL, lh);
      append_to_statement_list (init, &expr);
    }

  genericize_c_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
		     FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees,
		     data, func, lh);
  append_to_statement_list (loop, &expr);
  if (expr == NULL_TREE)
    expr = loop;
  *stmt_p = expr;
}

/* Genericize a WHILE_STMT node *STMT_P.  */

static void
genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data,
		       walk_tree_fn func, walk_tree_lh lh)
{
  tree stmt = *stmt_p;
  genericize_c_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt),
		     WHILE_BODY (stmt), NULL_TREE, 1, walk_subtrees,
		     data, func, lh);
}

/* Genericize a DO_STMT node *STMT_P.  */

static void
genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data,
		    walk_tree_fn func, walk_tree_lh lh)
{
  tree stmt = *stmt_p;
  genericize_c_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt),
		     DO_BODY (stmt), NULL_TREE, 0, walk_subtrees,
		     data, func, lh);
}

/* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR.  */

static void
genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data,
			walk_tree_fn func, walk_tree_lh lh)
{
  tree stmt = *stmt_p;
  tree break_block, body, cond, type;
  location_t stmt_locus = EXPR_LOCATION (stmt);

  body = SWITCH_STMT_BODY (stmt);
  if (!body)
    body = build_empty_stmt (stmt_locus);
  cond = SWITCH_STMT_COND (stmt);
  type = SWITCH_STMT_TYPE (stmt);

  walk_tree_1 (&cond, func, data, NULL, lh);

  break_block = begin_bc_block (bc_break, stmt_locus);

  walk_tree_1 (&body, func, data, NULL, lh);
  walk_tree_1 (&type, func, data, NULL, lh);
  *walk_subtrees = 0;

  if (TREE_USED (break_block))
    SWITCH_BREAK_LABEL_P (break_block) = 1;
  finish_bc_block (&body, bc_break, break_block);
  *stmt_p = build2_loc (stmt_locus, SWITCH_EXPR, type, cond, body);
  SWITCH_ALL_CASES_P (*stmt_p) = SWITCH_STMT_ALL_CASES_P (stmt);
  gcc_checking_assert (!SWITCH_STMT_NO_BREAK_P (stmt)
		       || !TREE_USED (break_block));
}

/* Genericize a CONTINUE_STMT node *STMT_P.  */

static void
genericize_continue_stmt (tree *stmt_p)
{
  tree stmt_list = NULL;
  tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN);
  tree label = get_bc_label (bc_continue);
  location_t location = EXPR_LOCATION (*stmt_p);
  tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label);
  append_to_statement_list_force (pred, &stmt_list);
  append_to_statement_list (jump, &stmt_list);
  *stmt_p = stmt_list;
}

/* Genericize a BREAK_STMT node *STMT_P.  */

static void
genericize_break_stmt (tree *stmt_p)
{
  tree label = get_bc_label (bc_break);
  location_t location = EXPR_LOCATION (*stmt_p);
  *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label);
}

/* Genericize a OMP_FOR node *STMT_P.  */

static void
genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data,
			 walk_tree_fn func, walk_tree_lh lh)
{
  tree stmt = *stmt_p;
  location_t locus = EXPR_LOCATION (stmt);
  tree clab = begin_bc_block (bc_continue, locus);

  walk_tree_1 (&OMP_FOR_BODY (stmt), func, data, NULL, lh);
  if (TREE_CODE (stmt) != OMP_TASKLOOP)
    walk_tree_1 (&OMP_FOR_CLAUSES (stmt), func, data, NULL, lh);
  walk_tree_1 (&OMP_FOR_INIT (stmt), func, data, NULL, lh);
  walk_tree_1 (&OMP_FOR_COND (stmt), func, data, NULL, lh);
  walk_tree_1 (&OMP_FOR_INCR (stmt), func, data, NULL, lh);
  walk_tree_1 (&OMP_FOR_PRE_BODY (stmt), func, data, NULL, lh);
  *walk_subtrees = 0;

  finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab);
}


/* Lower structured control flow tree nodes, such as loops.  The
   STMT_P, WALK_SUBTREES, and DATA arguments are as for the walk_tree_fn
   type.  FUNC and LH are language-specific functions passed to walk_tree_1
   for node visiting and traversal, respectively; they are used to do
   subtree processing in a language-dependent way.  */

tree
c_genericize_control_stmt (tree *stmt_p, int *walk_subtrees, void *data,
			   walk_tree_fn func, walk_tree_lh lh)
{
  tree stmt = *stmt_p;

  switch (TREE_CODE (stmt))
    {
    case FOR_STMT:
      genericize_for_stmt (stmt_p, walk_subtrees, data, func, lh);
      break;

    case WHILE_STMT:
      genericize_while_stmt (stmt_p, walk_subtrees, data, func, lh);
      break;

    case DO_STMT:
      genericize_do_stmt (stmt_p, walk_subtrees, data, func, lh);
      break;

    case SWITCH_STMT:
      genericize_switch_stmt (stmt_p, walk_subtrees, data, func, lh);
      break;

    case CONTINUE_STMT:
      genericize_continue_stmt (stmt_p);
      break;

    case BREAK_STMT:
      genericize_break_stmt (stmt_p);
      break;

    case OMP_FOR:
    case OMP_SIMD:
    case OMP_DISTRIBUTE:
    case OMP_LOOP:
    case OMP_TASKLOOP:
    case OACC_LOOP:
      genericize_omp_for_stmt (stmt_p, walk_subtrees, data, func, lh);
      break;

    case STATEMENT_LIST:
      if (TREE_SIDE_EFFECTS (stmt))
	{
	  tree_stmt_iterator i;
	  int nondebug_stmts = 0;
	  bool clear_side_effects = true;
	  /* Genericization can clear TREE_SIDE_EFFECTS, e.g. when
	     transforming an IF_STMT into COND_EXPR.  If such stmt
	     appears in a STATEMENT_LIST that contains only that
	     stmt and some DEBUG_BEGIN_STMTs, without -g where the
	     STATEMENT_LIST wouldn't be present at all the resulting
	     expression wouldn't have TREE_SIDE_EFFECTS set, so make sure
	     to clear it even on the STATEMENT_LIST in such cases.  */
	  for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i))
	    {
	      tree t = tsi_stmt (i);
	      if (TREE_CODE (t) != DEBUG_BEGIN_STMT && nondebug_stmts < 2)
		nondebug_stmts++;
	      walk_tree_1 (tsi_stmt_ptr (i), func, data, NULL, lh);
	      if (TREE_CODE (t) != DEBUG_BEGIN_STMT
		  && (nondebug_stmts > 1 || TREE_SIDE_EFFECTS (tsi_stmt (i))))
		clear_side_effects = false;
	    }
	  if (clear_side_effects)
	    TREE_SIDE_EFFECTS (stmt) = 0;
	  *walk_subtrees = 0;
	}
      break;

    default:
      break;
    }

  return NULL;
}


/* Wrapper for c_genericize_control_stmt to allow it to be used as a walk_tree
   callback.  This is appropriate for C; C++ calls c_genericize_control_stmt
   directly.  */

static tree
c_genericize_control_r (tree *stmt_p, int *walk_subtrees, void *data)
{
  c_genericize_control_stmt (stmt_p, walk_subtrees, data,
			     c_genericize_control_r, NULL);
  return NULL;
}

/* Convert the tree representation of FNDECL from C frontend trees to
   GENERIC.  */

void
c_genericize (tree fndecl)
{
  FILE *dump_orig;
  dump_flags_t local_dump_flags;
  struct cgraph_node *cgn;

  if (flag_sanitize & SANITIZE_BOUNDS)
    {
      hash_set<tree> pset;
      walk_tree (&DECL_SAVED_TREE (fndecl), ubsan_walk_array_refs_r, &pset,
		 &pset);
    }

  /* Genericize loops and other structured control constructs.  The C++
     front end has already done this in lang-specific code.  */
  if (!c_dialect_cxx ())
    {
      bc_state_t save_state;
      push_cfun (DECL_STRUCT_FUNCTION (fndecl));
      save_bc_state (&save_state);
      walk_tree (&DECL_SAVED_TREE (fndecl), c_genericize_control_r,
		 NULL, NULL);
      restore_bc_state (&save_state);
      pop_cfun ();
    }

  if (warn_duplicated_branches)
    walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
				  do_warn_duplicated_branches_r, NULL);

  /* Dump the C-specific tree IR.  */
  dump_orig = get_dump_info (TDI_original, &local_dump_flags);
  if (dump_orig)
    {
      fprintf (dump_orig, "\n;; Function %s",
	       lang_hooks.decl_printable_name (fndecl, 2));
      fprintf (dump_orig, " (%s)\n",
	       (!DECL_ASSEMBLER_NAME_SET_P (fndecl) ? "null"
		: IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl))));
      fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original));
      fprintf (dump_orig, "\n");

      if (local_dump_flags & TDF_RAW)
	dump_node (DECL_SAVED_TREE (fndecl),
		   TDF_SLIM | local_dump_flags, dump_orig);
      else
	print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl));
      fprintf (dump_orig, "\n");
    }

  /* Dump all nested functions now.  */
  cgn = cgraph_node::get_create (fndecl);
  for (cgn = first_nested_function (cgn);
       cgn; cgn = next_nested_function (cgn))
    c_genericize (cgn->decl);
}

static void
add_block_to_enclosing (tree block)
{
  unsigned i;
  tree enclosing;
  gbind *bind;
  vec<gbind *> stack = gimple_bind_expr_stack ();

  FOR_EACH_VEC_ELT (stack, i, bind)
    if (gimple_bind_block (bind))
      break;

  enclosing = gimple_bind_block (bind);
  BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
}

/* Genericize a scope by creating a new BIND_EXPR.
   BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
     In the latter case, we need to create a new BLOCK and add it to the
     BLOCK_SUBBLOCKS of the enclosing block.
   BODY is a chain of C _STMT nodes for the contents of the scope, to be
     genericized.  */

tree
c_build_bind_expr (location_t loc, tree block, tree body)
{
  tree decls, bind;

  if (block == NULL_TREE)
    decls = NULL_TREE;
  else if (TREE_CODE (block) == BLOCK)
    decls = BLOCK_VARS (block);
  else
    {
      decls = block;
      if (DECL_ARTIFICIAL (decls))
	block = NULL_TREE;
      else
	{
	  block = make_node (BLOCK);
	  BLOCK_VARS (block) = decls;
	  add_block_to_enclosing (block);
	}
    }

  if (!body)
    body = build_empty_stmt (loc);
  if (decls || block)
    {
      bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
      TREE_SIDE_EFFECTS (bind) = 1;
      SET_EXPR_LOCATION (bind, loc);
    }
  else
    bind = body;

  return bind;
}

/* Gimplification of expression trees.  */

/* Do C-specific gimplification on *EXPR_P.  PRE_P and POST_P are as in
   gimplify_expr.  */

int
c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
		 gimple_seq *post_p ATTRIBUTE_UNUSED)
{
  enum tree_code code = TREE_CODE (*expr_p);

  switch (code)
    {
    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
    case LROTATE_EXPR:
    case RROTATE_EXPR:
      {
	/* We used to convert the right operand of a shift-expression
	   to an integer_type_node in the FEs.  But it is unnecessary
	   and not desirable for diagnostics and sanitizers.  We keep
	   this here to not pessimize the code, but we convert to an
	   unsigned type, because negative shift counts are undefined
	   anyway.
	   We should get rid of this conversion when we have a proper
	   type demotion/promotion pass.  */
	tree *op1_p = &TREE_OPERAND (*expr_p, 1);
	if (!VECTOR_TYPE_P (TREE_TYPE (*op1_p))
	    && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
				    unsigned_type_node)
	    && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
				    integer_type_node))
	  /* Make sure to unshare the result, tree sharing is invalid
	     during gimplification.  */
	  *op1_p = unshare_expr (convert (unsigned_type_node, *op1_p));
	break;
      }

    case DECL_EXPR:
      /* This is handled mostly by gimplify.c, but we have to deal with
	 not warning about int x = x; as it is a GCC extension to turn off
	 this warning but only if warn_init_self is zero.  */
      if (VAR_P (DECL_EXPR_DECL (*expr_p))
	  && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
	  && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
	  && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p))
	  && !warn_init_self)
	suppress_warning (DECL_EXPR_DECL (*expr_p), OPT_Winit_self);
      break;

    case PREINCREMENT_EXPR:
    case PREDECREMENT_EXPR:
    case POSTINCREMENT_EXPR:
    case POSTDECREMENT_EXPR:
      {
	tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
	if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type))
	  {
	    if (!TYPE_OVERFLOW_WRAPS (type))
	      type = unsigned_type_for (type);
	    return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type);
	  }
	break;
      }

    default:;
    }

  return GS_UNHANDLED;
}
