xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/cp/cp-gimplify.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
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 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12 
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along 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 
61 static tree cp_genericize_r (tree *, int *, void *);
62 static void cp_genericize_tree (tree*, bool);
63 
64 /* Local declarations.  */
65 
66 enum 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.  */
70 static 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 
78 static tree
79 begin_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 
98 static void
99 finish_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 
114 static tree
115 get_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 
126 static void
127 genericize_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 
137 static void
138 genericize_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 
150 static tree
151 build_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 
168 static void
169 genericize_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 
182 static void
183 genericize_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 
216 static void
217 genericize_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 
282 static void
283 genericize_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 
306 static void
307 genericize_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 
316 static void
317 genericize_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 
326 static void
327 genericize_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 
352 static void
353 genericize_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 
367 static void
368 genericize_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 
377 static void
378 genericize_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 
397 static enum gimplify_status
398 cp_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 
418 static void
419 gimplify_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 
453 static void
454 cp_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 
507 static enum gimplify_status
508 gimplify_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 
540 static bool
541 simple_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 
558 int
559 cp_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, false);
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 
786 static inline bool
787 is_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 
795 bool
796 cxx_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 
803 unsigned int
804 cxx_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 
811 static int
812 splay_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 
822 struct 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 
833 static bool
834 omp_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 
852 static void
853 omp_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 
903 struct 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   bool handle_invisiref_parm_p;
910 };
911 
912 /* Perform any pre-gimplification lowering of C++ front end trees to
913    GENERIC.  */
914 
915 static tree
916 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
917 {
918   tree stmt = *stmt_p;
919   struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
920   hash_set<tree> *p_set = wtd->p_set;
921 
922   /* If in an OpenMP context, note var uses.  */
923   if (__builtin_expect (wtd->omp_ctx != NULL, 0)
924       && (VAR_P (stmt)
925 	  || TREE_CODE (stmt) == PARM_DECL
926 	  || TREE_CODE (stmt) == RESULT_DECL)
927       && omp_var_to_track (stmt))
928     omp_cxx_notice_variable (wtd->omp_ctx, stmt);
929 
930   if (wtd->handle_invisiref_parm_p
931       && is_invisiref_parm (stmt)
932       /* Don't dereference parms in a thunk, pass the references through. */
933       && !(DECL_THUNK_P (current_function_decl)
934 	   && TREE_CODE (stmt) == PARM_DECL))
935     {
936       *stmt_p = convert_from_reference (stmt);
937       *walk_subtrees = 0;
938       return NULL;
939     }
940 
941   /* Map block scope extern declarations to visible declarations with the
942      same name and type in outer scopes if any.  */
943   if (cp_function_chain->extern_decl_map
944       && VAR_OR_FUNCTION_DECL_P (stmt)
945       && DECL_EXTERNAL (stmt))
946     {
947       struct cxx_int_tree_map *h, in;
948       in.uid = DECL_UID (stmt);
949       h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid);
950       if (h)
951 	{
952 	  *stmt_p = h->to;
953 	  *walk_subtrees = 0;
954 	  return NULL;
955 	}
956     }
957 
958   /* Other than invisiref parms, don't walk the same tree twice.  */
959   if (p_set->contains (stmt))
960     {
961       *walk_subtrees = 0;
962       return NULL_TREE;
963     }
964 
965   if (TREE_CODE (stmt) == ADDR_EXPR
966       && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
967     {
968       /* If in an OpenMP context, note var uses.  */
969       if (__builtin_expect (wtd->omp_ctx != NULL, 0)
970 	  && omp_var_to_track (TREE_OPERAND (stmt, 0)))
971 	omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
972       *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
973       *walk_subtrees = 0;
974     }
975   else if (TREE_CODE (stmt) == RETURN_EXPR
976 	   && TREE_OPERAND (stmt, 0)
977 	   && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
978     /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR.  */
979     *walk_subtrees = 0;
980   else if (TREE_CODE (stmt) == OMP_CLAUSE)
981     switch (OMP_CLAUSE_CODE (stmt))
982       {
983       case OMP_CLAUSE_LASTPRIVATE:
984 	/* Don't dereference an invisiref in OpenMP clauses.  */
985 	if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
986 	  {
987 	    *walk_subtrees = 0;
988 	    if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
989 	      cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
990 			    cp_genericize_r, data, NULL);
991 	  }
992 	break;
993       case OMP_CLAUSE_PRIVATE:
994 	/* Don't dereference an invisiref in OpenMP clauses.  */
995 	if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
996 	  *walk_subtrees = 0;
997 	else if (wtd->omp_ctx != NULL)
998 	  {
999 	    /* Private clause doesn't cause any references to the
1000 	       var in outer contexts, avoid calling
1001 	       omp_cxx_notice_variable for it.  */
1002 	    struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
1003 	    wtd->omp_ctx = NULL;
1004 	    cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
1005 			  data, NULL);
1006 	    wtd->omp_ctx = old;
1007 	    *walk_subtrees = 0;
1008 	  }
1009 	break;
1010       case OMP_CLAUSE_SHARED:
1011       case OMP_CLAUSE_FIRSTPRIVATE:
1012       case OMP_CLAUSE_COPYIN:
1013       case OMP_CLAUSE_COPYPRIVATE:
1014 	/* Don't dereference an invisiref in OpenMP clauses.  */
1015 	if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1016 	  *walk_subtrees = 0;
1017 	break;
1018       case OMP_CLAUSE_REDUCTION:
1019 	/* Don't dereference an invisiref in reduction clause's
1020 	   OMP_CLAUSE_DECL either.  OMP_CLAUSE_REDUCTION_{INIT,MERGE}
1021 	   still needs to be genericized.  */
1022 	if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1023 	  {
1024 	    *walk_subtrees = 0;
1025 	    if (OMP_CLAUSE_REDUCTION_INIT (stmt))
1026 	      cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
1027 			    cp_genericize_r, data, NULL);
1028 	    if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
1029 	      cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
1030 			    cp_genericize_r, data, NULL);
1031 	  }
1032 	break;
1033       default:
1034 	break;
1035       }
1036   else if (IS_TYPE_OR_DECL_P (stmt))
1037     *walk_subtrees = 0;
1038 
1039   /* Due to the way voidify_wrapper_expr is written, we don't get a chance
1040      to lower this construct before scanning it, so we need to lower these
1041      before doing anything else.  */
1042   else if (TREE_CODE (stmt) == CLEANUP_STMT)
1043     *stmt_p = build2_loc (EXPR_LOCATION (stmt),
1044 			  CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
1045 						 : TRY_FINALLY_EXPR,
1046 			  void_type_node,
1047 			  CLEANUP_BODY (stmt),
1048 			  CLEANUP_EXPR (stmt));
1049 
1050   else if (TREE_CODE (stmt) == IF_STMT)
1051     {
1052       genericize_if_stmt (stmt_p);
1053       /* *stmt_p has changed, tail recurse to handle it again.  */
1054       return cp_genericize_r (stmt_p, walk_subtrees, data);
1055     }
1056 
1057   /* COND_EXPR might have incompatible types in branches if one or both
1058      arms are bitfields.  Fix it up now.  */
1059   else if (TREE_CODE (stmt) == COND_EXPR)
1060     {
1061       tree type_left
1062 	= (TREE_OPERAND (stmt, 1)
1063 	   ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
1064 	   : NULL_TREE);
1065       tree type_right
1066 	= (TREE_OPERAND (stmt, 2)
1067 	   ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
1068 	   : NULL_TREE);
1069       if (type_left
1070 	  && !useless_type_conversion_p (TREE_TYPE (stmt),
1071 					 TREE_TYPE (TREE_OPERAND (stmt, 1))))
1072 	{
1073 	  TREE_OPERAND (stmt, 1)
1074 	    = fold_convert (type_left, TREE_OPERAND (stmt, 1));
1075 	  gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1076 						 type_left));
1077 	}
1078       if (type_right
1079 	  && !useless_type_conversion_p (TREE_TYPE (stmt),
1080 					 TREE_TYPE (TREE_OPERAND (stmt, 2))))
1081 	{
1082 	  TREE_OPERAND (stmt, 2)
1083 	    = fold_convert (type_right, TREE_OPERAND (stmt, 2));
1084 	  gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1085 						 type_right));
1086 	}
1087     }
1088 
1089   else if (TREE_CODE (stmt) == BIND_EXPR)
1090     {
1091       if (__builtin_expect (wtd->omp_ctx != NULL, 0))
1092 	{
1093 	  tree decl;
1094 	  for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
1095 	    if (VAR_P (decl)
1096 		&& !DECL_EXTERNAL (decl)
1097 		&& omp_var_to_track (decl))
1098 	      {
1099 		splay_tree_node n
1100 		  = splay_tree_lookup (wtd->omp_ctx->variables,
1101 				       (splay_tree_key) decl);
1102 		if (n == NULL)
1103 		  splay_tree_insert (wtd->omp_ctx->variables,
1104 				     (splay_tree_key) decl,
1105 				     TREE_STATIC (decl)
1106 				     ? OMP_CLAUSE_DEFAULT_SHARED
1107 				     : OMP_CLAUSE_DEFAULT_PRIVATE);
1108 	      }
1109 	}
1110       if (flag_sanitize
1111 	  & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
1112 	{
1113 	  /* The point here is to not sanitize static initializers.  */
1114 	  bool no_sanitize_p = wtd->no_sanitize_p;
1115 	  wtd->no_sanitize_p = true;
1116 	  for (tree decl = BIND_EXPR_VARS (stmt);
1117 	       decl;
1118 	       decl = DECL_CHAIN (decl))
1119 	    if (VAR_P (decl)
1120 		&& TREE_STATIC (decl)
1121 		&& DECL_INITIAL (decl))
1122 	      cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL);
1123 	  wtd->no_sanitize_p = no_sanitize_p;
1124 	}
1125       wtd->bind_expr_stack.safe_push (stmt);
1126       cp_walk_tree (&BIND_EXPR_BODY (stmt),
1127 		    cp_genericize_r, data, NULL);
1128       wtd->bind_expr_stack.pop ();
1129     }
1130 
1131   else if (TREE_CODE (stmt) == USING_STMT)
1132     {
1133       tree block = NULL_TREE;
1134 
1135       /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
1136          BLOCK, and append an IMPORTED_DECL to its
1137 	 BLOCK_VARS chained list.  */
1138       if (wtd->bind_expr_stack.exists ())
1139 	{
1140 	  int i;
1141 	  for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
1142 	    if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
1143 	      break;
1144 	}
1145       if (block)
1146 	{
1147 	  tree using_directive;
1148 	  gcc_assert (TREE_OPERAND (stmt, 0));
1149 
1150 	  using_directive = make_node (IMPORTED_DECL);
1151 	  TREE_TYPE (using_directive) = void_type_node;
1152 
1153 	  IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
1154 	    = TREE_OPERAND (stmt, 0);
1155 	  DECL_CHAIN (using_directive) = BLOCK_VARS (block);
1156 	  BLOCK_VARS (block) = using_directive;
1157 	}
1158       /* The USING_STMT won't appear in GENERIC.  */
1159       *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1160       *walk_subtrees = 0;
1161     }
1162 
1163   else if (TREE_CODE (stmt) == DECL_EXPR
1164 	   && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
1165     {
1166       /* Using decls inside DECL_EXPRs are just dropped on the floor.  */
1167       *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1168       *walk_subtrees = 0;
1169     }
1170   else if (TREE_CODE (stmt) == OMP_PARALLEL || TREE_CODE (stmt) == OMP_TASK)
1171     {
1172       struct cp_genericize_omp_taskreg omp_ctx;
1173       tree c, decl;
1174       splay_tree_node n;
1175 
1176       *walk_subtrees = 0;
1177       cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
1178       omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
1179       omp_ctx.default_shared = omp_ctx.is_parallel;
1180       omp_ctx.outer = wtd->omp_ctx;
1181       omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
1182       wtd->omp_ctx = &omp_ctx;
1183       for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
1184 	switch (OMP_CLAUSE_CODE (c))
1185 	  {
1186 	  case OMP_CLAUSE_SHARED:
1187 	  case OMP_CLAUSE_PRIVATE:
1188 	  case OMP_CLAUSE_FIRSTPRIVATE:
1189 	  case OMP_CLAUSE_LASTPRIVATE:
1190 	    decl = OMP_CLAUSE_DECL (c);
1191 	    if (decl == error_mark_node || !omp_var_to_track (decl))
1192 	      break;
1193 	    n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
1194 	    if (n != NULL)
1195 	      break;
1196 	    splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
1197 			       OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
1198 			       ? OMP_CLAUSE_DEFAULT_SHARED
1199 			       : OMP_CLAUSE_DEFAULT_PRIVATE);
1200 	    if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE
1201 		&& omp_ctx.outer)
1202 	      omp_cxx_notice_variable (omp_ctx.outer, decl);
1203 	    break;
1204 	  case OMP_CLAUSE_DEFAULT:
1205 	    if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
1206 	      omp_ctx.default_shared = true;
1207 	  default:
1208 	    break;
1209 	  }
1210       cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
1211       wtd->omp_ctx = omp_ctx.outer;
1212       splay_tree_delete (omp_ctx.variables);
1213     }
1214   else if (TREE_CODE (stmt) == CONVERT_EXPR)
1215     gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
1216   else if (TREE_CODE (stmt) == FOR_STMT)
1217     genericize_for_stmt (stmt_p, walk_subtrees, data);
1218   else if (TREE_CODE (stmt) == WHILE_STMT)
1219     genericize_while_stmt (stmt_p, walk_subtrees, data);
1220   else if (TREE_CODE (stmt) == DO_STMT)
1221     genericize_do_stmt (stmt_p, walk_subtrees, data);
1222   else if (TREE_CODE (stmt) == SWITCH_STMT)
1223     genericize_switch_stmt (stmt_p, walk_subtrees, data);
1224   else if (TREE_CODE (stmt) == CONTINUE_STMT)
1225     genericize_continue_stmt (stmt_p);
1226   else if (TREE_CODE (stmt) == BREAK_STMT)
1227     genericize_break_stmt (stmt_p);
1228   else if (TREE_CODE (stmt) == OMP_FOR
1229 	   || TREE_CODE (stmt) == OMP_SIMD
1230 	   || TREE_CODE (stmt) == OMP_DISTRIBUTE)
1231     genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
1232   else if (TREE_CODE (stmt) == SIZEOF_EXPR)
1233     {
1234       if (SIZEOF_EXPR_TYPE_P (stmt))
1235 	*stmt_p
1236 	  = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (stmt, 0)),
1237 					SIZEOF_EXPR, false);
1238       else if (TYPE_P (TREE_OPERAND (stmt, 0)))
1239 	*stmt_p = cxx_sizeof_or_alignof_type (TREE_OPERAND (stmt, 0),
1240 					      SIZEOF_EXPR, false);
1241       else
1242 	*stmt_p = cxx_sizeof_or_alignof_expr (TREE_OPERAND (stmt, 0),
1243 					      SIZEOF_EXPR, false);
1244       if (*stmt_p == error_mark_node)
1245 	*stmt_p = size_one_node;
1246       return NULL;
1247     }
1248   else if ((flag_sanitize
1249 	    & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
1250 	   && !wtd->no_sanitize_p)
1251     {
1252       if ((flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1253 	  && TREE_CODE (stmt) == NOP_EXPR
1254 	  && TREE_CODE (TREE_TYPE (stmt)) == REFERENCE_TYPE)
1255 	ubsan_maybe_instrument_reference (stmt);
1256       else if (TREE_CODE (stmt) == CALL_EXPR)
1257 	{
1258 	  tree fn = CALL_EXPR_FN (stmt);
1259 	  if (fn != NULL_TREE
1260 	      && !error_operand_p (fn)
1261 	      && POINTER_TYPE_P (TREE_TYPE (fn))
1262 	      && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE)
1263 	    {
1264 	      bool is_ctor
1265 		= TREE_CODE (fn) == ADDR_EXPR
1266 		  && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
1267 		  && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0));
1268 	      if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1269 		ubsan_maybe_instrument_member_call (stmt, is_ctor);
1270 	      if ((flag_sanitize & SANITIZE_VPTR) && !is_ctor)
1271 		cp_ubsan_maybe_instrument_member_call (stmt);
1272 	    }
1273 	}
1274     }
1275 
1276   p_set->add (*stmt_p);
1277 
1278   return NULL;
1279 }
1280 
1281 /* Lower C++ front end trees to GENERIC in T_P.  */
1282 
1283 static void
1284 cp_genericize_tree (tree* t_p, bool handle_invisiref_parm_p)
1285 {
1286   struct cp_genericize_data wtd;
1287 
1288   wtd.p_set = new hash_set<tree>;
1289   wtd.bind_expr_stack.create (0);
1290   wtd.omp_ctx = NULL;
1291   wtd.no_sanitize_p = false;
1292   wtd.handle_invisiref_parm_p = handle_invisiref_parm_p;
1293   cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
1294   delete wtd.p_set;
1295   wtd.bind_expr_stack.release ();
1296   if (flag_sanitize & SANITIZE_VPTR)
1297     cp_ubsan_instrument_member_accesses (t_p);
1298 }
1299 
1300 /* If a function that should end with a return in non-void
1301    function doesn't obviously end with return, add ubsan
1302    instrumentation code to verify it at runtime.  */
1303 
1304 static void
1305 cp_ubsan_maybe_instrument_return (tree fndecl)
1306 {
1307   if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
1308       || DECL_CONSTRUCTOR_P (fndecl)
1309       || DECL_DESTRUCTOR_P (fndecl)
1310       || !targetm.warn_func_return (fndecl))
1311     return;
1312 
1313   tree t = DECL_SAVED_TREE (fndecl);
1314   while (t)
1315     {
1316       switch (TREE_CODE (t))
1317 	{
1318 	case BIND_EXPR:
1319 	  t = BIND_EXPR_BODY (t);
1320 	  continue;
1321 	case TRY_FINALLY_EXPR:
1322 	  t = TREE_OPERAND (t, 0);
1323 	  continue;
1324 	case STATEMENT_LIST:
1325 	  {
1326 	    tree_stmt_iterator i = tsi_last (t);
1327 	    if (!tsi_end_p (i))
1328 	      {
1329 		t = tsi_stmt (i);
1330 		continue;
1331 	      }
1332 	  }
1333 	  break;
1334 	case RETURN_EXPR:
1335 	  return;
1336 	default:
1337 	  break;
1338 	}
1339       break;
1340     }
1341   if (t == NULL_TREE)
1342     return;
1343   tree *p = &DECL_SAVED_TREE (fndecl);
1344   if (TREE_CODE (*p) == BIND_EXPR)
1345     p = &BIND_EXPR_BODY (*p);
1346   t = ubsan_instrument_return (DECL_SOURCE_LOCATION (fndecl));
1347   append_to_statement_list (t, p);
1348 }
1349 
1350 void
1351 cp_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 (VAR_P (var)
1388 		  && DECL_NAME (t) == DECL_NAME (var)
1389 		  && DECL_HAS_VALUE_EXPR_P (var)
1390 		  && DECL_VALUE_EXPR (var) == t)
1391 		{
1392 		  tree val = convert_from_reference (t);
1393 		  SET_DECL_VALUE_EXPR (var, val);
1394 		  break;
1395 		}
1396 	}
1397     }
1398 
1399   /* If we're a clone, the body is already GIMPLE.  */
1400   if (DECL_CLONED_FUNCTION_P (fndecl))
1401     return;
1402 
1403   /* Expand all the array notations here.  */
1404   if (flag_cilkplus
1405       && contains_array_notation_expr (DECL_SAVED_TREE (fndecl)))
1406     DECL_SAVED_TREE (fndecl)
1407       = expand_array_notation_exprs (DECL_SAVED_TREE (fndecl));
1408 
1409   /* We do want to see every occurrence of the parms, so we can't just use
1410      walk_tree's hash functionality.  */
1411   cp_genericize_tree (&DECL_SAVED_TREE (fndecl), true);
1412 
1413   if (flag_sanitize & SANITIZE_RETURN
1414       && do_ubsan_in_current_function ())
1415     cp_ubsan_maybe_instrument_return (fndecl);
1416 
1417   /* Do everything else.  */
1418   c_genericize (fndecl);
1419 
1420   gcc_assert (bc_label[bc_break] == NULL);
1421   gcc_assert (bc_label[bc_continue] == NULL);
1422 }
1423 
1424 /* Build code to apply FN to each member of ARG1 and ARG2.  FN may be
1425    NULL if there is in fact nothing to do.  ARG2 may be null if FN
1426    actually only takes one argument.  */
1427 
1428 static tree
1429 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
1430 {
1431   tree defparm, parm, t;
1432   int i = 0;
1433   int nargs;
1434   tree *argarray;
1435 
1436   if (fn == NULL)
1437     return NULL;
1438 
1439   nargs = list_length (DECL_ARGUMENTS (fn));
1440   argarray = XALLOCAVEC (tree, nargs);
1441 
1442   defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
1443   if (arg2)
1444     defparm = TREE_CHAIN (defparm);
1445 
1446   if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
1447     {
1448       tree inner_type = TREE_TYPE (arg1);
1449       tree start1, end1, p1;
1450       tree start2 = NULL, p2 = NULL;
1451       tree ret = NULL, lab;
1452 
1453       start1 = arg1;
1454       start2 = arg2;
1455       do
1456 	{
1457 	  inner_type = TREE_TYPE (inner_type);
1458 	  start1 = build4 (ARRAY_REF, inner_type, start1,
1459 			   size_zero_node, NULL, NULL);
1460 	  if (arg2)
1461 	    start2 = build4 (ARRAY_REF, inner_type, start2,
1462 			     size_zero_node, NULL, NULL);
1463 	}
1464       while (TREE_CODE (inner_type) == ARRAY_TYPE);
1465       start1 = build_fold_addr_expr_loc (input_location, start1);
1466       if (arg2)
1467 	start2 = build_fold_addr_expr_loc (input_location, start2);
1468 
1469       end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
1470       end1 = fold_build_pointer_plus (start1, end1);
1471 
1472       p1 = create_tmp_var (TREE_TYPE (start1));
1473       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
1474       append_to_statement_list (t, &ret);
1475 
1476       if (arg2)
1477 	{
1478 	  p2 = create_tmp_var (TREE_TYPE (start2));
1479 	  t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
1480 	  append_to_statement_list (t, &ret);
1481 	}
1482 
1483       lab = create_artificial_label (input_location);
1484       t = build1 (LABEL_EXPR, void_type_node, lab);
1485       append_to_statement_list (t, &ret);
1486 
1487       argarray[i++] = p1;
1488       if (arg2)
1489 	argarray[i++] = p2;
1490       /* Handle default arguments.  */
1491       for (parm = defparm; parm && parm != void_list_node;
1492 	   parm = TREE_CHAIN (parm), i++)
1493 	argarray[i] = convert_default_arg (TREE_VALUE (parm),
1494 					   TREE_PURPOSE (parm), fn, i,
1495 					   tf_warning_or_error);
1496       t = build_call_a (fn, i, argarray);
1497       t = fold_convert (void_type_node, t);
1498       t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1499       append_to_statement_list (t, &ret);
1500 
1501       t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type));
1502       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
1503       append_to_statement_list (t, &ret);
1504 
1505       if (arg2)
1506 	{
1507 	  t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type));
1508 	  t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
1509 	  append_to_statement_list (t, &ret);
1510 	}
1511 
1512       t = build2 (NE_EXPR, boolean_type_node, p1, end1);
1513       t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
1514       append_to_statement_list (t, &ret);
1515 
1516       return ret;
1517     }
1518   else
1519     {
1520       argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
1521       if (arg2)
1522 	argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
1523       /* Handle default arguments.  */
1524       for (parm = defparm; parm && parm != void_list_node;
1525 	   parm = TREE_CHAIN (parm), i++)
1526 	argarray[i] = convert_default_arg (TREE_VALUE (parm),
1527 					   TREE_PURPOSE (parm),
1528 					   fn, i, tf_warning_or_error);
1529       t = build_call_a (fn, i, argarray);
1530       t = fold_convert (void_type_node, t);
1531       return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1532     }
1533 }
1534 
1535 /* Return code to initialize DECL with its default constructor, or
1536    NULL if there's nothing to do.  */
1537 
1538 tree
1539 cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/)
1540 {
1541   tree info = CP_OMP_CLAUSE_INFO (clause);
1542   tree ret = NULL;
1543 
1544   if (info)
1545     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
1546 
1547   return ret;
1548 }
1549 
1550 /* Return code to initialize DST with a copy constructor from SRC.  */
1551 
1552 tree
1553 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
1554 {
1555   tree info = CP_OMP_CLAUSE_INFO (clause);
1556   tree ret = NULL;
1557 
1558   if (info)
1559     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
1560   if (ret == NULL)
1561     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1562 
1563   return ret;
1564 }
1565 
1566 /* Similarly, except use an assignment operator instead.  */
1567 
1568 tree
1569 cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
1570 {
1571   tree info = CP_OMP_CLAUSE_INFO (clause);
1572   tree ret = NULL;
1573 
1574   if (info)
1575     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
1576   if (ret == NULL)
1577     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1578 
1579   return ret;
1580 }
1581 
1582 /* Return code to destroy DECL.  */
1583 
1584 tree
1585 cxx_omp_clause_dtor (tree clause, tree decl)
1586 {
1587   tree info = CP_OMP_CLAUSE_INFO (clause);
1588   tree ret = NULL;
1589 
1590   if (info)
1591     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
1592 
1593   return ret;
1594 }
1595 
1596 /* True if OpenMP should privatize what this DECL points to rather
1597    than the DECL itself.  */
1598 
1599 bool
1600 cxx_omp_privatize_by_reference (const_tree decl)
1601 {
1602   return (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
1603 	  || is_invisiref_parm (decl));
1604 }
1605 
1606 /* Return true if DECL is const qualified var having no mutable member.  */
1607 bool
1608 cxx_omp_const_qual_no_mutable (tree decl)
1609 {
1610   tree type = TREE_TYPE (decl);
1611   if (TREE_CODE (type) == REFERENCE_TYPE)
1612     {
1613       if (!is_invisiref_parm (decl))
1614 	return false;
1615       type = TREE_TYPE (type);
1616 
1617       if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
1618 	{
1619 	  /* NVR doesn't preserve const qualification of the
1620 	     variable's type.  */
1621 	  tree outer = outer_curly_brace_block (current_function_decl);
1622 	  tree var;
1623 
1624 	  if (outer)
1625 	    for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1626 	      if (VAR_P (var)
1627 		  && DECL_NAME (decl) == DECL_NAME (var)
1628 		  && (TYPE_MAIN_VARIANT (type)
1629 		      == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
1630 		{
1631 		  if (TYPE_READONLY (TREE_TYPE (var)))
1632 		    type = TREE_TYPE (var);
1633 		  break;
1634 		}
1635 	}
1636     }
1637 
1638   if (type == error_mark_node)
1639     return false;
1640 
1641   /* Variables with const-qualified type having no mutable member
1642      are predetermined shared.  */
1643   if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
1644     return true;
1645 
1646   return false;
1647 }
1648 
1649 /* True if OpenMP sharing attribute of DECL is predetermined.  */
1650 
1651 enum omp_clause_default_kind
1652 cxx_omp_predetermined_sharing (tree decl)
1653 {
1654   /* Static data members are predetermined shared.  */
1655   if (TREE_STATIC (decl))
1656     {
1657       tree ctx = CP_DECL_CONTEXT (decl);
1658       if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
1659 	return OMP_CLAUSE_DEFAULT_SHARED;
1660     }
1661 
1662   /* Const qualified vars having no mutable member are predetermined
1663      shared.  */
1664   if (cxx_omp_const_qual_no_mutable (decl))
1665     return OMP_CLAUSE_DEFAULT_SHARED;
1666 
1667   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1668 }
1669 
1670 /* Finalize an implicitly determined clause.  */
1671 
1672 void
1673 cxx_omp_finish_clause (tree c, gimple_seq *)
1674 {
1675   tree decl, inner_type;
1676   bool make_shared = false;
1677 
1678   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
1679     return;
1680 
1681   decl = OMP_CLAUSE_DECL (c);
1682   decl = require_complete_type (decl);
1683   inner_type = TREE_TYPE (decl);
1684   if (decl == error_mark_node)
1685     make_shared = true;
1686   else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1687     {
1688       if (is_invisiref_parm (decl))
1689 	inner_type = TREE_TYPE (inner_type);
1690       else
1691 	{
1692 	  error ("%qE implicitly determined as %<firstprivate%> has reference type",
1693 		 decl);
1694 	  make_shared = true;
1695 	}
1696     }
1697 
1698   /* We're interested in the base element, not arrays.  */
1699   while (TREE_CODE (inner_type) == ARRAY_TYPE)
1700     inner_type = TREE_TYPE (inner_type);
1701 
1702   /* Check for special function availability by building a call to one.
1703      Save the results, because later we won't be in the right context
1704      for making these queries.  */
1705   if (!make_shared
1706       && CLASS_TYPE_P (inner_type)
1707       && cxx_omp_create_clause_info (c, inner_type, false, true, false, true))
1708     make_shared = true;
1709 
1710   if (make_shared)
1711     OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
1712 }
1713