1/* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
2
3   Copyright (C) 2002-2015 Free Software Foundation, Inc.
4   Contributed by Jason Merrill <jason@redhat.com>
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3.  If not see
20<http://www.gnu.org/licenses/>.  */
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "tm.h"
26#include "hash-set.h"
27#include "machmode.h"
28#include "vec.h"
29#include "double-int.h"
30#include "input.h"
31#include "alias.h"
32#include "symtab.h"
33#include "wide-int.h"
34#include "inchash.h"
35#include "tree.h"
36#include "stor-layout.h"
37#include "cp-tree.h"
38#include "c-family/c-common.h"
39#include "tree-iterator.h"
40#include "predict.h"
41#include "hard-reg-set.h"
42#include "input.h"
43#include "function.h"
44#include "basic-block.h"
45#include "tree-ssa-alias.h"
46#include "internal-fn.h"
47#include "gimple-expr.h"
48#include "is-a.h"
49#include "gimple.h"
50#include "gimplify.h"
51#include "flags.h"
52#include "splay-tree.h"
53#include "target.h"
54#include "c-family/c-ubsan.h"
55#include "cilk.h"
56#include "gimplify.h"
57#include "gimple-expr.h"
58
59/* Forward declarations.  */
60
61static tree cp_genericize_r (tree *, int *, void *);
62static void cp_genericize_tree (tree*);
63
64/* Local declarations.  */
65
66enum bc_t { bc_break = 0, bc_continue = 1 };
67
68/* Stack of labels which are targets for "break" or "continue",
69   linked through TREE_CHAIN.  */
70static tree bc_label[2];
71
72/* Begin a scope which can be exited by a break or continue statement.  BC
73   indicates which.
74
75   Just creates a label with location LOCATION and pushes it into the current
76   context.  */
77
78static tree
79begin_bc_block (enum bc_t bc, location_t location)
80{
81  tree label = create_artificial_label (location);
82  DECL_CHAIN (label) = bc_label[bc];
83  bc_label[bc] = label;
84  if (bc == bc_break)
85    LABEL_DECL_BREAK (label) = true;
86  else
87    LABEL_DECL_CONTINUE (label) = true;
88  return label;
89}
90
91/* Finish a scope which can be exited by a break or continue statement.
92   LABEL was returned from the most recent call to begin_bc_block.  BLOCK is
93   an expression for the contents of the scope.
94
95   If we saw a break (or continue) in the scope, append a LABEL_EXPR to
96   BLOCK.  Otherwise, just forget the label.  */
97
98static void
99finish_bc_block (tree *block, enum bc_t bc, tree label)
100{
101  gcc_assert (label == bc_label[bc]);
102
103  if (TREE_USED (label))
104    append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label),
105			      block);
106
107  bc_label[bc] = DECL_CHAIN (label);
108  DECL_CHAIN (label) = NULL_TREE;
109}
110
111/* Get the LABEL_EXPR to represent a break or continue statement
112   in the current block scope.  BC indicates which.  */
113
114static tree
115get_bc_label (enum bc_t bc)
116{
117  tree label = bc_label[bc];
118
119  /* Mark the label used for finish_bc_block.  */
120  TREE_USED (label) = 1;
121  return label;
122}
123
124/* Genericize a TRY_BLOCK.  */
125
126static void
127genericize_try_block (tree *stmt_p)
128{
129  tree body = TRY_STMTS (*stmt_p);
130  tree cleanup = TRY_HANDLERS (*stmt_p);
131
132  *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
133}
134
135/* Genericize a HANDLER by converting to a CATCH_EXPR.  */
136
137static void
138genericize_catch_block (tree *stmt_p)
139{
140  tree type = HANDLER_TYPE (*stmt_p);
141  tree body = HANDLER_BODY (*stmt_p);
142
143  /* FIXME should the caught type go in TREE_TYPE?  */
144  *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
145}
146
147/* A terser interface for building a representation of an exception
148   specification.  */
149
150static tree
151build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
152{
153  tree t;
154
155  /* FIXME should the allowed types go in TREE_TYPE?  */
156  t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
157  append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
158
159  t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
160  append_to_statement_list (body, &TREE_OPERAND (t, 0));
161
162  return t;
163}
164
165/* Genericize an EH_SPEC_BLOCK by converting it to a
166   TRY_CATCH_EXPR/EH_FILTER_EXPR pair.  */
167
168static void
169genericize_eh_spec_block (tree *stmt_p)
170{
171  tree body = EH_SPEC_STMTS (*stmt_p);
172  tree allowed = EH_SPEC_RAISES (*stmt_p);
173  tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ());
174
175  *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
176  TREE_NO_WARNING (*stmt_p) = true;
177  TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true;
178}
179
180/* Genericize an IF_STMT by turning it into a COND_EXPR.  */
181
182static void
183genericize_if_stmt (tree *stmt_p)
184{
185  tree stmt, cond, then_, else_;
186  location_t locus = EXPR_LOCATION (*stmt_p);
187
188  stmt = *stmt_p;
189  cond = IF_COND (stmt);
190  then_ = THEN_CLAUSE (stmt);
191  else_ = ELSE_CLAUSE (stmt);
192
193  if (!then_)
194    then_ = build_empty_stmt (locus);
195  if (!else_)
196    else_ = build_empty_stmt (locus);
197
198  if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
199    stmt = then_;
200  else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
201    stmt = else_;
202  else
203    stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
204  if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt))
205    SET_EXPR_LOCATION (stmt, locus);
206  *stmt_p = stmt;
207}
208
209/* Build a generic representation of one of the C loop forms.  COND is the
210   loop condition or NULL_TREE.  BODY is the (possibly compound) statement
211   controlled by the loop.  INCR is the increment expression of a for-loop,
212   or NULL_TREE.  COND_IS_FIRST indicates whether the condition is
213   evaluated before the loop body as in while and for loops, or after the
214   loop body as in do-while loops.  */
215
216static void
217genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
218		    tree incr, bool cond_is_first, int *walk_subtrees,
219		    void *data)
220{
221  tree blab, clab;
222  tree exit = NULL;
223  tree stmt_list = NULL;
224
225  blab = begin_bc_block (bc_break, start_locus);
226  clab = begin_bc_block (bc_continue, start_locus);
227
228  if (incr && EXPR_P (incr))
229    SET_EXPR_LOCATION (incr, start_locus);
230
231  cp_walk_tree (&cond, cp_genericize_r, data, NULL);
232  cp_walk_tree (&body, cp_genericize_r, data, NULL);
233  cp_walk_tree (&incr, cp_genericize_r, data, NULL);
234  *walk_subtrees = 0;
235
236  if (cond && TREE_CODE (cond) != INTEGER_CST)
237    {
238      /* If COND is constant, don't bother building an exit.  If it's false,
239	 we won't build a loop.  If it's true, any exits are in the body.  */
240      location_t cloc = EXPR_LOC_OR_LOC (cond, start_locus);
241      exit = build1_loc (cloc, GOTO_EXPR, void_type_node,
242			 get_bc_label (bc_break));
243      exit = fold_build3_loc (cloc, COND_EXPR, void_type_node, cond,
244			      build_empty_stmt (cloc), exit);
245    }
246
247  if (exit && cond_is_first)
248    append_to_statement_list (exit, &stmt_list);
249  append_to_statement_list (body, &stmt_list);
250  finish_bc_block (&stmt_list, bc_continue, clab);
251  append_to_statement_list (incr, &stmt_list);
252  if (exit && !cond_is_first)
253    append_to_statement_list (exit, &stmt_list);
254
255  if (!stmt_list)
256    stmt_list = build_empty_stmt (start_locus);
257
258  tree loop;
259  if (cond && integer_zerop (cond))
260    {
261      if (cond_is_first)
262	loop = fold_build3_loc (start_locus, COND_EXPR,
263				void_type_node, cond, stmt_list,
264				build_empty_stmt (start_locus));
265      else
266	loop = stmt_list;
267    }
268  else
269    loop = build1_loc (start_locus, LOOP_EXPR, void_type_node, stmt_list);
270
271  stmt_list = NULL;
272  append_to_statement_list (loop, &stmt_list);
273  finish_bc_block (&stmt_list, bc_break, blab);
274  if (!stmt_list)
275    stmt_list = build_empty_stmt (start_locus);
276
277  *stmt_p = stmt_list;
278}
279
280/* Genericize a FOR_STMT node *STMT_P.  */
281
282static void
283genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
284{
285  tree stmt = *stmt_p;
286  tree expr = NULL;
287  tree loop;
288  tree init = FOR_INIT_STMT (stmt);
289
290  if (init)
291    {
292      cp_walk_tree (&init, cp_genericize_r, data, NULL);
293      append_to_statement_list (init, &expr);
294    }
295
296  genericize_cp_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
297		      FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees, data);
298  append_to_statement_list (loop, &expr);
299  if (expr == NULL_TREE)
300    expr = loop;
301  *stmt_p = expr;
302}
303
304/* Genericize a WHILE_STMT node *STMT_P.  */
305
306static void
307genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data)
308{
309  tree stmt = *stmt_p;
310  genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt),
311		      WHILE_BODY (stmt), NULL_TREE, 1, walk_subtrees, data);
312}
313
314/* Genericize a DO_STMT node *STMT_P.  */
315
316static void
317genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data)
318{
319  tree stmt = *stmt_p;
320  genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt),
321		      DO_BODY (stmt), NULL_TREE, 0, walk_subtrees, data);
322}
323
324/* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR.  */
325
326static void
327genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data)
328{
329  tree stmt = *stmt_p;
330  tree break_block, body, cond, type;
331  location_t stmt_locus = EXPR_LOCATION (stmt);
332
333  break_block = begin_bc_block (bc_break, stmt_locus);
334
335  body = SWITCH_STMT_BODY (stmt);
336  if (!body)
337    body = build_empty_stmt (stmt_locus);
338  cond = SWITCH_STMT_COND (stmt);
339  type = SWITCH_STMT_TYPE (stmt);
340
341  cp_walk_tree (&body, cp_genericize_r, data, NULL);
342  cp_walk_tree (&cond, cp_genericize_r, data, NULL);
343  cp_walk_tree (&type, cp_genericize_r, data, NULL);
344  *walk_subtrees = 0;
345
346  *stmt_p = build3_loc (stmt_locus, SWITCH_EXPR, type, cond, body, NULL_TREE);
347  finish_bc_block (stmt_p, bc_break, break_block);
348}
349
350/* Genericize a CONTINUE_STMT node *STMT_P.  */
351
352static void
353genericize_continue_stmt (tree *stmt_p)
354{
355  tree stmt_list = NULL;
356  tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN);
357  tree label = get_bc_label (bc_continue);
358  location_t location = EXPR_LOCATION (*stmt_p);
359  tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label);
360  append_to_statement_list (pred, &stmt_list);
361  append_to_statement_list (jump, &stmt_list);
362  *stmt_p = stmt_list;
363}
364
365/* Genericize a BREAK_STMT node *STMT_P.  */
366
367static void
368genericize_break_stmt (tree *stmt_p)
369{
370  tree label = get_bc_label (bc_break);
371  location_t location = EXPR_LOCATION (*stmt_p);
372  *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label);
373}
374
375/* Genericize a OMP_FOR node *STMT_P.  */
376
377static void
378genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
379{
380  tree stmt = *stmt_p;
381  location_t locus = EXPR_LOCATION (stmt);
382  tree clab = begin_bc_block (bc_continue, locus);
383
384  cp_walk_tree (&OMP_FOR_BODY (stmt), cp_genericize_r, data, NULL);
385  cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_genericize_r, data, NULL);
386  cp_walk_tree (&OMP_FOR_INIT (stmt), cp_genericize_r, data, NULL);
387  cp_walk_tree (&OMP_FOR_COND (stmt), cp_genericize_r, data, NULL);
388  cp_walk_tree (&OMP_FOR_INCR (stmt), cp_genericize_r, data, NULL);
389  cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_genericize_r, data, NULL);
390  *walk_subtrees = 0;
391
392  finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab);
393}
394
395/* Hook into the middle of gimplifying an OMP_FOR node.  */
396
397static enum gimplify_status
398cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
399{
400  tree for_stmt = *expr_p;
401  gimple_seq seq = NULL;
402
403  /* Protect ourselves from recursion.  */
404  if (OMP_FOR_GIMPLIFYING_P (for_stmt))
405    return GS_UNHANDLED;
406  OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
407
408  gimplify_and_add (for_stmt, &seq);
409  gimple_seq_add_seq (pre_p, seq);
410
411  OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
412
413  return GS_ALL_DONE;
414}
415
416/*  Gimplify an EXPR_STMT node.  */
417
418static void
419gimplify_expr_stmt (tree *stmt_p)
420{
421  tree stmt = EXPR_STMT_EXPR (*stmt_p);
422
423  if (stmt == error_mark_node)
424    stmt = NULL;
425
426  /* Gimplification of a statement expression will nullify the
427     statement if all its side effects are moved to *PRE_P and *POST_P.
428
429     In this case we will not want to emit the gimplified statement.
430     However, we may still want to emit a warning, so we do that before
431     gimplification.  */
432  if (stmt && warn_unused_value)
433    {
434      if (!TREE_SIDE_EFFECTS (stmt))
435	{
436	  if (!IS_EMPTY_STMT (stmt)
437	      && !VOID_TYPE_P (TREE_TYPE (stmt))
438	      && !TREE_NO_WARNING (stmt))
439	    warning (OPT_Wunused_value, "statement with no effect");
440	}
441      else
442	warn_if_unused_value (stmt, input_location);
443    }
444
445  if (stmt == NULL_TREE)
446    stmt = alloc_stmt_list ();
447
448  *stmt_p = stmt;
449}
450
451/* Gimplify initialization from an AGGR_INIT_EXPR.  */
452
453static void
454cp_gimplify_init_expr (tree *expr_p)
455{
456  tree from = TREE_OPERAND (*expr_p, 1);
457  tree to = TREE_OPERAND (*expr_p, 0);
458  tree t;
459
460  /* What about code that pulls out the temp and uses it elsewhere?  I
461     think that such code never uses the TARGET_EXPR as an initializer.  If
462     I'm wrong, we'll abort because the temp won't have any RTL.  In that
463     case, I guess we'll need to replace references somehow.  */
464  if (TREE_CODE (from) == TARGET_EXPR)
465    from = TARGET_EXPR_INITIAL (from);
466
467  /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
468     inside the TARGET_EXPR.  */
469  for (t = from; t; )
470    {
471      tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
472
473      /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
474	 replace the slot operand with our target.
475
476	 Should we add a target parm to gimplify_expr instead?  No, as in this
477	 case we want to replace the INIT_EXPR.  */
478      if (TREE_CODE (sub) == AGGR_INIT_EXPR
479	  || TREE_CODE (sub) == VEC_INIT_EXPR)
480	{
481	  if (TREE_CODE (sub) == AGGR_INIT_EXPR)
482	    AGGR_INIT_EXPR_SLOT (sub) = to;
483	  else
484	    VEC_INIT_EXPR_SLOT (sub) = to;
485	  *expr_p = from;
486
487	  /* The initialization is now a side-effect, so the container can
488	     become void.  */
489	  if (from != sub)
490	    TREE_TYPE (from) = void_type_node;
491	}
492
493      if (cxx_dialect >= cxx14 && TREE_CODE (sub) == CONSTRUCTOR)
494	/* Handle aggregate NSDMI.  */
495	replace_placeholders (sub, to);
496
497      if (t == sub)
498	break;
499      else
500	t = TREE_OPERAND (t, 1);
501    }
502
503}
504
505/* Gimplify a MUST_NOT_THROW_EXPR.  */
506
507static enum gimplify_status
508gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
509{
510  tree stmt = *expr_p;
511  tree temp = voidify_wrapper_expr (stmt, NULL);
512  tree body = TREE_OPERAND (stmt, 0);
513  gimple_seq try_ = NULL;
514  gimple_seq catch_ = NULL;
515  gimple mnt;
516
517  gimplify_and_add (body, &try_);
518  mnt = gimple_build_eh_must_not_throw (terminate_node);
519  gimple_seq_add_stmt_without_update (&catch_, mnt);
520  mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
521
522  gimple_seq_add_stmt_without_update (pre_p, mnt);
523  if (temp)
524    {
525      *expr_p = temp;
526      return GS_OK;
527    }
528
529  *expr_p = NULL;
530  return GS_ALL_DONE;
531}
532
533/* Return TRUE if an operand (OP) of a given TYPE being copied is
534   really just an empty class copy.
535
536   Check that the operand has a simple form so that TARGET_EXPRs and
537   non-empty CONSTRUCTORs get reduced properly, and we leave the
538   return slot optimization alone because it isn't a copy.  */
539
540static bool
541simple_empty_class_p (tree type, tree op)
542{
543  return
544    ((TREE_CODE (op) == COMPOUND_EXPR
545      && simple_empty_class_p (type, TREE_OPERAND (op, 1)))
546     || is_gimple_lvalue (op)
547     || INDIRECT_REF_P (op)
548     || (TREE_CODE (op) == CONSTRUCTOR
549	 && CONSTRUCTOR_NELTS (op) == 0
550	 && !TREE_CLOBBER_P (op))
551     || (TREE_CODE (op) == CALL_EXPR
552	 && !CALL_EXPR_RETURN_SLOT_OPT (op)))
553    && is_really_empty_class (type);
554}
555
556/* Do C++-specific gimplification.  Args are as for gimplify_expr.  */
557
558int
559cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
560{
561  int saved_stmts_are_full_exprs_p = 0;
562  enum tree_code code = TREE_CODE (*expr_p);
563  enum gimplify_status ret;
564
565  if (STATEMENT_CODE_P (code))
566    {
567      saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
568      current_stmt_tree ()->stmts_are_full_exprs_p
569	= STMT_IS_FULL_EXPR_P (*expr_p);
570    }
571
572  switch (code)
573    {
574    case PTRMEM_CST:
575      *expr_p = cplus_expand_constant (*expr_p);
576      ret = GS_OK;
577      break;
578
579    case AGGR_INIT_EXPR:
580      simplify_aggr_init_expr (expr_p);
581      ret = GS_OK;
582      break;
583
584    case VEC_INIT_EXPR:
585      {
586	location_t loc = input_location;
587	tree init = VEC_INIT_EXPR_INIT (*expr_p);
588	int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
589	gcc_assert (EXPR_HAS_LOCATION (*expr_p));
590	input_location = EXPR_LOCATION (*expr_p);
591	*expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
592				  init, VEC_INIT_EXPR_VALUE_INIT (*expr_p),
593				  from_array,
594				  tf_warning_or_error);
595	cp_genericize_tree (expr_p);
596	ret = GS_OK;
597	input_location = loc;
598      }
599      break;
600
601    case THROW_EXPR:
602      /* FIXME communicate throw type to back end, probably by moving
603	 THROW_EXPR into ../tree.def.  */
604      *expr_p = TREE_OPERAND (*expr_p, 0);
605      ret = GS_OK;
606      break;
607
608    case MUST_NOT_THROW_EXPR:
609      ret = gimplify_must_not_throw_expr (expr_p, pre_p);
610      break;
611
612      /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
613	 LHS of an assignment might also be involved in the RHS, as in bug
614	 25979.  */
615    case INIT_EXPR:
616      if (fn_contains_cilk_spawn_p (cfun)
617	  && cilk_detect_spawn_and_unwrap (expr_p)
618	  && !seen_error ())
619	return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
620      cp_gimplify_init_expr (expr_p);
621      if (TREE_CODE (*expr_p) != INIT_EXPR)
622	return GS_OK;
623      /* Otherwise fall through.  */
624    case MODIFY_EXPR:
625    modify_expr_case:
626      {
627	if (fn_contains_cilk_spawn_p (cfun)
628	    && cilk_detect_spawn_and_unwrap (expr_p)
629	    && !seen_error ())
630	  return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
631
632	/* If the back end isn't clever enough to know that the lhs and rhs
633	   types are the same, add an explicit conversion.  */
634	tree op0 = TREE_OPERAND (*expr_p, 0);
635	tree op1 = TREE_OPERAND (*expr_p, 1);
636
637	if (!error_operand_p (op0)
638	    && !error_operand_p (op1)
639	    && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
640		|| TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
641	    && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
642	  TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
643					      TREE_TYPE (op0), op1);
644
645	else if (simple_empty_class_p (TREE_TYPE (op0), op1))
646	  {
647	    /* Remove any copies of empty classes.  Also drop volatile
648	       variables on the RHS to avoid infinite recursion from
649	       gimplify_expr trying to load the value.  */
650	    gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
651			   is_gimple_lvalue, fb_lvalue);
652	    if (TREE_SIDE_EFFECTS (op1))
653	      {
654		if (TREE_THIS_VOLATILE (op1)
655		    && (REFERENCE_CLASS_P (op1) || DECL_P (op1)))
656		  op1 = build_fold_addr_expr (op1);
657
658		gimplify_and_add (op1, pre_p);
659	      }
660	    *expr_p = TREE_OPERAND (*expr_p, 0);
661	  }
662      }
663      ret = GS_OK;
664      break;
665
666    case EMPTY_CLASS_EXPR:
667      /* We create an empty CONSTRUCTOR with RECORD_TYPE.  */
668      *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
669      ret = GS_OK;
670      break;
671
672    case BASELINK:
673      *expr_p = BASELINK_FUNCTIONS (*expr_p);
674      ret = GS_OK;
675      break;
676
677    case TRY_BLOCK:
678      genericize_try_block (expr_p);
679      ret = GS_OK;
680      break;
681
682    case HANDLER:
683      genericize_catch_block (expr_p);
684      ret = GS_OK;
685      break;
686
687    case EH_SPEC_BLOCK:
688      genericize_eh_spec_block (expr_p);
689      ret = GS_OK;
690      break;
691
692    case USING_STMT:
693      gcc_unreachable ();
694
695    case FOR_STMT:
696    case WHILE_STMT:
697    case DO_STMT:
698    case SWITCH_STMT:
699    case CONTINUE_STMT:
700    case BREAK_STMT:
701      gcc_unreachable ();
702
703    case OMP_FOR:
704    case OMP_SIMD:
705    case OMP_DISTRIBUTE:
706      ret = cp_gimplify_omp_for (expr_p, pre_p);
707      break;
708
709    case EXPR_STMT:
710      gimplify_expr_stmt (expr_p);
711      ret = GS_OK;
712      break;
713
714    case UNARY_PLUS_EXPR:
715      {
716	tree arg = TREE_OPERAND (*expr_p, 0);
717	tree type = TREE_TYPE (*expr_p);
718	*expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
719					    : arg;
720	ret = GS_OK;
721      }
722      break;
723
724    case CILK_SPAWN_STMT:
725      gcc_assert
726	(fn_contains_cilk_spawn_p (cfun)
727	 && cilk_detect_spawn_and_unwrap (expr_p));
728
729      /* If errors are seen, then just process it as a CALL_EXPR.  */
730      if (!seen_error ())
731	return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
732
733    case CALL_EXPR:
734      if (fn_contains_cilk_spawn_p (cfun)
735	  && cilk_detect_spawn_and_unwrap (expr_p)
736	  && !seen_error ())
737	return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
738
739      /* DR 1030 says that we need to evaluate the elements of an
740	 initializer-list in forward order even when it's used as arguments to
741	 a constructor.  So if the target wants to evaluate them in reverse
742	 order and there's more than one argument other than 'this', gimplify
743	 them in order.  */
744      ret = GS_OK;
745      if (PUSH_ARGS_REVERSED && CALL_EXPR_LIST_INIT_P (*expr_p)
746	  && call_expr_nargs (*expr_p) > 2)
747	{
748	  int nargs = call_expr_nargs (*expr_p);
749	  location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location);
750	  for (int i = 1; i < nargs; ++i)
751	    {
752	      enum gimplify_status t
753		= gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc);
754	      if (t == GS_ERROR)
755		ret = GS_ERROR;
756	    }
757	}
758      break;
759
760    case RETURN_EXPR:
761      if (TREE_OPERAND (*expr_p, 0)
762	  && (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == INIT_EXPR
763	      || TREE_CODE (TREE_OPERAND (*expr_p, 0)) == MODIFY_EXPR))
764	{
765	  expr_p = &TREE_OPERAND (*expr_p, 0);
766	  code = TREE_CODE (*expr_p);
767	  /* Avoid going through the INIT_EXPR case, which can
768	     degrade INIT_EXPRs into AGGR_INIT_EXPRs.  */
769	  goto modify_expr_case;
770	}
771      /* Fall through.  */
772
773    default:
774      ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
775      break;
776    }
777
778  /* Restore saved state.  */
779  if (STATEMENT_CODE_P (code))
780    current_stmt_tree ()->stmts_are_full_exprs_p
781      = saved_stmts_are_full_exprs_p;
782
783  return ret;
784}
785
786static inline bool
787is_invisiref_parm (const_tree t)
788{
789  return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
790	  && DECL_BY_REFERENCE (t));
791}
792
793/* Return true if the uid in both int tree maps are equal.  */
794
795bool
796cxx_int_tree_map_hasher::equal (cxx_int_tree_map *a, cxx_int_tree_map *b)
797{
798  return (a->uid == b->uid);
799}
800
801/* Hash a UID in a cxx_int_tree_map.  */
802
803unsigned int
804cxx_int_tree_map_hasher::hash (cxx_int_tree_map *item)
805{
806  return item->uid;
807}
808
809/* A stable comparison routine for use with splay trees and DECLs.  */
810
811static int
812splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
813{
814  tree a = (tree) xa;
815  tree b = (tree) xb;
816
817  return DECL_UID (a) - DECL_UID (b);
818}
819
820/* OpenMP context during genericization.  */
821
822struct cp_genericize_omp_taskreg
823{
824  bool is_parallel;
825  bool default_shared;
826  struct cp_genericize_omp_taskreg *outer;
827  splay_tree variables;
828};
829
830/* Return true if genericization should try to determine if
831   DECL is firstprivate or shared within task regions.  */
832
833static bool
834omp_var_to_track (tree decl)
835{
836  tree type = TREE_TYPE (decl);
837  if (is_invisiref_parm (decl))
838    type = TREE_TYPE (type);
839  while (TREE_CODE (type) == ARRAY_TYPE)
840    type = TREE_TYPE (type);
841  if (type == error_mark_node || !CLASS_TYPE_P (type))
842    return false;
843  if (VAR_P (decl) && DECL_THREAD_LOCAL_P (decl))
844    return false;
845  if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
846    return false;
847  return true;
848}
849
850/* Note DECL use in OpenMP region OMP_CTX during genericization.  */
851
852static void
853omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl)
854{
855  splay_tree_node n = splay_tree_lookup (omp_ctx->variables,
856					 (splay_tree_key) decl);
857  if (n == NULL)
858    {
859      int flags = OMP_CLAUSE_DEFAULT_SHARED;
860      if (omp_ctx->outer)
861	omp_cxx_notice_variable (omp_ctx->outer, decl);
862      if (!omp_ctx->default_shared)
863	{
864	  struct cp_genericize_omp_taskreg *octx;
865
866	  for (octx = omp_ctx->outer; octx; octx = octx->outer)
867	    {
868	      n = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
869	      if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED)
870		{
871		  flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
872		  break;
873		}
874	      if (octx->is_parallel)
875		break;
876	    }
877	  if (octx == NULL
878	      && (TREE_CODE (decl) == PARM_DECL
879		  || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl))
880		      && DECL_CONTEXT (decl) == current_function_decl)))
881	    flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
882	  if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
883	    {
884	      /* DECL is implicitly determined firstprivate in
885		 the current task construct.  Ensure copy ctor and
886		 dtor are instantiated, because during gimplification
887		 it will be already too late.  */
888	      tree type = TREE_TYPE (decl);
889	      if (is_invisiref_parm (decl))
890		type = TREE_TYPE (type);
891	      while (TREE_CODE (type) == ARRAY_TYPE)
892		type = TREE_TYPE (type);
893	      get_copy_ctor (type, tf_none);
894	      get_dtor (type, tf_none);
895	    }
896	}
897      splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags);
898    }
899}
900
901/* Genericization context.  */
902
903struct cp_genericize_data
904{
905  hash_set<tree> *p_set;
906  vec<tree> bind_expr_stack;
907  struct cp_genericize_omp_taskreg *omp_ctx;
908  bool no_sanitize_p;
909};
910
911/* Perform any pre-gimplification lowering of C++ front end trees to
912   GENERIC.  */
913
914static tree
915cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
916{
917  tree stmt = *stmt_p;
918  struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
919  hash_set<tree> *p_set = wtd->p_set;
920
921  /* If in an OpenMP context, note var uses.  */
922  if (__builtin_expect (wtd->omp_ctx != NULL, 0)
923      && (VAR_P (stmt)
924	  || TREE_CODE (stmt) == PARM_DECL
925	  || TREE_CODE (stmt) == RESULT_DECL)
926      && omp_var_to_track (stmt))
927    omp_cxx_notice_variable (wtd->omp_ctx, stmt);
928
929  if (is_invisiref_parm (stmt)
930      /* Don't dereference parms in a thunk, pass the references through. */
931      && !(DECL_THUNK_P (current_function_decl)
932	   && TREE_CODE (stmt) == PARM_DECL))
933    {
934      *stmt_p = convert_from_reference (stmt);
935      *walk_subtrees = 0;
936      return NULL;
937    }
938
939  /* Map block scope extern declarations to visible declarations with the
940     same name and type in outer scopes if any.  */
941  if (cp_function_chain->extern_decl_map
942      && VAR_OR_FUNCTION_DECL_P (stmt)
943      && DECL_EXTERNAL (stmt))
944    {
945      struct cxx_int_tree_map *h, in;
946      in.uid = DECL_UID (stmt);
947      h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid);
948      if (h)
949	{
950	  *stmt_p = h->to;
951	  *walk_subtrees = 0;
952	  return NULL;
953	}
954    }
955
956  /* Other than invisiref parms, don't walk the same tree twice.  */
957  if (p_set->contains (stmt))
958    {
959      *walk_subtrees = 0;
960      return NULL_TREE;
961    }
962
963  if (TREE_CODE (stmt) == ADDR_EXPR
964      && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
965    {
966      /* If in an OpenMP context, note var uses.  */
967      if (__builtin_expect (wtd->omp_ctx != NULL, 0)
968	  && omp_var_to_track (TREE_OPERAND (stmt, 0)))
969	omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
970      *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
971      *walk_subtrees = 0;
972    }
973  else if (TREE_CODE (stmt) == RETURN_EXPR
974	   && TREE_OPERAND (stmt, 0)
975	   && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
976    /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR.  */
977    *walk_subtrees = 0;
978  else if (TREE_CODE (stmt) == OMP_CLAUSE)
979    switch (OMP_CLAUSE_CODE (stmt))
980      {
981      case OMP_CLAUSE_LASTPRIVATE:
982	/* Don't dereference an invisiref in OpenMP clauses.  */
983	if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
984	  {
985	    *walk_subtrees = 0;
986	    if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
987	      cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
988			    cp_genericize_r, data, NULL);
989	  }
990	break;
991      case OMP_CLAUSE_PRIVATE:
992	/* Don't dereference an invisiref in OpenMP clauses.  */
993	if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
994	  *walk_subtrees = 0;
995	else if (wtd->omp_ctx != NULL)
996	  {
997	    /* Private clause doesn't cause any references to the
998	       var in outer contexts, avoid calling
999	       omp_cxx_notice_variable for it.  */
1000	    struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
1001	    wtd->omp_ctx = NULL;
1002	    cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
1003			  data, NULL);
1004	    wtd->omp_ctx = old;
1005	    *walk_subtrees = 0;
1006	  }
1007	break;
1008      case OMP_CLAUSE_SHARED:
1009      case OMP_CLAUSE_FIRSTPRIVATE:
1010      case OMP_CLAUSE_COPYIN:
1011      case OMP_CLAUSE_COPYPRIVATE:
1012	/* Don't dereference an invisiref in OpenMP clauses.  */
1013	if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1014	  *walk_subtrees = 0;
1015	break;
1016      case OMP_CLAUSE_REDUCTION:
1017	/* Don't dereference an invisiref in reduction clause's
1018	   OMP_CLAUSE_DECL either.  OMP_CLAUSE_REDUCTION_{INIT,MERGE}
1019	   still needs to be genericized.  */
1020	if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1021	  {
1022	    *walk_subtrees = 0;
1023	    if (OMP_CLAUSE_REDUCTION_INIT (stmt))
1024	      cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
1025			    cp_genericize_r, data, NULL);
1026	    if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
1027	      cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
1028			    cp_genericize_r, data, NULL);
1029	  }
1030	break;
1031      default:
1032	break;
1033      }
1034  else if (IS_TYPE_OR_DECL_P (stmt))
1035    *walk_subtrees = 0;
1036
1037  /* Due to the way voidify_wrapper_expr is written, we don't get a chance
1038     to lower this construct before scanning it, so we need to lower these
1039     before doing anything else.  */
1040  else if (TREE_CODE (stmt) == CLEANUP_STMT)
1041    *stmt_p = build2_loc (EXPR_LOCATION (stmt),
1042			  CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
1043						 : TRY_FINALLY_EXPR,
1044			  void_type_node,
1045			  CLEANUP_BODY (stmt),
1046			  CLEANUP_EXPR (stmt));
1047
1048  else if (TREE_CODE (stmt) == IF_STMT)
1049    {
1050      genericize_if_stmt (stmt_p);
1051      /* *stmt_p has changed, tail recurse to handle it again.  */
1052      return cp_genericize_r (stmt_p, walk_subtrees, data);
1053    }
1054
1055  /* COND_EXPR might have incompatible types in branches if one or both
1056     arms are bitfields.  Fix it up now.  */
1057  else if (TREE_CODE (stmt) == COND_EXPR)
1058    {
1059      tree type_left
1060	= (TREE_OPERAND (stmt, 1)
1061	   ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
1062	   : NULL_TREE);
1063      tree type_right
1064	= (TREE_OPERAND (stmt, 2)
1065	   ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
1066	   : NULL_TREE);
1067      if (type_left
1068	  && !useless_type_conversion_p (TREE_TYPE (stmt),
1069					 TREE_TYPE (TREE_OPERAND (stmt, 1))))
1070	{
1071	  TREE_OPERAND (stmt, 1)
1072	    = fold_convert (type_left, TREE_OPERAND (stmt, 1));
1073	  gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1074						 type_left));
1075	}
1076      if (type_right
1077	  && !useless_type_conversion_p (TREE_TYPE (stmt),
1078					 TREE_TYPE (TREE_OPERAND (stmt, 2))))
1079	{
1080	  TREE_OPERAND (stmt, 2)
1081	    = fold_convert (type_right, TREE_OPERAND (stmt, 2));
1082	  gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1083						 type_right));
1084	}
1085    }
1086
1087  else if (TREE_CODE (stmt) == BIND_EXPR)
1088    {
1089      if (__builtin_expect (wtd->omp_ctx != NULL, 0))
1090	{
1091	  tree decl;
1092	  for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
1093	    if (VAR_P (decl)
1094		&& !DECL_EXTERNAL (decl)
1095		&& omp_var_to_track (decl))
1096	      {
1097		splay_tree_node n
1098		  = splay_tree_lookup (wtd->omp_ctx->variables,
1099				       (splay_tree_key) decl);
1100		if (n == NULL)
1101		  splay_tree_insert (wtd->omp_ctx->variables,
1102				     (splay_tree_key) decl,
1103				     TREE_STATIC (decl)
1104				     ? OMP_CLAUSE_DEFAULT_SHARED
1105				     : OMP_CLAUSE_DEFAULT_PRIVATE);
1106	      }
1107	}
1108      if (flag_sanitize
1109	  & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
1110	{
1111	  /* The point here is to not sanitize static initializers.  */
1112	  bool no_sanitize_p = wtd->no_sanitize_p;
1113	  wtd->no_sanitize_p = true;
1114	  for (tree decl = BIND_EXPR_VARS (stmt);
1115	       decl;
1116	       decl = DECL_CHAIN (decl))
1117	    if (VAR_P (decl)
1118		&& TREE_STATIC (decl)
1119		&& DECL_INITIAL (decl))
1120	      cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL);
1121	  wtd->no_sanitize_p = no_sanitize_p;
1122	}
1123      wtd->bind_expr_stack.safe_push (stmt);
1124      cp_walk_tree (&BIND_EXPR_BODY (stmt),
1125		    cp_genericize_r, data, NULL);
1126      wtd->bind_expr_stack.pop ();
1127    }
1128
1129  else if (TREE_CODE (stmt) == USING_STMT)
1130    {
1131      tree block = NULL_TREE;
1132
1133      /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
1134         BLOCK, and append an IMPORTED_DECL to its
1135	 BLOCK_VARS chained list.  */
1136      if (wtd->bind_expr_stack.exists ())
1137	{
1138	  int i;
1139	  for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
1140	    if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
1141	      break;
1142	}
1143      if (block)
1144	{
1145	  tree using_directive;
1146	  gcc_assert (TREE_OPERAND (stmt, 0));
1147
1148	  using_directive = make_node (IMPORTED_DECL);
1149	  TREE_TYPE (using_directive) = void_type_node;
1150
1151	  IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
1152	    = TREE_OPERAND (stmt, 0);
1153	  DECL_CHAIN (using_directive) = BLOCK_VARS (block);
1154	  BLOCK_VARS (block) = using_directive;
1155	}
1156      /* The USING_STMT won't appear in GENERIC.  */
1157      *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1158      *walk_subtrees = 0;
1159    }
1160
1161  else if (TREE_CODE (stmt) == DECL_EXPR
1162	   && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
1163    {
1164      /* Using decls inside DECL_EXPRs are just dropped on the floor.  */
1165      *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1166      *walk_subtrees = 0;
1167    }
1168  else if (TREE_CODE (stmt) == OMP_PARALLEL || TREE_CODE (stmt) == OMP_TASK)
1169    {
1170      struct cp_genericize_omp_taskreg omp_ctx;
1171      tree c, decl;
1172      splay_tree_node n;
1173
1174      *walk_subtrees = 0;
1175      cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
1176      omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
1177      omp_ctx.default_shared = omp_ctx.is_parallel;
1178      omp_ctx.outer = wtd->omp_ctx;
1179      omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
1180      wtd->omp_ctx = &omp_ctx;
1181      for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
1182	switch (OMP_CLAUSE_CODE (c))
1183	  {
1184	  case OMP_CLAUSE_SHARED:
1185	  case OMP_CLAUSE_PRIVATE:
1186	  case OMP_CLAUSE_FIRSTPRIVATE:
1187	  case OMP_CLAUSE_LASTPRIVATE:
1188	    decl = OMP_CLAUSE_DECL (c);
1189	    if (decl == error_mark_node || !omp_var_to_track (decl))
1190	      break;
1191	    n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
1192	    if (n != NULL)
1193	      break;
1194	    splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
1195			       OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
1196			       ? OMP_CLAUSE_DEFAULT_SHARED
1197			       : OMP_CLAUSE_DEFAULT_PRIVATE);
1198	    if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE
1199		&& omp_ctx.outer)
1200	      omp_cxx_notice_variable (omp_ctx.outer, decl);
1201	    break;
1202	  case OMP_CLAUSE_DEFAULT:
1203	    if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
1204	      omp_ctx.default_shared = true;
1205	  default:
1206	    break;
1207	  }
1208      cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
1209      wtd->omp_ctx = omp_ctx.outer;
1210      splay_tree_delete (omp_ctx.variables);
1211    }
1212  else if (TREE_CODE (stmt) == CONVERT_EXPR)
1213    gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
1214  else if (TREE_CODE (stmt) == FOR_STMT)
1215    genericize_for_stmt (stmt_p, walk_subtrees, data);
1216  else if (TREE_CODE (stmt) == WHILE_STMT)
1217    genericize_while_stmt (stmt_p, walk_subtrees, data);
1218  else if (TREE_CODE (stmt) == DO_STMT)
1219    genericize_do_stmt (stmt_p, walk_subtrees, data);
1220  else if (TREE_CODE (stmt) == SWITCH_STMT)
1221    genericize_switch_stmt (stmt_p, walk_subtrees, data);
1222  else if (TREE_CODE (stmt) == CONTINUE_STMT)
1223    genericize_continue_stmt (stmt_p);
1224  else if (TREE_CODE (stmt) == BREAK_STMT)
1225    genericize_break_stmt (stmt_p);
1226  else if (TREE_CODE (stmt) == OMP_FOR
1227	   || TREE_CODE (stmt) == OMP_SIMD
1228	   || TREE_CODE (stmt) == OMP_DISTRIBUTE)
1229    genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
1230  else if (TREE_CODE (stmt) == SIZEOF_EXPR)
1231    {
1232      if (SIZEOF_EXPR_TYPE_P (stmt))
1233	*stmt_p
1234	  = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (stmt, 0)),
1235					SIZEOF_EXPR, false);
1236      else if (TYPE_P (TREE_OPERAND (stmt, 0)))
1237	*stmt_p = cxx_sizeof_or_alignof_type (TREE_OPERAND (stmt, 0),
1238					      SIZEOF_EXPR, false);
1239      else
1240	*stmt_p = cxx_sizeof_or_alignof_expr (TREE_OPERAND (stmt, 0),
1241					      SIZEOF_EXPR, false);
1242      if (*stmt_p == error_mark_node)
1243	*stmt_p = size_one_node;
1244      return NULL;
1245    }
1246  else if ((flag_sanitize
1247	    & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
1248	   && !wtd->no_sanitize_p)
1249    {
1250      if ((flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1251	  && TREE_CODE (stmt) == NOP_EXPR
1252	  && TREE_CODE (TREE_TYPE (stmt)) == REFERENCE_TYPE)
1253	ubsan_maybe_instrument_reference (stmt);
1254      else if (TREE_CODE (stmt) == CALL_EXPR)
1255	{
1256	  tree fn = CALL_EXPR_FN (stmt);
1257	  if (fn != NULL_TREE
1258	      && !error_operand_p (fn)
1259	      && POINTER_TYPE_P (TREE_TYPE (fn))
1260	      && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE)
1261	    {
1262	      bool is_ctor
1263		= TREE_CODE (fn) == ADDR_EXPR
1264		  && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
1265		  && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0));
1266	      if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1267		ubsan_maybe_instrument_member_call (stmt, is_ctor);
1268	      if ((flag_sanitize & SANITIZE_VPTR) && !is_ctor)
1269		cp_ubsan_maybe_instrument_member_call (stmt);
1270	    }
1271	}
1272    }
1273
1274  p_set->add (*stmt_p);
1275
1276  return NULL;
1277}
1278
1279/* Lower C++ front end trees to GENERIC in T_P.  */
1280
1281static void
1282cp_genericize_tree (tree* t_p)
1283{
1284  struct cp_genericize_data wtd;
1285
1286  wtd.p_set = new hash_set<tree>;
1287  wtd.bind_expr_stack.create (0);
1288  wtd.omp_ctx = NULL;
1289  wtd.no_sanitize_p = false;
1290  cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
1291  delete wtd.p_set;
1292  wtd.bind_expr_stack.release ();
1293  if (flag_sanitize & SANITIZE_VPTR)
1294    cp_ubsan_instrument_member_accesses (t_p);
1295}
1296
1297/* If a function that should end with a return in non-void
1298   function doesn't obviously end with return, add ubsan
1299   instrumentation code to verify it at runtime.  */
1300
1301static void
1302cp_ubsan_maybe_instrument_return (tree fndecl)
1303{
1304  if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
1305      || DECL_CONSTRUCTOR_P (fndecl)
1306      || DECL_DESTRUCTOR_P (fndecl)
1307      || !targetm.warn_func_return (fndecl))
1308    return;
1309
1310  tree t = DECL_SAVED_TREE (fndecl);
1311  while (t)
1312    {
1313      switch (TREE_CODE (t))
1314	{
1315	case BIND_EXPR:
1316	  t = BIND_EXPR_BODY (t);
1317	  continue;
1318	case TRY_FINALLY_EXPR:
1319	  t = TREE_OPERAND (t, 0);
1320	  continue;
1321	case STATEMENT_LIST:
1322	  {
1323	    tree_stmt_iterator i = tsi_last (t);
1324	    if (!tsi_end_p (i))
1325	      {
1326		t = tsi_stmt (i);
1327		continue;
1328	      }
1329	  }
1330	  break;
1331	case RETURN_EXPR:
1332	  return;
1333	default:
1334	  break;
1335	}
1336      break;
1337    }
1338  if (t == NULL_TREE)
1339    return;
1340  t = DECL_SAVED_TREE (fndecl);
1341  if (TREE_CODE (t) == BIND_EXPR
1342      && TREE_CODE (BIND_EXPR_BODY (t)) == STATEMENT_LIST)
1343    {
1344      tree_stmt_iterator i = tsi_last (BIND_EXPR_BODY (t));
1345      t = ubsan_instrument_return (DECL_SOURCE_LOCATION (fndecl));
1346      tsi_link_after (&i, t, TSI_NEW_STMT);
1347    }
1348}
1349
1350void
1351cp_genericize (tree fndecl)
1352{
1353  tree t;
1354
1355  /* Fix up the types of parms passed by invisible reference.  */
1356  for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
1357    if (TREE_ADDRESSABLE (TREE_TYPE (t)))
1358      {
1359	/* If a function's arguments are copied to create a thunk,
1360	   then DECL_BY_REFERENCE will be set -- but the type of the
1361	   argument will be a pointer type, so we will never get
1362	   here.  */
1363	gcc_assert (!DECL_BY_REFERENCE (t));
1364	gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
1365	TREE_TYPE (t) = DECL_ARG_TYPE (t);
1366	DECL_BY_REFERENCE (t) = 1;
1367	TREE_ADDRESSABLE (t) = 0;
1368	relayout_decl (t);
1369      }
1370
1371  /* Do the same for the return value.  */
1372  if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
1373    {
1374      t = DECL_RESULT (fndecl);
1375      TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
1376      DECL_BY_REFERENCE (t) = 1;
1377      TREE_ADDRESSABLE (t) = 0;
1378      relayout_decl (t);
1379      if (DECL_NAME (t))
1380	{
1381	  /* Adjust DECL_VALUE_EXPR of the original var.  */
1382	  tree outer = outer_curly_brace_block (current_function_decl);
1383	  tree var;
1384
1385	  if (outer)
1386	    for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1387	      if (DECL_NAME (t) == DECL_NAME (var)
1388		  && DECL_HAS_VALUE_EXPR_P (var)
1389		  && DECL_VALUE_EXPR (var) == t)
1390		{
1391		  tree val = convert_from_reference (t);
1392		  SET_DECL_VALUE_EXPR (var, val);
1393		  break;
1394		}
1395	}
1396    }
1397
1398  /* If we're a clone, the body is already GIMPLE.  */
1399  if (DECL_CLONED_FUNCTION_P (fndecl))
1400    return;
1401
1402  /* Expand all the array notations here.  */
1403  if (flag_cilkplus
1404      && contains_array_notation_expr (DECL_SAVED_TREE (fndecl)))
1405    DECL_SAVED_TREE (fndecl) =
1406      expand_array_notation_exprs (DECL_SAVED_TREE (fndecl));
1407
1408  /* We do want to see every occurrence of the parms, so we can't just use
1409     walk_tree's hash functionality.  */
1410  cp_genericize_tree (&DECL_SAVED_TREE (fndecl));
1411
1412  if (flag_sanitize & SANITIZE_RETURN
1413      && do_ubsan_in_current_function ())
1414    cp_ubsan_maybe_instrument_return (fndecl);
1415
1416  /* Do everything else.  */
1417  c_genericize (fndecl);
1418
1419  gcc_assert (bc_label[bc_break] == NULL);
1420  gcc_assert (bc_label[bc_continue] == NULL);
1421}
1422
1423/* Build code to apply FN to each member of ARG1 and ARG2.  FN may be
1424   NULL if there is in fact nothing to do.  ARG2 may be null if FN
1425   actually only takes one argument.  */
1426
1427static tree
1428cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
1429{
1430  tree defparm, parm, t;
1431  int i = 0;
1432  int nargs;
1433  tree *argarray;
1434
1435  if (fn == NULL)
1436    return NULL;
1437
1438  nargs = list_length (DECL_ARGUMENTS (fn));
1439  argarray = XALLOCAVEC (tree, nargs);
1440
1441  defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
1442  if (arg2)
1443    defparm = TREE_CHAIN (defparm);
1444
1445  if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
1446    {
1447      tree inner_type = TREE_TYPE (arg1);
1448      tree start1, end1, p1;
1449      tree start2 = NULL, p2 = NULL;
1450      tree ret = NULL, lab;
1451
1452      start1 = arg1;
1453      start2 = arg2;
1454      do
1455	{
1456	  inner_type = TREE_TYPE (inner_type);
1457	  start1 = build4 (ARRAY_REF, inner_type, start1,
1458			   size_zero_node, NULL, NULL);
1459	  if (arg2)
1460	    start2 = build4 (ARRAY_REF, inner_type, start2,
1461			     size_zero_node, NULL, NULL);
1462	}
1463      while (TREE_CODE (inner_type) == ARRAY_TYPE);
1464      start1 = build_fold_addr_expr_loc (input_location, start1);
1465      if (arg2)
1466	start2 = build_fold_addr_expr_loc (input_location, start2);
1467
1468      end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
1469      end1 = fold_build_pointer_plus (start1, end1);
1470
1471      p1 = create_tmp_var (TREE_TYPE (start1));
1472      t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
1473      append_to_statement_list (t, &ret);
1474
1475      if (arg2)
1476	{
1477	  p2 = create_tmp_var (TREE_TYPE (start2));
1478	  t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
1479	  append_to_statement_list (t, &ret);
1480	}
1481
1482      lab = create_artificial_label (input_location);
1483      t = build1 (LABEL_EXPR, void_type_node, lab);
1484      append_to_statement_list (t, &ret);
1485
1486      argarray[i++] = p1;
1487      if (arg2)
1488	argarray[i++] = p2;
1489      /* Handle default arguments.  */
1490      for (parm = defparm; parm && parm != void_list_node;
1491	   parm = TREE_CHAIN (parm), i++)
1492	argarray[i] = convert_default_arg (TREE_VALUE (parm),
1493					   TREE_PURPOSE (parm), fn, i,
1494					   tf_warning_or_error);
1495      t = build_call_a (fn, i, argarray);
1496      t = fold_convert (void_type_node, t);
1497      t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1498      append_to_statement_list (t, &ret);
1499
1500      t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type));
1501      t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
1502      append_to_statement_list (t, &ret);
1503
1504      if (arg2)
1505	{
1506	  t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type));
1507	  t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
1508	  append_to_statement_list (t, &ret);
1509	}
1510
1511      t = build2 (NE_EXPR, boolean_type_node, p1, end1);
1512      t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
1513      append_to_statement_list (t, &ret);
1514
1515      return ret;
1516    }
1517  else
1518    {
1519      argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
1520      if (arg2)
1521	argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
1522      /* Handle default arguments.  */
1523      for (parm = defparm; parm && parm != void_list_node;
1524	   parm = TREE_CHAIN (parm), i++)
1525	argarray[i] = convert_default_arg (TREE_VALUE (parm),
1526					   TREE_PURPOSE (parm),
1527					   fn, i, tf_warning_or_error);
1528      t = build_call_a (fn, i, argarray);
1529      t = fold_convert (void_type_node, t);
1530      return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1531    }
1532}
1533
1534/* Return code to initialize DECL with its default constructor, or
1535   NULL if there's nothing to do.  */
1536
1537tree
1538cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/)
1539{
1540  tree info = CP_OMP_CLAUSE_INFO (clause);
1541  tree ret = NULL;
1542
1543  if (info)
1544    ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
1545
1546  return ret;
1547}
1548
1549/* Return code to initialize DST with a copy constructor from SRC.  */
1550
1551tree
1552cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
1553{
1554  tree info = CP_OMP_CLAUSE_INFO (clause);
1555  tree ret = NULL;
1556
1557  if (info)
1558    ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
1559  if (ret == NULL)
1560    ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1561
1562  return ret;
1563}
1564
1565/* Similarly, except use an assignment operator instead.  */
1566
1567tree
1568cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
1569{
1570  tree info = CP_OMP_CLAUSE_INFO (clause);
1571  tree ret = NULL;
1572
1573  if (info)
1574    ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
1575  if (ret == NULL)
1576    ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1577
1578  return ret;
1579}
1580
1581/* Return code to destroy DECL.  */
1582
1583tree
1584cxx_omp_clause_dtor (tree clause, tree decl)
1585{
1586  tree info = CP_OMP_CLAUSE_INFO (clause);
1587  tree ret = NULL;
1588
1589  if (info)
1590    ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
1591
1592  return ret;
1593}
1594
1595/* True if OpenMP should privatize what this DECL points to rather
1596   than the DECL itself.  */
1597
1598bool
1599cxx_omp_privatize_by_reference (const_tree decl)
1600{
1601  return (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
1602	  || is_invisiref_parm (decl));
1603}
1604
1605/* Return true if DECL is const qualified var having no mutable member.  */
1606bool
1607cxx_omp_const_qual_no_mutable (tree decl)
1608{
1609  tree type = TREE_TYPE (decl);
1610  if (TREE_CODE (type) == REFERENCE_TYPE)
1611    {
1612      if (!is_invisiref_parm (decl))
1613	return false;
1614      type = TREE_TYPE (type);
1615
1616      if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
1617	{
1618	  /* NVR doesn't preserve const qualification of the
1619	     variable's type.  */
1620	  tree outer = outer_curly_brace_block (current_function_decl);
1621	  tree var;
1622
1623	  if (outer)
1624	    for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1625	      if (DECL_NAME (decl) == DECL_NAME (var)
1626		  && (TYPE_MAIN_VARIANT (type)
1627		      == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
1628		{
1629		  if (TYPE_READONLY (TREE_TYPE (var)))
1630		    type = TREE_TYPE (var);
1631		  break;
1632		}
1633	}
1634    }
1635
1636  if (type == error_mark_node)
1637    return false;
1638
1639  /* Variables with const-qualified type having no mutable member
1640     are predetermined shared.  */
1641  if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
1642    return true;
1643
1644  return false;
1645}
1646
1647/* True if OpenMP sharing attribute of DECL is predetermined.  */
1648
1649enum omp_clause_default_kind
1650cxx_omp_predetermined_sharing (tree decl)
1651{
1652  /* Static data members are predetermined shared.  */
1653  if (TREE_STATIC (decl))
1654    {
1655      tree ctx = CP_DECL_CONTEXT (decl);
1656      if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
1657	return OMP_CLAUSE_DEFAULT_SHARED;
1658    }
1659
1660  /* Const qualified vars having no mutable member are predetermined
1661     shared.  */
1662  if (cxx_omp_const_qual_no_mutable (decl))
1663    return OMP_CLAUSE_DEFAULT_SHARED;
1664
1665  return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1666}
1667
1668/* Finalize an implicitly determined clause.  */
1669
1670void
1671cxx_omp_finish_clause (tree c, gimple_seq *)
1672{
1673  tree decl, inner_type;
1674  bool make_shared = false;
1675
1676  if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
1677    return;
1678
1679  decl = OMP_CLAUSE_DECL (c);
1680  decl = require_complete_type (decl);
1681  inner_type = TREE_TYPE (decl);
1682  if (decl == error_mark_node)
1683    make_shared = true;
1684  else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1685    {
1686      if (is_invisiref_parm (decl))
1687	inner_type = TREE_TYPE (inner_type);
1688      else
1689	{
1690	  error ("%qE implicitly determined as %<firstprivate%> has reference type",
1691		 decl);
1692	  make_shared = true;
1693	}
1694    }
1695
1696  /* We're interested in the base element, not arrays.  */
1697  while (TREE_CODE (inner_type) == ARRAY_TYPE)
1698    inner_type = TREE_TYPE (inner_type);
1699
1700  /* Check for special function availability by building a call to one.
1701     Save the results, because later we won't be in the right context
1702     for making these queries.  */
1703  if (!make_shared
1704      && CLASS_TYPE_P (inner_type)
1705      && cxx_omp_create_clause_info (c, inner_type, false, true, false, true))
1706    make_shared = true;
1707
1708  if (make_shared)
1709    OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
1710}
1711