Merge from trunk:
[official-gcc.git] / main / gcc / cp / cp-gimplify.c
blob55d6c144dd67497819e3565b65eb0562f5457a67
1 /* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
3 Copyright (C) 2002-2014 Free Software Foundation, Inc.
4 Contributed by Jason Merrill <jason@redhat.com>
6 This file is part of GCC.
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.
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.
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/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "stor-layout.h"
28 #include "cp-tree.h"
29 #include "c-family/c-common.h"
30 #include "tree-iterator.h"
31 #include "pointer-set.h"
32 #include "basic-block.h"
33 #include "tree-ssa-alias.h"
34 #include "internal-fn.h"
35 #include "gimple-expr.h"
36 #include "is-a.h"
37 #include "gimple.h"
38 #include "gimplify.h"
39 #include "hashtab.h"
40 #include "flags.h"
41 #include "splay-tree.h"
42 #include "target.h"
43 #include "c-family/c-ubsan.h"
44 #include "cilk.h"
46 /* Forward declarations. */
48 static tree cp_genericize_r (tree *, int *, void *);
49 static void cp_genericize_tree (tree*);
51 /* Local declarations. */
53 enum bc_t { bc_break = 0, bc_continue = 1 };
55 /* Stack of labels which are targets for "break" or "continue",
56 linked through TREE_CHAIN. */
57 static tree bc_label[2];
59 /* Begin a scope which can be exited by a break or continue statement. BC
60 indicates which.
62 Just creates a label with location LOCATION and pushes it into the current
63 context. */
65 static tree
66 begin_bc_block (enum bc_t bc, location_t location)
68 tree label = create_artificial_label (location);
69 DECL_CHAIN (label) = bc_label[bc];
70 bc_label[bc] = label;
71 return label;
74 /* Finish a scope which can be exited by a break or continue statement.
75 LABEL was returned from the most recent call to begin_bc_block. BLOCK is
76 an expression for the contents of the scope.
78 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
79 BLOCK. Otherwise, just forget the label. */
81 static void
82 finish_bc_block (tree *block, enum bc_t bc, tree label)
84 gcc_assert (label == bc_label[bc]);
86 if (TREE_USED (label))
87 append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label),
88 block);
90 bc_label[bc] = DECL_CHAIN (label);
91 DECL_CHAIN (label) = NULL_TREE;
94 /* Get the LABEL_EXPR to represent a break or continue statement
95 in the current block scope. BC indicates which. */
97 static tree
98 get_bc_label (enum bc_t bc)
100 tree label = bc_label[bc];
102 /* Mark the label used for finish_bc_block. */
103 TREE_USED (label) = 1;
104 return label;
107 /* Genericize a TRY_BLOCK. */
109 static void
110 genericize_try_block (tree *stmt_p)
112 tree body = TRY_STMTS (*stmt_p);
113 tree cleanup = TRY_HANDLERS (*stmt_p);
115 *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
118 /* Genericize a HANDLER by converting to a CATCH_EXPR. */
120 static void
121 genericize_catch_block (tree *stmt_p)
123 tree type = HANDLER_TYPE (*stmt_p);
124 tree body = HANDLER_BODY (*stmt_p);
126 /* FIXME should the caught type go in TREE_TYPE? */
127 *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
130 /* A terser interface for building a representation of an exception
131 specification. */
133 static tree
134 build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
136 tree t;
138 /* FIXME should the allowed types go in TREE_TYPE? */
139 t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
140 append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
142 t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
143 append_to_statement_list (body, &TREE_OPERAND (t, 0));
145 return t;
148 /* Genericize an EH_SPEC_BLOCK by converting it to a
149 TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
151 static void
152 genericize_eh_spec_block (tree *stmt_p)
154 tree body = EH_SPEC_STMTS (*stmt_p);
155 tree allowed = EH_SPEC_RAISES (*stmt_p);
156 tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ());
158 *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
159 TREE_NO_WARNING (*stmt_p) = true;
160 TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true;
163 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
165 static void
166 genericize_if_stmt (tree *stmt_p)
168 tree stmt, cond, then_, else_;
169 location_t locus = EXPR_LOCATION (*stmt_p);
171 stmt = *stmt_p;
172 cond = IF_COND (stmt);
173 then_ = THEN_CLAUSE (stmt);
174 else_ = ELSE_CLAUSE (stmt);
176 if (!then_)
177 then_ = build_empty_stmt (locus);
178 if (!else_)
179 else_ = build_empty_stmt (locus);
181 if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
182 stmt = then_;
183 else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
184 stmt = else_;
185 else
186 stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
187 if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt))
188 SET_EXPR_LOCATION (stmt, locus);
189 *stmt_p = stmt;
192 /* Build a generic representation of one of the C loop forms. COND is the
193 loop condition or NULL_TREE. BODY is the (possibly compound) statement
194 controlled by the loop. INCR is the increment expression of a for-loop,
195 or NULL_TREE. COND_IS_FIRST indicates whether the condition is
196 evaluated before the loop body as in while and for loops, or after the
197 loop body as in do-while loops. */
199 static void
200 genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
201 tree incr, bool cond_is_first, int *walk_subtrees,
202 void *data)
204 tree blab, clab;
205 tree entry = NULL, exit = NULL, t;
206 tree stmt_list = NULL;
208 blab = begin_bc_block (bc_break, start_locus);
209 clab = begin_bc_block (bc_continue, start_locus);
211 if (incr && EXPR_P (incr))
212 SET_EXPR_LOCATION (incr, start_locus);
214 cp_walk_tree (&cond, cp_genericize_r, data, NULL);
215 cp_walk_tree (&body, cp_genericize_r, data, NULL);
216 cp_walk_tree (&incr, cp_genericize_r, data, NULL);
217 *walk_subtrees = 0;
219 /* If condition is zero don't generate a loop construct. */
220 if (cond && integer_zerop (cond))
222 if (cond_is_first)
224 t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
225 get_bc_label (bc_break));
226 append_to_statement_list (t, &stmt_list);
229 else
231 /* Expand to gotos, just like c_finish_loop. TODO: Use LOOP_EXPR. */
232 tree top = build1 (LABEL_EXPR, void_type_node,
233 create_artificial_label (start_locus));
235 /* If we have an exit condition, then we build an IF with gotos either
236 out of the loop, or to the top of it. If there's no exit condition,
237 then we just build a jump back to the top. */
238 exit = build1 (GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL (top));
240 if (cond && !integer_nonzerop (cond))
242 /* Canonicalize the loop condition to the end. This means
243 generating a branch to the loop condition. Reuse the
244 continue label, if possible. */
245 if (cond_is_first)
247 if (incr)
249 entry = build1 (LABEL_EXPR, void_type_node,
250 create_artificial_label (start_locus));
251 t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
252 LABEL_EXPR_LABEL (entry));
254 else
255 t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
256 get_bc_label (bc_continue));
257 append_to_statement_list (t, &stmt_list);
260 t = build1 (GOTO_EXPR, void_type_node, get_bc_label (bc_break));
261 exit = fold_build3_loc (start_locus,
262 COND_EXPR, void_type_node, cond, exit, t);
265 append_to_statement_list (top, &stmt_list);
268 append_to_statement_list (body, &stmt_list);
269 finish_bc_block (&stmt_list, bc_continue, clab);
270 append_to_statement_list (incr, &stmt_list);
271 append_to_statement_list (entry, &stmt_list);
272 append_to_statement_list (exit, &stmt_list);
273 finish_bc_block (&stmt_list, bc_break, blab);
275 if (stmt_list == NULL_TREE)
276 stmt_list = build1 (NOP_EXPR, void_type_node, integer_zero_node);
278 *stmt_p = stmt_list;
281 /* Genericize a FOR_STMT node *STMT_P. */
283 static void
284 genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
286 tree stmt = *stmt_p;
287 tree expr = NULL;
288 tree loop;
289 tree init = FOR_INIT_STMT (stmt);
291 if (init)
293 cp_walk_tree (&init, cp_genericize_r, data, NULL);
294 append_to_statement_list (init, &expr);
297 genericize_cp_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
298 FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees, data);
299 append_to_statement_list (loop, &expr);
300 *stmt_p = expr;
303 /* Genericize a WHILE_STMT node *STMT_P. */
305 static void
306 genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data)
308 tree stmt = *stmt_p;
309 genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt),
310 WHILE_BODY (stmt), NULL_TREE, 1, walk_subtrees, data);
313 /* Genericize a DO_STMT node *STMT_P. */
315 static void
316 genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data)
318 tree stmt = *stmt_p;
319 genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt),
320 DO_BODY (stmt), NULL_TREE, 0, walk_subtrees, data);
323 /* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR. */
325 static void
326 genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data)
328 tree stmt = *stmt_p;
329 tree break_block, body, cond, type;
330 location_t stmt_locus = EXPR_LOCATION (stmt);
332 break_block = begin_bc_block (bc_break, stmt_locus);
334 body = SWITCH_STMT_BODY (stmt);
335 if (!body)
336 body = build_empty_stmt (stmt_locus);
337 cond = SWITCH_STMT_COND (stmt);
338 type = SWITCH_STMT_TYPE (stmt);
340 cp_walk_tree (&body, cp_genericize_r, data, NULL);
341 cp_walk_tree (&cond, cp_genericize_r, data, NULL);
342 cp_walk_tree (&type, cp_genericize_r, data, NULL);
343 *walk_subtrees = 0;
345 *stmt_p = build3_loc (stmt_locus, SWITCH_EXPR, type, cond, body, NULL_TREE);
346 finish_bc_block (stmt_p, bc_break, break_block);
349 /* Genericize a CONTINUE_STMT node *STMT_P. */
351 static void
352 genericize_continue_stmt (tree *stmt_p)
354 tree stmt_list = NULL;
355 tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN);
356 tree label = get_bc_label (bc_continue);
357 location_t location = EXPR_LOCATION (*stmt_p);
358 tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label);
359 append_to_statement_list (pred, &stmt_list);
360 append_to_statement_list (jump, &stmt_list);
361 *stmt_p = stmt_list;
364 /* Genericize a BREAK_STMT node *STMT_P. */
366 static void
367 genericize_break_stmt (tree *stmt_p)
369 tree label = get_bc_label (bc_break);
370 location_t location = EXPR_LOCATION (*stmt_p);
371 *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label);
374 /* Genericize a OMP_FOR node *STMT_P. */
376 static void
377 genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
379 tree stmt = *stmt_p;
380 location_t locus = EXPR_LOCATION (stmt);
381 tree clab = begin_bc_block (bc_continue, locus);
383 cp_walk_tree (&OMP_FOR_BODY (stmt), cp_genericize_r, data, NULL);
384 cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_genericize_r, data, NULL);
385 cp_walk_tree (&OMP_FOR_INIT (stmt), cp_genericize_r, data, NULL);
386 cp_walk_tree (&OMP_FOR_COND (stmt), cp_genericize_r, data, NULL);
387 cp_walk_tree (&OMP_FOR_INCR (stmt), cp_genericize_r, data, NULL);
388 cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_genericize_r, data, NULL);
389 *walk_subtrees = 0;
391 finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab);
394 /* Hook into the middle of gimplifying an OMP_FOR node. */
396 static enum gimplify_status
397 cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
399 tree for_stmt = *expr_p;
400 gimple_seq seq = NULL;
402 /* Protect ourselves from recursion. */
403 if (OMP_FOR_GIMPLIFYING_P (for_stmt))
404 return GS_UNHANDLED;
405 OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
407 gimplify_and_add (for_stmt, &seq);
408 gimple_seq_add_seq (pre_p, seq);
410 OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
412 return GS_ALL_DONE;
415 /* Gimplify an EXPR_STMT node. */
417 static void
418 gimplify_expr_stmt (tree *stmt_p)
420 tree stmt = EXPR_STMT_EXPR (*stmt_p);
422 if (stmt == error_mark_node)
423 stmt = NULL;
425 /* Gimplification of a statement expression will nullify the
426 statement if all its side effects are moved to *PRE_P and *POST_P.
428 In this case we will not want to emit the gimplified statement.
429 However, we may still want to emit a warning, so we do that before
430 gimplification. */
431 if (stmt && warn_unused_value)
433 if (!TREE_SIDE_EFFECTS (stmt))
435 if (!IS_EMPTY_STMT (stmt)
436 && !VOID_TYPE_P (TREE_TYPE (stmt))
437 && !TREE_NO_WARNING (stmt))
438 warning (OPT_Wunused_value, "statement with no effect");
440 else
441 warn_if_unused_value (stmt, input_location);
444 if (stmt == NULL_TREE)
445 stmt = alloc_stmt_list ();
447 *stmt_p = stmt;
450 /* Gimplify initialization from an AGGR_INIT_EXPR. */
452 static void
453 cp_gimplify_init_expr (tree *expr_p)
455 tree from = TREE_OPERAND (*expr_p, 1);
456 tree to = TREE_OPERAND (*expr_p, 0);
457 tree t;
459 /* What about code that pulls out the temp and uses it elsewhere? I
460 think that such code never uses the TARGET_EXPR as an initializer. If
461 I'm wrong, we'll abort because the temp won't have any RTL. In that
462 case, I guess we'll need to replace references somehow. */
463 if (TREE_CODE (from) == TARGET_EXPR)
464 from = TARGET_EXPR_INITIAL (from);
466 /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
467 inside the TARGET_EXPR. */
468 for (t = from; t; )
470 tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
472 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
473 replace the slot operand with our target.
475 Should we add a target parm to gimplify_expr instead? No, as in this
476 case we want to replace the INIT_EXPR. */
477 if (TREE_CODE (sub) == AGGR_INIT_EXPR
478 || TREE_CODE (sub) == VEC_INIT_EXPR)
480 if (TREE_CODE (sub) == AGGR_INIT_EXPR)
481 AGGR_INIT_EXPR_SLOT (sub) = to;
482 else
483 VEC_INIT_EXPR_SLOT (sub) = to;
484 *expr_p = from;
486 /* The initialization is now a side-effect, so the container can
487 become void. */
488 if (from != sub)
489 TREE_TYPE (from) = void_type_node;
492 if (t == sub)
493 break;
494 else
495 t = TREE_OPERAND (t, 1);
500 /* Gimplify a MUST_NOT_THROW_EXPR. */
502 static enum gimplify_status
503 gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
505 tree stmt = *expr_p;
506 tree temp = voidify_wrapper_expr (stmt, NULL);
507 tree body = TREE_OPERAND (stmt, 0);
508 gimple_seq try_ = NULL;
509 gimple_seq catch_ = NULL;
510 gimple mnt;
512 gimplify_and_add (body, &try_);
513 mnt = gimple_build_eh_must_not_throw (terminate_node);
514 gimple_seq_add_stmt_without_update (&catch_, mnt);
515 mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
517 gimple_seq_add_stmt_without_update (pre_p, mnt);
518 if (temp)
520 *expr_p = temp;
521 return GS_OK;
524 *expr_p = NULL;
525 return GS_ALL_DONE;
528 /* Do C++-specific gimplification. Args are as for gimplify_expr. */
531 cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
533 int saved_stmts_are_full_exprs_p = 0;
534 enum tree_code code = TREE_CODE (*expr_p);
535 enum gimplify_status ret;
537 if (STATEMENT_CODE_P (code))
539 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
540 current_stmt_tree ()->stmts_are_full_exprs_p
541 = STMT_IS_FULL_EXPR_P (*expr_p);
544 switch (code)
546 case PTRMEM_CST:
547 *expr_p = cplus_expand_constant (*expr_p);
548 ret = GS_OK;
549 break;
551 case AGGR_INIT_EXPR:
552 simplify_aggr_init_expr (expr_p);
553 ret = GS_OK;
554 break;
556 case VEC_INIT_EXPR:
558 location_t loc = input_location;
559 tree init = VEC_INIT_EXPR_INIT (*expr_p);
560 int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
561 gcc_assert (EXPR_HAS_LOCATION (*expr_p));
562 input_location = EXPR_LOCATION (*expr_p);
563 *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
564 init, VEC_INIT_EXPR_VALUE_INIT (*expr_p),
565 from_array,
566 tf_warning_or_error);
567 cp_genericize_tree (expr_p);
568 ret = GS_OK;
569 input_location = loc;
571 break;
573 case THROW_EXPR:
574 /* FIXME communicate throw type to back end, probably by moving
575 THROW_EXPR into ../tree.def. */
576 *expr_p = TREE_OPERAND (*expr_p, 0);
577 ret = GS_OK;
578 break;
580 case MUST_NOT_THROW_EXPR:
581 ret = gimplify_must_not_throw_expr (expr_p, pre_p);
582 break;
584 /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
585 LHS of an assignment might also be involved in the RHS, as in bug
586 25979. */
587 case INIT_EXPR:
588 if (fn_contains_cilk_spawn_p (cfun)
589 && cilk_detect_spawn_and_unwrap (expr_p)
590 && !seen_error ())
591 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
592 cp_gimplify_init_expr (expr_p);
593 if (TREE_CODE (*expr_p) != INIT_EXPR)
594 return GS_OK;
595 /* Otherwise fall through. */
596 case MODIFY_EXPR:
598 if (fn_contains_cilk_spawn_p (cfun)
599 && cilk_detect_spawn_and_unwrap (expr_p)
600 && !seen_error ())
601 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
603 /* If the back end isn't clever enough to know that the lhs and rhs
604 types are the same, add an explicit conversion. */
605 tree op0 = TREE_OPERAND (*expr_p, 0);
606 tree op1 = TREE_OPERAND (*expr_p, 1);
608 if (!error_operand_p (op0)
609 && !error_operand_p (op1)
610 && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
611 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
612 && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
613 TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
614 TREE_TYPE (op0), op1);
616 else if ((is_gimple_lvalue (op1) || INDIRECT_REF_P (op1)
617 || (TREE_CODE (op1) == CONSTRUCTOR
618 && CONSTRUCTOR_NELTS (op1) == 0
619 && !TREE_CLOBBER_P (op1))
620 || (TREE_CODE (op1) == CALL_EXPR
621 && !CALL_EXPR_RETURN_SLOT_OPT (op1)))
622 && is_really_empty_class (TREE_TYPE (op0)))
624 /* Remove any copies of empty classes. We check that the RHS
625 has a simple form so that TARGET_EXPRs and non-empty
626 CONSTRUCTORs get reduced properly, and we leave the return
627 slot optimization alone because it isn't a copy (FIXME so it
628 shouldn't be represented as one).
630 Also drop volatile variables on the RHS to avoid infinite
631 recursion from gimplify_expr trying to load the value. */
632 if (!TREE_SIDE_EFFECTS (op1))
633 *expr_p = op0;
634 else if (TREE_THIS_VOLATILE (op1)
635 && (REFERENCE_CLASS_P (op1) || DECL_P (op1)))
636 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
637 build_fold_addr_expr (op1), op0);
638 else
639 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
640 op0, op1);
643 ret = GS_OK;
644 break;
646 case EMPTY_CLASS_EXPR:
647 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
648 *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
649 ret = GS_OK;
650 break;
652 case BASELINK:
653 *expr_p = BASELINK_FUNCTIONS (*expr_p);
654 ret = GS_OK;
655 break;
657 case TRY_BLOCK:
658 genericize_try_block (expr_p);
659 ret = GS_OK;
660 break;
662 case HANDLER:
663 genericize_catch_block (expr_p);
664 ret = GS_OK;
665 break;
667 case EH_SPEC_BLOCK:
668 genericize_eh_spec_block (expr_p);
669 ret = GS_OK;
670 break;
672 case USING_STMT:
673 gcc_unreachable ();
675 case FOR_STMT:
676 case WHILE_STMT:
677 case DO_STMT:
678 case SWITCH_STMT:
679 case CONTINUE_STMT:
680 case BREAK_STMT:
681 gcc_unreachable ();
683 case OMP_FOR:
684 case OMP_SIMD:
685 case OMP_DISTRIBUTE:
686 ret = cp_gimplify_omp_for (expr_p, pre_p);
687 break;
689 case EXPR_STMT:
690 gimplify_expr_stmt (expr_p);
691 ret = GS_OK;
692 break;
694 case UNARY_PLUS_EXPR:
696 tree arg = TREE_OPERAND (*expr_p, 0);
697 tree type = TREE_TYPE (*expr_p);
698 *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
699 : arg;
700 ret = GS_OK;
702 break;
704 case CILK_SPAWN_STMT:
705 gcc_assert
706 (fn_contains_cilk_spawn_p (cfun)
707 && cilk_detect_spawn_and_unwrap (expr_p));
709 /* If errors are seen, then just process it as a CALL_EXPR. */
710 if (!seen_error ())
711 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
713 case CALL_EXPR:
714 if (fn_contains_cilk_spawn_p (cfun)
715 && cilk_detect_spawn_and_unwrap (expr_p)
716 && !seen_error ())
717 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
719 /* DR 1030 says that we need to evaluate the elements of an
720 initializer-list in forward order even when it's used as arguments to
721 a constructor. So if the target wants to evaluate them in reverse
722 order and there's more than one argument other than 'this', gimplify
723 them in order. */
724 ret = GS_OK;
725 if (PUSH_ARGS_REVERSED && CALL_EXPR_LIST_INIT_P (*expr_p)
726 && call_expr_nargs (*expr_p) > 2)
728 int nargs = call_expr_nargs (*expr_p);
729 location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location);
730 for (int i = 1; i < nargs; ++i)
732 enum gimplify_status t
733 = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc);
734 if (t == GS_ERROR)
735 ret = GS_ERROR;
738 break;
740 default:
741 ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
742 break;
745 /* Restore saved state. */
746 if (STATEMENT_CODE_P (code))
747 current_stmt_tree ()->stmts_are_full_exprs_p
748 = saved_stmts_are_full_exprs_p;
750 return ret;
753 static inline bool
754 is_invisiref_parm (const_tree t)
756 return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
757 && DECL_BY_REFERENCE (t));
760 /* Return true if the uid in both int tree maps are equal. */
763 cxx_int_tree_map_eq (const void *va, const void *vb)
765 const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va;
766 const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb;
767 return (a->uid == b->uid);
770 /* Hash a UID in a cxx_int_tree_map. */
772 unsigned int
773 cxx_int_tree_map_hash (const void *item)
775 return ((const struct cxx_int_tree_map *)item)->uid;
778 /* A stable comparison routine for use with splay trees and DECLs. */
780 static int
781 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
783 tree a = (tree) xa;
784 tree b = (tree) xb;
786 return DECL_UID (a) - DECL_UID (b);
789 /* OpenMP context during genericization. */
791 struct cp_genericize_omp_taskreg
793 bool is_parallel;
794 bool default_shared;
795 struct cp_genericize_omp_taskreg *outer;
796 splay_tree variables;
799 /* Return true if genericization should try to determine if
800 DECL is firstprivate or shared within task regions. */
802 static bool
803 omp_var_to_track (tree decl)
805 tree type = TREE_TYPE (decl);
806 if (is_invisiref_parm (decl))
807 type = TREE_TYPE (type);
808 while (TREE_CODE (type) == ARRAY_TYPE)
809 type = TREE_TYPE (type);
810 if (type == error_mark_node || !CLASS_TYPE_P (type))
811 return false;
812 if (VAR_P (decl) && DECL_THREAD_LOCAL_P (decl))
813 return false;
814 if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
815 return false;
816 return true;
819 /* Note DECL use in OpenMP region OMP_CTX during genericization. */
821 static void
822 omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl)
824 splay_tree_node n = splay_tree_lookup (omp_ctx->variables,
825 (splay_tree_key) decl);
826 if (n == NULL)
828 int flags = OMP_CLAUSE_DEFAULT_SHARED;
829 if (omp_ctx->outer)
830 omp_cxx_notice_variable (omp_ctx->outer, decl);
831 if (!omp_ctx->default_shared)
833 struct cp_genericize_omp_taskreg *octx;
835 for (octx = omp_ctx->outer; octx; octx = octx->outer)
837 n = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
838 if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED)
840 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
841 break;
843 if (octx->is_parallel)
844 break;
846 if (octx == NULL
847 && (TREE_CODE (decl) == PARM_DECL
848 || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl))
849 && DECL_CONTEXT (decl) == current_function_decl)))
850 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
851 if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
853 /* DECL is implicitly determined firstprivate in
854 the current task construct. Ensure copy ctor and
855 dtor are instantiated, because during gimplification
856 it will be already too late. */
857 tree type = TREE_TYPE (decl);
858 if (is_invisiref_parm (decl))
859 type = TREE_TYPE (type);
860 while (TREE_CODE (type) == ARRAY_TYPE)
861 type = TREE_TYPE (type);
862 get_copy_ctor (type, tf_none);
863 get_dtor (type, tf_none);
866 splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags);
870 /* Genericization context. */
872 struct cp_genericize_data
874 hash_set<tree> *p_set;
875 vec<tree> bind_expr_stack;
876 struct cp_genericize_omp_taskreg *omp_ctx;
879 /* Perform any pre-gimplification lowering of C++ front end trees to
880 GENERIC. */
882 static tree
883 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
885 tree stmt = *stmt_p;
886 struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
887 hash_set<tree> *p_set = wtd->p_set;
889 /* If in an OpenMP context, note var uses. */
890 if (__builtin_expect (wtd->omp_ctx != NULL, 0)
891 && (VAR_P (stmt)
892 || TREE_CODE (stmt) == PARM_DECL
893 || TREE_CODE (stmt) == RESULT_DECL)
894 && omp_var_to_track (stmt))
895 omp_cxx_notice_variable (wtd->omp_ctx, stmt);
897 if (is_invisiref_parm (stmt)
898 /* Don't dereference parms in a thunk, pass the references through. */
899 && !(DECL_THUNK_P (current_function_decl)
900 && TREE_CODE (stmt) == PARM_DECL))
902 *stmt_p = convert_from_reference (stmt);
903 *walk_subtrees = 0;
904 return NULL;
907 /* Map block scope extern declarations to visible declarations with the
908 same name and type in outer scopes if any. */
909 if (cp_function_chain->extern_decl_map
910 && VAR_OR_FUNCTION_DECL_P (stmt)
911 && DECL_EXTERNAL (stmt))
913 struct cxx_int_tree_map *h, in;
914 in.uid = DECL_UID (stmt);
915 h = (struct cxx_int_tree_map *)
916 htab_find_with_hash (cp_function_chain->extern_decl_map,
917 &in, in.uid);
918 if (h)
920 *stmt_p = h->to;
921 *walk_subtrees = 0;
922 return NULL;
926 /* Other than invisiref parms, don't walk the same tree twice. */
927 if (p_set->contains (stmt))
929 *walk_subtrees = 0;
930 return NULL_TREE;
933 if (TREE_CODE (stmt) == ADDR_EXPR
934 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
936 /* If in an OpenMP context, note var uses. */
937 if (__builtin_expect (wtd->omp_ctx != NULL, 0)
938 && omp_var_to_track (TREE_OPERAND (stmt, 0)))
939 omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
940 *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
941 *walk_subtrees = 0;
943 else if (TREE_CODE (stmt) == RETURN_EXPR
944 && TREE_OPERAND (stmt, 0)
945 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
946 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */
947 *walk_subtrees = 0;
948 else if (TREE_CODE (stmt) == OMP_CLAUSE)
949 switch (OMP_CLAUSE_CODE (stmt))
951 case OMP_CLAUSE_LASTPRIVATE:
952 /* Don't dereference an invisiref in OpenMP clauses. */
953 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
955 *walk_subtrees = 0;
956 if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
957 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
958 cp_genericize_r, data, NULL);
960 break;
961 case OMP_CLAUSE_PRIVATE:
962 /* Don't dereference an invisiref in OpenMP clauses. */
963 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
964 *walk_subtrees = 0;
965 else if (wtd->omp_ctx != NULL)
967 /* Private clause doesn't cause any references to the
968 var in outer contexts, avoid calling
969 omp_cxx_notice_variable for it. */
970 struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
971 wtd->omp_ctx = NULL;
972 cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
973 data, NULL);
974 wtd->omp_ctx = old;
975 *walk_subtrees = 0;
977 break;
978 case OMP_CLAUSE_SHARED:
979 case OMP_CLAUSE_FIRSTPRIVATE:
980 case OMP_CLAUSE_COPYIN:
981 case OMP_CLAUSE_COPYPRIVATE:
982 /* Don't dereference an invisiref in OpenMP clauses. */
983 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
984 *walk_subtrees = 0;
985 break;
986 case OMP_CLAUSE_REDUCTION:
987 /* Don't dereference an invisiref in reduction clause's
988 OMP_CLAUSE_DECL either. OMP_CLAUSE_REDUCTION_{INIT,MERGE}
989 still needs to be genericized. */
990 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
992 *walk_subtrees = 0;
993 if (OMP_CLAUSE_REDUCTION_INIT (stmt))
994 cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
995 cp_genericize_r, data, NULL);
996 if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
997 cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
998 cp_genericize_r, data, NULL);
1000 break;
1001 default:
1002 break;
1004 else if (IS_TYPE_OR_DECL_P (stmt))
1005 *walk_subtrees = 0;
1007 /* Due to the way voidify_wrapper_expr is written, we don't get a chance
1008 to lower this construct before scanning it, so we need to lower these
1009 before doing anything else. */
1010 else if (TREE_CODE (stmt) == CLEANUP_STMT)
1011 *stmt_p = build2_loc (EXPR_LOCATION (stmt),
1012 CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
1013 : TRY_FINALLY_EXPR,
1014 void_type_node,
1015 CLEANUP_BODY (stmt),
1016 CLEANUP_EXPR (stmt));
1018 else if (TREE_CODE (stmt) == IF_STMT)
1020 genericize_if_stmt (stmt_p);
1021 /* *stmt_p has changed, tail recurse to handle it again. */
1022 return cp_genericize_r (stmt_p, walk_subtrees, data);
1025 /* COND_EXPR might have incompatible types in branches if one or both
1026 arms are bitfields. Fix it up now. */
1027 else if (TREE_CODE (stmt) == COND_EXPR)
1029 tree type_left
1030 = (TREE_OPERAND (stmt, 1)
1031 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
1032 : NULL_TREE);
1033 tree type_right
1034 = (TREE_OPERAND (stmt, 2)
1035 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
1036 : NULL_TREE);
1037 if (type_left
1038 && !useless_type_conversion_p (TREE_TYPE (stmt),
1039 TREE_TYPE (TREE_OPERAND (stmt, 1))))
1041 TREE_OPERAND (stmt, 1)
1042 = fold_convert (type_left, TREE_OPERAND (stmt, 1));
1043 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1044 type_left));
1046 if (type_right
1047 && !useless_type_conversion_p (TREE_TYPE (stmt),
1048 TREE_TYPE (TREE_OPERAND (stmt, 2))))
1050 TREE_OPERAND (stmt, 2)
1051 = fold_convert (type_right, TREE_OPERAND (stmt, 2));
1052 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1053 type_right));
1057 else if (TREE_CODE (stmt) == BIND_EXPR)
1059 if (__builtin_expect (wtd->omp_ctx != NULL, 0))
1061 tree decl;
1062 for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
1063 if (VAR_P (decl)
1064 && !DECL_EXTERNAL (decl)
1065 && omp_var_to_track (decl))
1067 splay_tree_node n
1068 = splay_tree_lookup (wtd->omp_ctx->variables,
1069 (splay_tree_key) decl);
1070 if (n == NULL)
1071 splay_tree_insert (wtd->omp_ctx->variables,
1072 (splay_tree_key) decl,
1073 TREE_STATIC (decl)
1074 ? OMP_CLAUSE_DEFAULT_SHARED
1075 : OMP_CLAUSE_DEFAULT_PRIVATE);
1078 wtd->bind_expr_stack.safe_push (stmt);
1079 cp_walk_tree (&BIND_EXPR_BODY (stmt),
1080 cp_genericize_r, data, NULL);
1081 wtd->bind_expr_stack.pop ();
1084 else if (TREE_CODE (stmt) == USING_STMT)
1086 tree block = NULL_TREE;
1088 /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
1089 BLOCK, and append an IMPORTED_DECL to its
1090 BLOCK_VARS chained list. */
1091 if (wtd->bind_expr_stack.exists ())
1093 int i;
1094 for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
1095 if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
1096 break;
1098 if (block)
1100 tree using_directive;
1101 gcc_assert (TREE_OPERAND (stmt, 0));
1103 using_directive = make_node (IMPORTED_DECL);
1104 TREE_TYPE (using_directive) = void_type_node;
1106 IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
1107 = TREE_OPERAND (stmt, 0);
1108 DECL_CHAIN (using_directive) = BLOCK_VARS (block);
1109 BLOCK_VARS (block) = using_directive;
1111 /* The USING_STMT won't appear in GENERIC. */
1112 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1113 *walk_subtrees = 0;
1116 else if (TREE_CODE (stmt) == DECL_EXPR
1117 && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
1119 /* Using decls inside DECL_EXPRs are just dropped on the floor. */
1120 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1121 *walk_subtrees = 0;
1123 else if (TREE_CODE (stmt) == OMP_PARALLEL || TREE_CODE (stmt) == OMP_TASK)
1125 struct cp_genericize_omp_taskreg omp_ctx;
1126 tree c, decl;
1127 splay_tree_node n;
1129 *walk_subtrees = 0;
1130 cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
1131 omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
1132 omp_ctx.default_shared = omp_ctx.is_parallel;
1133 omp_ctx.outer = wtd->omp_ctx;
1134 omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
1135 wtd->omp_ctx = &omp_ctx;
1136 for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
1137 switch (OMP_CLAUSE_CODE (c))
1139 case OMP_CLAUSE_SHARED:
1140 case OMP_CLAUSE_PRIVATE:
1141 case OMP_CLAUSE_FIRSTPRIVATE:
1142 case OMP_CLAUSE_LASTPRIVATE:
1143 decl = OMP_CLAUSE_DECL (c);
1144 if (decl == error_mark_node || !omp_var_to_track (decl))
1145 break;
1146 n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
1147 if (n != NULL)
1148 break;
1149 splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
1150 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
1151 ? OMP_CLAUSE_DEFAULT_SHARED
1152 : OMP_CLAUSE_DEFAULT_PRIVATE);
1153 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE
1154 && omp_ctx.outer)
1155 omp_cxx_notice_variable (omp_ctx.outer, decl);
1156 break;
1157 case OMP_CLAUSE_DEFAULT:
1158 if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
1159 omp_ctx.default_shared = true;
1160 default:
1161 break;
1163 cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
1164 wtd->omp_ctx = omp_ctx.outer;
1165 splay_tree_delete (omp_ctx.variables);
1167 else if (TREE_CODE (stmt) == CONVERT_EXPR)
1168 gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
1169 else if (TREE_CODE (stmt) == FOR_STMT)
1170 genericize_for_stmt (stmt_p, walk_subtrees, data);
1171 else if (TREE_CODE (stmt) == WHILE_STMT)
1172 genericize_while_stmt (stmt_p, walk_subtrees, data);
1173 else if (TREE_CODE (stmt) == DO_STMT)
1174 genericize_do_stmt (stmt_p, walk_subtrees, data);
1175 else if (TREE_CODE (stmt) == SWITCH_STMT)
1176 genericize_switch_stmt (stmt_p, walk_subtrees, data);
1177 else if (TREE_CODE (stmt) == CONTINUE_STMT)
1178 genericize_continue_stmt (stmt_p);
1179 else if (TREE_CODE (stmt) == BREAK_STMT)
1180 genericize_break_stmt (stmt_p);
1181 else if (TREE_CODE (stmt) == OMP_FOR
1182 || TREE_CODE (stmt) == OMP_SIMD
1183 || TREE_CODE (stmt) == OMP_DISTRIBUTE)
1184 genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
1185 else if (TREE_CODE (stmt) == SIZEOF_EXPR)
1187 if (SIZEOF_EXPR_TYPE_P (stmt))
1188 *stmt_p
1189 = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (stmt, 0)),
1190 SIZEOF_EXPR, false);
1191 else if (TYPE_P (TREE_OPERAND (stmt, 0)))
1192 *stmt_p = cxx_sizeof_or_alignof_type (TREE_OPERAND (stmt, 0),
1193 SIZEOF_EXPR, false);
1194 else
1195 *stmt_p = cxx_sizeof_or_alignof_expr (TREE_OPERAND (stmt, 0),
1196 SIZEOF_EXPR, false);
1197 if (*stmt_p == error_mark_node)
1198 *stmt_p = size_one_node;
1199 return NULL;
1201 else if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1203 if (TREE_CODE (stmt) == NOP_EXPR
1204 && TREE_CODE (TREE_TYPE (stmt)) == REFERENCE_TYPE)
1205 ubsan_maybe_instrument_reference (stmt);
1206 else if (TREE_CODE (stmt) == CALL_EXPR)
1208 tree fn = CALL_EXPR_FN (stmt);
1209 if (fn != NULL_TREE
1210 && !error_operand_p (fn)
1211 && POINTER_TYPE_P (TREE_TYPE (fn))
1212 && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE)
1214 bool is_ctor
1215 = TREE_CODE (fn) == ADDR_EXPR
1216 && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
1217 && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0));
1218 ubsan_maybe_instrument_member_call (stmt, is_ctor);
1223 p_set->add (*stmt_p);
1225 return NULL;
1228 /* Lower C++ front end trees to GENERIC in T_P. */
1230 static void
1231 cp_genericize_tree (tree* t_p)
1233 struct cp_genericize_data wtd;
1235 wtd.p_set = new hash_set<tree>;
1236 wtd.bind_expr_stack.create (0);
1237 wtd.omp_ctx = NULL;
1238 cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
1239 delete wtd.p_set;
1240 wtd.bind_expr_stack.release ();
1243 /* If a function that should end with a return in non-void
1244 function doesn't obviously end with return, add ubsan
1245 instrumentation code to verify it at runtime. */
1247 static void
1248 cp_ubsan_maybe_instrument_return (tree fndecl)
1250 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
1251 || DECL_CONSTRUCTOR_P (fndecl)
1252 || DECL_DESTRUCTOR_P (fndecl)
1253 || !targetm.warn_func_return (fndecl))
1254 return;
1256 tree t = DECL_SAVED_TREE (fndecl);
1257 while (t)
1259 switch (TREE_CODE (t))
1261 case BIND_EXPR:
1262 t = BIND_EXPR_BODY (t);
1263 continue;
1264 case TRY_FINALLY_EXPR:
1265 t = TREE_OPERAND (t, 0);
1266 continue;
1267 case STATEMENT_LIST:
1269 tree_stmt_iterator i = tsi_last (t);
1270 if (!tsi_end_p (i))
1272 t = tsi_stmt (i);
1273 continue;
1276 break;
1277 case RETURN_EXPR:
1278 return;
1279 default:
1280 break;
1282 break;
1284 if (t == NULL_TREE)
1285 return;
1286 t = DECL_SAVED_TREE (fndecl);
1287 if (TREE_CODE (t) == BIND_EXPR
1288 && TREE_CODE (BIND_EXPR_BODY (t)) == STATEMENT_LIST)
1290 tree_stmt_iterator i = tsi_last (BIND_EXPR_BODY (t));
1291 t = ubsan_instrument_return (DECL_SOURCE_LOCATION (fndecl));
1292 tsi_link_after (&i, t, TSI_NEW_STMT);
1296 void
1297 cp_genericize (tree fndecl)
1299 tree t;
1301 /* Fix up the types of parms passed by invisible reference. */
1302 for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
1303 if (TREE_ADDRESSABLE (TREE_TYPE (t)))
1305 /* If a function's arguments are copied to create a thunk,
1306 then DECL_BY_REFERENCE will be set -- but the type of the
1307 argument will be a pointer type, so we will never get
1308 here. */
1309 gcc_assert (!DECL_BY_REFERENCE (t));
1310 gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
1311 TREE_TYPE (t) = DECL_ARG_TYPE (t);
1312 DECL_BY_REFERENCE (t) = 1;
1313 TREE_ADDRESSABLE (t) = 0;
1314 relayout_decl (t);
1317 /* Do the same for the return value. */
1318 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
1320 t = DECL_RESULT (fndecl);
1321 TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
1322 DECL_BY_REFERENCE (t) = 1;
1323 TREE_ADDRESSABLE (t) = 0;
1324 relayout_decl (t);
1325 if (DECL_NAME (t))
1327 /* Adjust DECL_VALUE_EXPR of the original var. */
1328 tree outer = outer_curly_brace_block (current_function_decl);
1329 tree var;
1331 if (outer)
1332 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1333 if (DECL_NAME (t) == DECL_NAME (var)
1334 && DECL_HAS_VALUE_EXPR_P (var)
1335 && DECL_VALUE_EXPR (var) == t)
1337 tree val = convert_from_reference (t);
1338 SET_DECL_VALUE_EXPR (var, val);
1339 break;
1344 /* If we're a clone, the body is already GIMPLE. */
1345 if (DECL_CLONED_FUNCTION_P (fndecl))
1346 return;
1348 /* Expand all the array notations here. */
1349 if (flag_cilkplus
1350 && contains_array_notation_expr (DECL_SAVED_TREE (fndecl)))
1351 DECL_SAVED_TREE (fndecl) =
1352 expand_array_notation_exprs (DECL_SAVED_TREE (fndecl));
1354 /* We do want to see every occurrence of the parms, so we can't just use
1355 walk_tree's hash functionality. */
1356 cp_genericize_tree (&DECL_SAVED_TREE (fndecl));
1358 if (flag_sanitize & SANITIZE_RETURN
1359 && current_function_decl != NULL_TREE
1360 && !lookup_attribute ("no_sanitize_undefined",
1361 DECL_ATTRIBUTES (current_function_decl)))
1362 cp_ubsan_maybe_instrument_return (fndecl);
1364 /* Do everything else. */
1365 c_genericize (fndecl);
1367 gcc_assert (bc_label[bc_break] == NULL);
1368 gcc_assert (bc_label[bc_continue] == NULL);
1371 /* Build code to apply FN to each member of ARG1 and ARG2. FN may be
1372 NULL if there is in fact nothing to do. ARG2 may be null if FN
1373 actually only takes one argument. */
1375 static tree
1376 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
1378 tree defparm, parm, t;
1379 int i = 0;
1380 int nargs;
1381 tree *argarray;
1383 if (fn == NULL)
1384 return NULL;
1386 nargs = list_length (DECL_ARGUMENTS (fn));
1387 argarray = XALLOCAVEC (tree, nargs);
1389 defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
1390 if (arg2)
1391 defparm = TREE_CHAIN (defparm);
1393 if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
1395 tree inner_type = TREE_TYPE (arg1);
1396 tree start1, end1, p1;
1397 tree start2 = NULL, p2 = NULL;
1398 tree ret = NULL, lab;
1400 start1 = arg1;
1401 start2 = arg2;
1404 inner_type = TREE_TYPE (inner_type);
1405 start1 = build4 (ARRAY_REF, inner_type, start1,
1406 size_zero_node, NULL, NULL);
1407 if (arg2)
1408 start2 = build4 (ARRAY_REF, inner_type, start2,
1409 size_zero_node, NULL, NULL);
1411 while (TREE_CODE (inner_type) == ARRAY_TYPE);
1412 start1 = build_fold_addr_expr_loc (input_location, start1);
1413 if (arg2)
1414 start2 = build_fold_addr_expr_loc (input_location, start2);
1416 end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
1417 end1 = fold_build_pointer_plus (start1, end1);
1419 p1 = create_tmp_var (TREE_TYPE (start1), NULL);
1420 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
1421 append_to_statement_list (t, &ret);
1423 if (arg2)
1425 p2 = create_tmp_var (TREE_TYPE (start2), NULL);
1426 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
1427 append_to_statement_list (t, &ret);
1430 lab = create_artificial_label (input_location);
1431 t = build1 (LABEL_EXPR, void_type_node, lab);
1432 append_to_statement_list (t, &ret);
1434 argarray[i++] = p1;
1435 if (arg2)
1436 argarray[i++] = p2;
1437 /* Handle default arguments. */
1438 for (parm = defparm; parm && parm != void_list_node;
1439 parm = TREE_CHAIN (parm), i++)
1440 argarray[i] = convert_default_arg (TREE_VALUE (parm),
1441 TREE_PURPOSE (parm), fn, i,
1442 tf_warning_or_error);
1443 t = build_call_a (fn, i, argarray);
1444 t = fold_convert (void_type_node, t);
1445 t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1446 append_to_statement_list (t, &ret);
1448 t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type));
1449 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
1450 append_to_statement_list (t, &ret);
1452 if (arg2)
1454 t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type));
1455 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
1456 append_to_statement_list (t, &ret);
1459 t = build2 (NE_EXPR, boolean_type_node, p1, end1);
1460 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
1461 append_to_statement_list (t, &ret);
1463 return ret;
1465 else
1467 argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
1468 if (arg2)
1469 argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
1470 /* Handle default arguments. */
1471 for (parm = defparm; parm && parm != void_list_node;
1472 parm = TREE_CHAIN (parm), i++)
1473 argarray[i] = convert_default_arg (TREE_VALUE (parm),
1474 TREE_PURPOSE (parm),
1475 fn, i, tf_warning_or_error);
1476 t = build_call_a (fn, i, argarray);
1477 t = fold_convert (void_type_node, t);
1478 return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1482 /* Return code to initialize DECL with its default constructor, or
1483 NULL if there's nothing to do. */
1485 tree
1486 cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/)
1488 tree info = CP_OMP_CLAUSE_INFO (clause);
1489 tree ret = NULL;
1491 if (info)
1492 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
1494 return ret;
1497 /* Return code to initialize DST with a copy constructor from SRC. */
1499 tree
1500 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
1502 tree info = CP_OMP_CLAUSE_INFO (clause);
1503 tree ret = NULL;
1505 if (info)
1506 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
1507 if (ret == NULL)
1508 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1510 return ret;
1513 /* Similarly, except use an assignment operator instead. */
1515 tree
1516 cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
1518 tree info = CP_OMP_CLAUSE_INFO (clause);
1519 tree ret = NULL;
1521 if (info)
1522 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
1523 if (ret == NULL)
1524 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1526 return ret;
1529 /* Return code to destroy DECL. */
1531 tree
1532 cxx_omp_clause_dtor (tree clause, tree decl)
1534 tree info = CP_OMP_CLAUSE_INFO (clause);
1535 tree ret = NULL;
1537 if (info)
1538 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
1540 return ret;
1543 /* True if OpenMP should privatize what this DECL points to rather
1544 than the DECL itself. */
1546 bool
1547 cxx_omp_privatize_by_reference (const_tree decl)
1549 return (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
1550 || is_invisiref_parm (decl));
1553 /* Return true if DECL is const qualified var having no mutable member. */
1554 bool
1555 cxx_omp_const_qual_no_mutable (tree decl)
1557 tree type = TREE_TYPE (decl);
1558 if (TREE_CODE (type) == REFERENCE_TYPE)
1560 if (!is_invisiref_parm (decl))
1561 return false;
1562 type = TREE_TYPE (type);
1564 if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
1566 /* NVR doesn't preserve const qualification of the
1567 variable's type. */
1568 tree outer = outer_curly_brace_block (current_function_decl);
1569 tree var;
1571 if (outer)
1572 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1573 if (DECL_NAME (decl) == DECL_NAME (var)
1574 && (TYPE_MAIN_VARIANT (type)
1575 == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
1577 if (TYPE_READONLY (TREE_TYPE (var)))
1578 type = TREE_TYPE (var);
1579 break;
1584 if (type == error_mark_node)
1585 return false;
1587 /* Variables with const-qualified type having no mutable member
1588 are predetermined shared. */
1589 if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
1590 return true;
1592 return false;
1595 /* True if OpenMP sharing attribute of DECL is predetermined. */
1597 enum omp_clause_default_kind
1598 cxx_omp_predetermined_sharing (tree decl)
1600 /* Static data members are predetermined shared. */
1601 if (TREE_STATIC (decl))
1603 tree ctx = CP_DECL_CONTEXT (decl);
1604 if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
1605 return OMP_CLAUSE_DEFAULT_SHARED;
1608 /* Const qualified vars having no mutable member are predetermined
1609 shared. */
1610 if (cxx_omp_const_qual_no_mutable (decl))
1611 return OMP_CLAUSE_DEFAULT_SHARED;
1613 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1616 /* Finalize an implicitly determined clause. */
1618 void
1619 cxx_omp_finish_clause (tree c, gimple_seq *)
1621 tree decl, inner_type;
1622 bool make_shared = false;
1624 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
1625 return;
1627 decl = OMP_CLAUSE_DECL (c);
1628 decl = require_complete_type (decl);
1629 inner_type = TREE_TYPE (decl);
1630 if (decl == error_mark_node)
1631 make_shared = true;
1632 else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1634 if (is_invisiref_parm (decl))
1635 inner_type = TREE_TYPE (inner_type);
1636 else
1638 error ("%qE implicitly determined as %<firstprivate%> has reference type",
1639 decl);
1640 make_shared = true;
1644 /* We're interested in the base element, not arrays. */
1645 while (TREE_CODE (inner_type) == ARRAY_TYPE)
1646 inner_type = TREE_TYPE (inner_type);
1648 /* Check for special function availability by building a call to one.
1649 Save the results, because later we won't be in the right context
1650 for making these queries. */
1651 if (!make_shared
1652 && CLASS_TYPE_P (inner_type)
1653 && cxx_omp_create_clause_info (c, inner_type, false, true, false, true))
1654 make_shared = true;
1656 if (make_shared)
1657 OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;