1/* Tree lowering pass.  This pass gimplifies the tree representation built
2   by the C-based front ends.  The structure of gimplified, or
3   language-independent, trees is dictated by the grammar described in this
4   file.
5   Copyright (C) 2002-2022 Free Software Foundation, Inc.
6   Lowering of expressions contributed by Sebastian Pop <s.pop@laposte.net>
7   Re-written to support lowering of whole function trees, documentation
8   and miscellaneous cleanups by Diego Novillo <dnovillo@redhat.com>
9
10This file is part of GCC.
11
12GCC is free software; you can redistribute it and/or modify it under
13the terms of the GNU General Public License as published by the Free
14Software Foundation; either version 3, or (at your option) any later
15version.
16
17GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18WARRANTY; without even the implied warranty of MERCHANTABILITY or
19FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20for more details.
21
22You should have received a copy of the GNU General Public License
23along with GCC; see the file COPYING3.  If not see
24<http://www.gnu.org/licenses/>.  */
25
26#include "config.h"
27#include "system.h"
28#include "coretypes.h"
29#include "tm.h"
30#include "function.h"
31#include "basic-block.h"
32#include "tree.h"
33#include "tree-iterator.h"
34#include "predict.h"
35#include "gimple.h"
36#include "cgraph.h"
37#include "c-pretty-print.h"
38#include "gimplify.h"
39#include "langhooks.h"
40#include "dumpfile.h"
41#include "c-ubsan.h"
42#include "tree-nested.h"
43
44/*  The gimplification pass converts the language-dependent trees
45    (ld-trees) emitted by the parser into language-independent trees
46    (li-trees) that are the target of SSA analysis and transformations.
47
48    Language-independent trees are based on the SIMPLE intermediate
49    representation used in the McCAT compiler framework:
50
51    "Designing the McCAT Compiler Based on a Family of Structured
52    Intermediate Representations,"
53    L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
54    Proceedings of the 5th International Workshop on Languages and
55    Compilers for Parallel Computing, no. 757 in Lecture Notes in
56    Computer Science, New Haven, Connecticut, pp. 406-420,
57    Springer-Verlag, August 3-5, 1992.
58
59    http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
60
61    Basically, we walk down gimplifying the nodes that we encounter.  As we
62    walk back up, we check that they fit our constraints, and copy them
63    into temporaries if not.  */
64
65/* Callback for c_genericize.  */
66
67static tree
68ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
69{
70  hash_set<tree> *pset = (hash_set<tree> *) data;
71
72  if (TREE_CODE (*tp) == BIND_EXPR)
73    {
74      /* Since walk_tree doesn't call the callback function on the decls
75	 in BIND_EXPR_VARS, we have to walk them manually, so we can avoid
76	 instrumenting DECL_INITIAL of TREE_STATIC vars.  */
77      *walk_subtrees = 0;
78      for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
79	{
80	  if (TREE_STATIC (decl))
81	    continue;
82	  walk_tree (&DECL_INITIAL (decl), ubsan_walk_array_refs_r, pset,
83		     pset);
84	  walk_tree (&DECL_SIZE (decl), ubsan_walk_array_refs_r, pset, pset);
85	  walk_tree (&DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, pset,
86		     pset);
87	}
88      walk_tree (&BIND_EXPR_BODY (*tp), ubsan_walk_array_refs_r, pset, pset);
89    }
90  else if (TREE_CODE (*tp) == ADDR_EXPR
91	   && TREE_CODE (TREE_OPERAND (*tp, 0)) == ARRAY_REF)
92    {
93      ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), true);
94      /* Make sure ubsan_maybe_instrument_array_ref is not called again
95	 on the ARRAY_REF, the above call might not instrument anything
96	 as the index might be constant or masked, so ensure it is not
97	 walked again and walk its subtrees manually.  */
98      tree aref = TREE_OPERAND (*tp, 0);
99      pset->add (aref);
100      *walk_subtrees = 0;
101      walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
102      walk_tree (&TREE_OPERAND (aref, 1), ubsan_walk_array_refs_r, pset, pset);
103      walk_tree (&TREE_OPERAND (aref, 2), ubsan_walk_array_refs_r, pset, pset);
104      walk_tree (&TREE_OPERAND (aref, 3), ubsan_walk_array_refs_r, pset, pset);
105    }
106  else if (TREE_CODE (*tp) == ARRAY_REF)
107    ubsan_maybe_instrument_array_ref (tp, false);
108  else if (TREE_CODE (*tp) == MODIFY_EXPR)
109    {
110      /* Since r7-1900, we gimplify RHS before LHS.  Consider
111	   a[b] |= c;
112	 wherein we can have a single shared tree a[b] in both LHS and RHS.
113	 If we only instrument the LHS and the access is invalid, the program
114	 could crash before emitting a UBSan error.  So instrument the RHS
115	 first.  */
116      *walk_subtrees = 0;
117      walk_tree (&TREE_OPERAND (*tp, 1), ubsan_walk_array_refs_r, pset, pset);
118      walk_tree (&TREE_OPERAND (*tp, 0), ubsan_walk_array_refs_r, pset, pset);
119    }
120  return NULL_TREE;
121}
122
123/* Gimplification of statement trees.  */
124
125/* Local declarations.  */
126
127enum bc_t { bc_break = 0, bc_continue = 1 };
128
129/* Stack of labels which are targets for "break" or "continue",
130   linked through TREE_CHAIN.  */
131static tree bc_label[2];
132
133/* Begin a scope which can be exited by a break or continue statement.  BC
134   indicates which.
135
136   Just creates a label with location LOCATION and pushes it into the current
137   context.  */
138
139static tree
140begin_bc_block (enum bc_t bc, location_t location)
141{
142  tree label = create_artificial_label (location);
143  DECL_CHAIN (label) = bc_label[bc];
144  bc_label[bc] = label;
145  if (bc == bc_break)
146    LABEL_DECL_BREAK (label) = true;
147  else
148    LABEL_DECL_CONTINUE (label) = true;
149  return label;
150}
151
152/* Finish a scope which can be exited by a break or continue statement.
153   LABEL was returned from the most recent call to begin_bc_block.  BLOCK is
154   an expression for the contents of the scope.
155
156   If we saw a break (or continue) in the scope, append a LABEL_EXPR to
157   BLOCK.  Otherwise, just forget the label.  */
158
159static void
160finish_bc_block (tree *block, enum bc_t bc, tree label)
161{
162  gcc_assert (label == bc_label[bc]);
163
164  if (TREE_USED (label))
165    append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label),
166			      block);
167
168  bc_label[bc] = DECL_CHAIN (label);
169  DECL_CHAIN (label) = NULL_TREE;
170}
171
172/* Allow saving and restoring break/continue state.  */
173
174void
175save_bc_state (bc_state_t *state)
176{
177  state->bc_label[bc_break] = bc_label[bc_break];
178  state->bc_label[bc_continue] = bc_label[bc_continue];
179  bc_label[bc_break] = NULL_TREE;
180  bc_label[bc_continue] = NULL_TREE;
181}
182
183void
184restore_bc_state (bc_state_t *state)
185{
186  gcc_assert (bc_label[bc_break] == NULL);
187  gcc_assert (bc_label[bc_continue] == NULL);
188  bc_label[bc_break] = state->bc_label[bc_break];
189  bc_label[bc_continue] = state->bc_label[bc_continue];
190}
191
192/* Get the LABEL_EXPR to represent a break or continue statement
193   in the current block scope.  BC indicates which.  */
194
195static tree
196get_bc_label (enum bc_t bc)
197{
198  tree label = bc_label[bc];
199  gcc_assert (label);
200
201  /* Mark the label used for finish_bc_block.  */
202  TREE_USED (label) = 1;
203  return label;
204}
205
206/* Return the location from EXPR, or OR_LOC if the former is unknown.  */
207
208location_t
209expr_loc_or_loc (const_tree expr, location_t or_loc)
210{
211  tree t = CONST_CAST_TREE (expr);
212  location_t loc = UNKNOWN_LOCATION;
213  if (t)
214    loc = EXPR_LOCATION (t);
215  if (loc == UNKNOWN_LOCATION)
216    loc = or_loc;
217  return loc;
218}
219
220/* Build a generic representation of one of the C loop forms.  COND is the
221   loop condition or NULL_TREE.  BODY is the (possibly compound) statement
222   controlled by the loop.  INCR is the increment expression of a for-loop,
223   or NULL_TREE.  COND_IS_FIRST indicates whether the condition is
224   evaluated before the loop body as in while and for loops, or after the
225   loop body as in do-while loops.  */
226
227static void
228genericize_c_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
229		   tree incr, bool cond_is_first, int *walk_subtrees,
230		   void *data, walk_tree_fn func, walk_tree_lh lh)
231{
232  tree blab, clab;
233  tree entry = NULL, exit = NULL, t;
234  tree stmt_list = NULL;
235  location_t cond_locus = expr_loc_or_loc (cond, start_locus);
236  location_t incr_locus = expr_loc_or_loc (incr, start_locus);
237
238  protected_set_expr_location_if_unset (incr, start_locus);
239
240  walk_tree_1 (&cond, func, data, NULL, lh);
241  walk_tree_1 (&incr, func, data, NULL, lh);
242
243  blab = begin_bc_block (bc_break, start_locus);
244  clab = begin_bc_block (bc_continue, start_locus);
245
246  walk_tree_1 (&body, func, data, NULL, lh);
247  *walk_subtrees = 0;
248
249  /* If condition is zero don't generate a loop construct.  */
250  if (cond && integer_zerop (cond))
251    {
252      if (cond_is_first)
253	{
254	  t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
255			  get_bc_label (bc_break));
256	  append_to_statement_list (t, &stmt_list);
257	}
258    }
259  else
260    {
261      /* Expand to gotos.  */
262      tree top = build1 (LABEL_EXPR, void_type_node,
263			 create_artificial_label (start_locus));
264
265      /* If we have an exit condition, then we build an IF with gotos either
266	 out of the loop, or to the top of it.  If there's no exit condition,
267	 then we just build a jump back to the top.  */
268      exit = build1 (GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL (top));
269
270      if (cond && !integer_nonzerop (cond))
271	{
272	  /* Canonicalize the loop condition to the end.  This means
273	     generating a branch to the loop condition.  Reuse the
274	     continue label, if there is no incr expression.  */
275	  if (cond_is_first)
276	    {
277	      if (incr)
278		{
279		  entry = build1 (LABEL_EXPR, void_type_node,
280				  create_artificial_label (start_locus));
281		  t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
282				  LABEL_EXPR_LABEL (entry));
283		}
284	      else
285		t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
286				get_bc_label (bc_continue));
287	      append_to_statement_list (t, &stmt_list);
288	    }
289
290	  t = build1 (GOTO_EXPR, void_type_node, get_bc_label (bc_break));
291	  exit = fold_build3_loc (cond_locus,
292				  COND_EXPR, void_type_node, cond, exit, t);
293	}
294      else
295	{
296	  /* For the backward-goto's location of an unconditional loop
297	     use the beginning of the body, or, if there is none, the
298	     top of the loop.  */
299	  location_t loc = expr_loc_or_loc (expr_first (body),
300					    start_locus);
301	  SET_EXPR_LOCATION (exit, loc);
302	}
303      append_to_statement_list (top, &stmt_list);
304    }
305
306  append_to_statement_list (body, &stmt_list);
307  finish_bc_block (&stmt_list, bc_continue, clab);
308  if (incr)
309    {
310      if (MAY_HAVE_DEBUG_MARKER_STMTS && incr_locus != UNKNOWN_LOCATION)
311	{
312	  tree d = build0 (DEBUG_BEGIN_STMT, void_type_node);
313	  SET_EXPR_LOCATION (d, expr_loc_or_loc (incr, start_locus));
314	  append_to_statement_list (d, &stmt_list);
315	}
316      append_to_statement_list (incr, &stmt_list);
317    }
318  append_to_statement_list (entry, &stmt_list);
319
320  if (MAY_HAVE_DEBUG_MARKER_STMTS && cond_locus != UNKNOWN_LOCATION)
321    {
322      tree d = build0 (DEBUG_BEGIN_STMT, void_type_node);
323      SET_EXPR_LOCATION (d, cond_locus);
324      append_to_statement_list (d, &stmt_list);
325    }
326  append_to_statement_list (exit, &stmt_list);
327  finish_bc_block (&stmt_list, bc_break, blab);
328  if (!stmt_list)
329    stmt_list = build_empty_stmt (start_locus);
330
331  *stmt_p = stmt_list;
332}
333
334/* Genericize a FOR_STMT node *STMT_P.  */
335
336static void
337genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data,
338		     walk_tree_fn func, walk_tree_lh lh)
339{
340  tree stmt = *stmt_p;
341  tree expr = NULL;
342  tree loop;
343  tree init = FOR_INIT_STMT (stmt);
344
345  if (init)
346    {
347      walk_tree_1 (&init, func, data, NULL, lh);
348      append_to_statement_list (init, &expr);
349    }
350
351  genericize_c_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
352		     FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees,
353		     data, func, lh);
354  append_to_statement_list (loop, &expr);
355  if (expr == NULL_TREE)
356    expr = loop;
357  *stmt_p = expr;
358}
359
360/* Genericize a WHILE_STMT node *STMT_P.  */
361
362static void
363genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data,
364		       walk_tree_fn func, walk_tree_lh lh)
365{
366  tree stmt = *stmt_p;
367  genericize_c_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt),
368		     WHILE_BODY (stmt), NULL_TREE, 1, walk_subtrees,
369		     data, func, lh);
370}
371
372/* Genericize a DO_STMT node *STMT_P.  */
373
374static void
375genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data,
376		    walk_tree_fn func, walk_tree_lh lh)
377{
378  tree stmt = *stmt_p;
379  genericize_c_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt),
380		     DO_BODY (stmt), NULL_TREE, 0, walk_subtrees,
381		     data, func, lh);
382}
383
384/* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR.  */
385
386static void
387genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data,
388			walk_tree_fn func, walk_tree_lh lh)
389{
390  tree stmt = *stmt_p;
391  tree break_block, body, cond, type;
392  location_t stmt_locus = EXPR_LOCATION (stmt);
393
394  body = SWITCH_STMT_BODY (stmt);
395  if (!body)
396    body = build_empty_stmt (stmt_locus);
397  cond = SWITCH_STMT_COND (stmt);
398  type = SWITCH_STMT_TYPE (stmt);
399
400  walk_tree_1 (&cond, func, data, NULL, lh);
401
402  break_block = begin_bc_block (bc_break, stmt_locus);
403
404  walk_tree_1 (&body, func, data, NULL, lh);
405  walk_tree_1 (&type, func, data, NULL, lh);
406  *walk_subtrees = 0;
407
408  if (TREE_USED (break_block))
409    SWITCH_BREAK_LABEL_P (break_block) = 1;
410  finish_bc_block (&body, bc_break, break_block);
411  *stmt_p = build2_loc (stmt_locus, SWITCH_EXPR, type, cond, body);
412  SWITCH_ALL_CASES_P (*stmt_p) = SWITCH_STMT_ALL_CASES_P (stmt);
413  gcc_checking_assert (!SWITCH_STMT_NO_BREAK_P (stmt)
414		       || !TREE_USED (break_block));
415}
416
417/* Genericize a CONTINUE_STMT node *STMT_P.  */
418
419static void
420genericize_continue_stmt (tree *stmt_p)
421{
422  tree stmt_list = NULL;
423  tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN);
424  tree label = get_bc_label (bc_continue);
425  location_t location = EXPR_LOCATION (*stmt_p);
426  tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label);
427  append_to_statement_list_force (pred, &stmt_list);
428  append_to_statement_list (jump, &stmt_list);
429  *stmt_p = stmt_list;
430}
431
432/* Genericize a BREAK_STMT node *STMT_P.  */
433
434static void
435genericize_break_stmt (tree *stmt_p)
436{
437  tree label = get_bc_label (bc_break);
438  location_t location = EXPR_LOCATION (*stmt_p);
439  *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label);
440}
441
442/* Genericize a OMP_FOR node *STMT_P.  */
443
444static void
445genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data,
446			 walk_tree_fn func, walk_tree_lh lh)
447{
448  tree stmt = *stmt_p;
449  location_t locus = EXPR_LOCATION (stmt);
450  tree clab = begin_bc_block (bc_continue, locus);
451
452  walk_tree_1 (&OMP_FOR_BODY (stmt), func, data, NULL, lh);
453  if (TREE_CODE (stmt) != OMP_TASKLOOP)
454    walk_tree_1 (&OMP_FOR_CLAUSES (stmt), func, data, NULL, lh);
455  walk_tree_1 (&OMP_FOR_INIT (stmt), func, data, NULL, lh);
456  walk_tree_1 (&OMP_FOR_COND (stmt), func, data, NULL, lh);
457  walk_tree_1 (&OMP_FOR_INCR (stmt), func, data, NULL, lh);
458  walk_tree_1 (&OMP_FOR_PRE_BODY (stmt), func, data, NULL, lh);
459  *walk_subtrees = 0;
460
461  finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab);
462}
463
464
465/* Lower structured control flow tree nodes, such as loops.  The
466   STMT_P, WALK_SUBTREES, and DATA arguments are as for the walk_tree_fn
467   type.  FUNC and LH are language-specific functions passed to walk_tree_1
468   for node visiting and traversal, respectively; they are used to do
469   subtree processing in a language-dependent way.  */
470
471tree
472c_genericize_control_stmt (tree *stmt_p, int *walk_subtrees, void *data,
473			   walk_tree_fn func, walk_tree_lh lh)
474{
475  tree stmt = *stmt_p;
476
477  switch (TREE_CODE (stmt))
478    {
479    case FOR_STMT:
480      genericize_for_stmt (stmt_p, walk_subtrees, data, func, lh);
481      break;
482
483    case WHILE_STMT:
484      genericize_while_stmt (stmt_p, walk_subtrees, data, func, lh);
485      break;
486
487    case DO_STMT:
488      genericize_do_stmt (stmt_p, walk_subtrees, data, func, lh);
489      break;
490
491    case SWITCH_STMT:
492      genericize_switch_stmt (stmt_p, walk_subtrees, data, func, lh);
493      break;
494
495    case CONTINUE_STMT:
496      genericize_continue_stmt (stmt_p);
497      break;
498
499    case BREAK_STMT:
500      genericize_break_stmt (stmt_p);
501      break;
502
503    case OMP_FOR:
504    case OMP_SIMD:
505    case OMP_DISTRIBUTE:
506    case OMP_LOOP:
507    case OMP_TASKLOOP:
508    case OACC_LOOP:
509      genericize_omp_for_stmt (stmt_p, walk_subtrees, data, func, lh);
510      break;
511
512    case STATEMENT_LIST:
513      if (TREE_SIDE_EFFECTS (stmt))
514	{
515	  tree_stmt_iterator i;
516	  int nondebug_stmts = 0;
517	  bool clear_side_effects = true;
518	  /* Genericization can clear TREE_SIDE_EFFECTS, e.g. when
519	     transforming an IF_STMT into COND_EXPR.  If such stmt
520	     appears in a STATEMENT_LIST that contains only that
521	     stmt and some DEBUG_BEGIN_STMTs, without -g where the
522	     STATEMENT_LIST wouldn't be present at all the resulting
523	     expression wouldn't have TREE_SIDE_EFFECTS set, so make sure
524	     to clear it even on the STATEMENT_LIST in such cases.  */
525	  hash_set<tree> *pset = (c_dialect_cxx ()
526				  ? nullptr
527				  : static_cast<hash_set<tree> *>(data));
528	  for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i))
529	    {
530	      tree t = tsi_stmt (i);
531	      if (TREE_CODE (t) != DEBUG_BEGIN_STMT && nondebug_stmts < 2)
532		nondebug_stmts++;
533	      walk_tree_1 (tsi_stmt_ptr (i), func, data, pset, lh);
534	      if (TREE_CODE (t) != DEBUG_BEGIN_STMT
535		  && (nondebug_stmts > 1 || TREE_SIDE_EFFECTS (tsi_stmt (i))))
536		clear_side_effects = false;
537	    }
538	  if (clear_side_effects)
539	    TREE_SIDE_EFFECTS (stmt) = 0;
540	  *walk_subtrees = 0;
541	}
542      break;
543
544    default:
545      break;
546    }
547
548  return NULL;
549}
550
551
552/* Wrapper for c_genericize_control_stmt to allow it to be used as a walk_tree
553   callback.  This is appropriate for C; C++ calls c_genericize_control_stmt
554   directly.  */
555
556static tree
557c_genericize_control_r (tree *stmt_p, int *walk_subtrees, void *data)
558{
559  c_genericize_control_stmt (stmt_p, walk_subtrees, data,
560			     c_genericize_control_r, NULL);
561  return NULL;
562}
563
564/* Convert the tree representation of FNDECL from C frontend trees to
565   GENERIC.  */
566
567void
568c_genericize (tree fndecl)
569{
570  FILE *dump_orig;
571  dump_flags_t local_dump_flags;
572  struct cgraph_node *cgn;
573
574  if (flag_sanitize & SANITIZE_BOUNDS)
575    {
576      hash_set<tree> pset;
577      walk_tree (&DECL_SAVED_TREE (fndecl), ubsan_walk_array_refs_r, &pset,
578		 &pset);
579    }
580
581  /* Genericize loops and other structured control constructs.  The C++
582     front end has already done this in lang-specific code.  */
583  if (!c_dialect_cxx ())
584    {
585      bc_state_t save_state;
586      push_cfun (DECL_STRUCT_FUNCTION (fndecl));
587      save_bc_state (&save_state);
588      hash_set<tree> pset;
589      walk_tree (&DECL_SAVED_TREE (fndecl), c_genericize_control_r, &pset,
590		 &pset);
591      restore_bc_state (&save_state);
592      pop_cfun ();
593    }
594
595  if (warn_duplicated_branches)
596    walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
597				  do_warn_duplicated_branches_r, NULL);
598
599  /* Dump the C-specific tree IR.  */
600  dump_orig = get_dump_info (TDI_original, &local_dump_flags);
601  if (dump_orig)
602    {
603      fprintf (dump_orig, "\n;; Function %s",
604	       lang_hooks.decl_printable_name (fndecl, 2));
605      fprintf (dump_orig, " (%s)\n",
606	       (!DECL_ASSEMBLER_NAME_SET_P (fndecl) ? "null"
607		: IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl))));
608      fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original));
609      fprintf (dump_orig, "\n");
610
611      if (local_dump_flags & TDF_RAW)
612	dump_node (DECL_SAVED_TREE (fndecl),
613		   TDF_SLIM | local_dump_flags, dump_orig);
614      else
615	print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl));
616      fprintf (dump_orig, "\n");
617    }
618
619  /* Dump all nested functions now.  */
620  cgn = cgraph_node::get_create (fndecl);
621  for (cgn = first_nested_function (cgn);
622       cgn; cgn = next_nested_function (cgn))
623    c_genericize (cgn->decl);
624}
625
626static void
627add_block_to_enclosing (tree block)
628{
629  unsigned i;
630  tree enclosing;
631  gbind *bind;
632  vec<gbind *> stack = gimple_bind_expr_stack ();
633
634  FOR_EACH_VEC_ELT (stack, i, bind)
635    if (gimple_bind_block (bind))
636      break;
637
638  enclosing = gimple_bind_block (bind);
639  BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
640}
641
642/* Genericize a scope by creating a new BIND_EXPR.
643   BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
644     In the latter case, we need to create a new BLOCK and add it to the
645     BLOCK_SUBBLOCKS of the enclosing block.
646   BODY is a chain of C _STMT nodes for the contents of the scope, to be
647     genericized.  */
648
649tree
650c_build_bind_expr (location_t loc, tree block, tree body)
651{
652  tree decls, bind;
653
654  if (block == NULL_TREE)
655    decls = NULL_TREE;
656  else if (TREE_CODE (block) == BLOCK)
657    decls = BLOCK_VARS (block);
658  else
659    {
660      decls = block;
661      if (DECL_ARTIFICIAL (decls))
662	block = NULL_TREE;
663      else
664	{
665	  block = make_node (BLOCK);
666	  BLOCK_VARS (block) = decls;
667	  add_block_to_enclosing (block);
668	}
669    }
670
671  if (!body)
672    body = build_empty_stmt (loc);
673  if (decls || block)
674    {
675      bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
676      TREE_SIDE_EFFECTS (bind) = 1;
677      SET_EXPR_LOCATION (bind, loc);
678    }
679  else
680    bind = body;
681
682  return bind;
683}
684
685/* Gimplification of expression trees.  */
686
687/* Do C-specific gimplification on *EXPR_P.  PRE_P and POST_P are as in
688   gimplify_expr.  */
689
690int
691c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
692		 gimple_seq *post_p ATTRIBUTE_UNUSED)
693{
694  enum tree_code code = TREE_CODE (*expr_p);
695
696  switch (code)
697    {
698    case LSHIFT_EXPR:
699    case RSHIFT_EXPR:
700    case LROTATE_EXPR:
701    case RROTATE_EXPR:
702      {
703	/* We used to convert the right operand of a shift-expression
704	   to an integer_type_node in the FEs.  But it is unnecessary
705	   and not desirable for diagnostics and sanitizers.  We keep
706	   this here to not pessimize the code, but we convert to an
707	   unsigned type, because negative shift counts are undefined
708	   anyway.
709	   We should get rid of this conversion when we have a proper
710	   type demotion/promotion pass.  */
711	tree *op1_p = &TREE_OPERAND (*expr_p, 1);
712	if (!VECTOR_TYPE_P (TREE_TYPE (*op1_p))
713	    && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
714				    unsigned_type_node)
715	    && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
716				    integer_type_node))
717	  /* Make sure to unshare the result, tree sharing is invalid
718	     during gimplification.  */
719	  *op1_p = unshare_expr (convert (unsigned_type_node, *op1_p));
720	break;
721      }
722
723    case PREINCREMENT_EXPR:
724    case PREDECREMENT_EXPR:
725    case POSTINCREMENT_EXPR:
726    case POSTDECREMENT_EXPR:
727      {
728	tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
729	if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type))
730	  {
731	    if (!TYPE_OVERFLOW_WRAPS (type))
732	      type = unsigned_type_for (type);
733	    return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type);
734	  }
735	break;
736      }
737
738    default:;
739    }
740
741  return GS_UNHANDLED;
742}
743