* gcc.dg/store-motion-fgcse-sm.c (dg-final): Cleanup
[official-gcc.git] / gcc / cp / cp-gimplify.c
blob82be90be437f3886aad5cdb3fd3b73b5bdf62550
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 "predict.h"
32 #include "vec.h"
33 #include "hashtab.h"
34 #include "hash-set.h"
35 #include "machmode.h"
36 #include "hard-reg-set.h"
37 #include "input.h"
38 #include "function.h"
39 #include "basic-block.h"
40 #include "tree-ssa-alias.h"
41 #include "internal-fn.h"
42 #include "gimple-expr.h"
43 #include "is-a.h"
44 #include "gimple.h"
45 #include "gimplify.h"
46 #include "flags.h"
47 #include "splay-tree.h"
48 #include "target.h"
49 #include "c-family/c-ubsan.h"
50 #include "cilk.h"
52 /* Forward declarations. */
54 static tree cp_genericize_r (tree *, int *, void *);
55 static void cp_genericize_tree (tree*);
57 /* Local declarations. */
59 enum bc_t { bc_break = 0, bc_continue = 1 };
61 /* Stack of labels which are targets for "break" or "continue",
62 linked through TREE_CHAIN. */
63 static tree bc_label[2];
65 /* Begin a scope which can be exited by a break or continue statement. BC
66 indicates which.
68 Just creates a label with location LOCATION and pushes it into the current
69 context. */
71 static tree
72 begin_bc_block (enum bc_t bc, location_t location)
74 tree label = create_artificial_label (location);
75 DECL_CHAIN (label) = bc_label[bc];
76 bc_label[bc] = label;
77 if (bc == bc_break)
78 LABEL_DECL_BREAK (label) = true;
79 else
80 LABEL_DECL_CONTINUE (label) = true;
81 return label;
84 /* Finish a scope which can be exited by a break or continue statement.
85 LABEL was returned from the most recent call to begin_bc_block. BLOCK is
86 an expression for the contents of the scope.
88 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
89 BLOCK. Otherwise, just forget the label. */
91 static void
92 finish_bc_block (tree *block, enum bc_t bc, tree label)
94 gcc_assert (label == bc_label[bc]);
96 if (TREE_USED (label))
97 append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label),
98 block);
100 bc_label[bc] = DECL_CHAIN (label);
101 DECL_CHAIN (label) = NULL_TREE;
104 /* Get the LABEL_EXPR to represent a break or continue statement
105 in the current block scope. BC indicates which. */
107 static tree
108 get_bc_label (enum bc_t bc)
110 tree label = bc_label[bc];
112 /* Mark the label used for finish_bc_block. */
113 TREE_USED (label) = 1;
114 return label;
117 /* Genericize a TRY_BLOCK. */
119 static void
120 genericize_try_block (tree *stmt_p)
122 tree body = TRY_STMTS (*stmt_p);
123 tree cleanup = TRY_HANDLERS (*stmt_p);
125 *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
128 /* Genericize a HANDLER by converting to a CATCH_EXPR. */
130 static void
131 genericize_catch_block (tree *stmt_p)
133 tree type = HANDLER_TYPE (*stmt_p);
134 tree body = HANDLER_BODY (*stmt_p);
136 /* FIXME should the caught type go in TREE_TYPE? */
137 *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
140 /* A terser interface for building a representation of an exception
141 specification. */
143 static tree
144 build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
146 tree t;
148 /* FIXME should the allowed types go in TREE_TYPE? */
149 t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
150 append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
152 t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
153 append_to_statement_list (body, &TREE_OPERAND (t, 0));
155 return t;
158 /* Genericize an EH_SPEC_BLOCK by converting it to a
159 TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
161 static void
162 genericize_eh_spec_block (tree *stmt_p)
164 tree body = EH_SPEC_STMTS (*stmt_p);
165 tree allowed = EH_SPEC_RAISES (*stmt_p);
166 tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ());
168 *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
169 TREE_NO_WARNING (*stmt_p) = true;
170 TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true;
173 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
175 static void
176 genericize_if_stmt (tree *stmt_p)
178 tree stmt, cond, then_, else_;
179 location_t locus = EXPR_LOCATION (*stmt_p);
181 stmt = *stmt_p;
182 cond = IF_COND (stmt);
183 then_ = THEN_CLAUSE (stmt);
184 else_ = ELSE_CLAUSE (stmt);
186 if (!then_)
187 then_ = build_empty_stmt (locus);
188 if (!else_)
189 else_ = build_empty_stmt (locus);
191 if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
192 stmt = then_;
193 else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
194 stmt = else_;
195 else
196 stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
197 if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt))
198 SET_EXPR_LOCATION (stmt, locus);
199 *stmt_p = stmt;
202 /* Build a generic representation of one of the C loop forms. COND is the
203 loop condition or NULL_TREE. BODY is the (possibly compound) statement
204 controlled by the loop. INCR is the increment expression of a for-loop,
205 or NULL_TREE. COND_IS_FIRST indicates whether the condition is
206 evaluated before the loop body as in while and for loops, or after the
207 loop body as in do-while loops. */
209 static void
210 genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
211 tree incr, bool cond_is_first, int *walk_subtrees,
212 void *data)
214 tree blab, clab;
215 tree exit = NULL;
216 tree stmt_list = NULL;
218 blab = begin_bc_block (bc_break, start_locus);
219 clab = begin_bc_block (bc_continue, start_locus);
221 if (incr && EXPR_P (incr))
222 SET_EXPR_LOCATION (incr, start_locus);
224 cp_walk_tree (&cond, cp_genericize_r, data, NULL);
225 cp_walk_tree (&body, cp_genericize_r, data, NULL);
226 cp_walk_tree (&incr, cp_genericize_r, data, NULL);
227 *walk_subtrees = 0;
229 if (cond && TREE_CODE (cond) != INTEGER_CST)
231 /* If COND is constant, don't bother building an exit. If it's false,
232 we won't build a loop. If it's true, any exits are in the body. */
233 location_t cloc = EXPR_LOC_OR_LOC (cond, start_locus);
234 exit = build1_loc (cloc, GOTO_EXPR, void_type_node,
235 get_bc_label (bc_break));
236 exit = fold_build3_loc (cloc, COND_EXPR, void_type_node, cond,
237 build_empty_stmt (cloc), exit);
240 if (exit && cond_is_first)
241 append_to_statement_list (exit, &stmt_list);
242 append_to_statement_list (body, &stmt_list);
243 finish_bc_block (&stmt_list, bc_continue, clab);
244 append_to_statement_list (incr, &stmt_list);
245 if (exit && !cond_is_first)
246 append_to_statement_list (exit, &stmt_list);
248 if (!stmt_list)
249 stmt_list = build_empty_stmt (start_locus);
251 tree loop;
252 if (cond && integer_zerop (cond))
254 if (cond_is_first)
255 loop = fold_build3_loc (start_locus, COND_EXPR,
256 void_type_node, cond, stmt_list,
257 build_empty_stmt (start_locus));
258 else
259 loop = stmt_list;
261 else
262 loop = build1_loc (start_locus, LOOP_EXPR, void_type_node, stmt_list);
264 stmt_list = NULL;
265 append_to_statement_list (loop, &stmt_list);
266 finish_bc_block (&stmt_list, bc_break, blab);
267 if (!stmt_list)
268 stmt_list = build_empty_stmt (start_locus);
270 *stmt_p = stmt_list;
273 /* Genericize a FOR_STMT node *STMT_P. */
275 static void
276 genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
278 tree stmt = *stmt_p;
279 tree expr = NULL;
280 tree loop;
281 tree init = FOR_INIT_STMT (stmt);
283 if (init)
285 cp_walk_tree (&init, cp_genericize_r, data, NULL);
286 append_to_statement_list (init, &expr);
289 genericize_cp_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
290 FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees, data);
291 append_to_statement_list (loop, &expr);
292 if (expr == NULL_TREE)
293 expr = loop;
294 *stmt_p = expr;
297 /* Genericize a WHILE_STMT node *STMT_P. */
299 static void
300 genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data)
302 tree stmt = *stmt_p;
303 genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt),
304 WHILE_BODY (stmt), NULL_TREE, 1, walk_subtrees, data);
307 /* Genericize a DO_STMT node *STMT_P. */
309 static void
310 genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data)
312 tree stmt = *stmt_p;
313 genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt),
314 DO_BODY (stmt), NULL_TREE, 0, walk_subtrees, data);
317 /* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR. */
319 static void
320 genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data)
322 tree stmt = *stmt_p;
323 tree break_block, body, cond, type;
324 location_t stmt_locus = EXPR_LOCATION (stmt);
326 break_block = begin_bc_block (bc_break, stmt_locus);
328 body = SWITCH_STMT_BODY (stmt);
329 if (!body)
330 body = build_empty_stmt (stmt_locus);
331 cond = SWITCH_STMT_COND (stmt);
332 type = SWITCH_STMT_TYPE (stmt);
334 cp_walk_tree (&body, cp_genericize_r, data, NULL);
335 cp_walk_tree (&cond, cp_genericize_r, data, NULL);
336 cp_walk_tree (&type, cp_genericize_r, data, NULL);
337 *walk_subtrees = 0;
339 *stmt_p = build3_loc (stmt_locus, SWITCH_EXPR, type, cond, body, NULL_TREE);
340 finish_bc_block (stmt_p, bc_break, break_block);
343 /* Genericize a CONTINUE_STMT node *STMT_P. */
345 static void
346 genericize_continue_stmt (tree *stmt_p)
348 tree stmt_list = NULL;
349 tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN);
350 tree label = get_bc_label (bc_continue);
351 location_t location = EXPR_LOCATION (*stmt_p);
352 tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label);
353 append_to_statement_list (pred, &stmt_list);
354 append_to_statement_list (jump, &stmt_list);
355 *stmt_p = stmt_list;
358 /* Genericize a BREAK_STMT node *STMT_P. */
360 static void
361 genericize_break_stmt (tree *stmt_p)
363 tree label = get_bc_label (bc_break);
364 location_t location = EXPR_LOCATION (*stmt_p);
365 *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label);
368 /* Genericize a OMP_FOR node *STMT_P. */
370 static void
371 genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
373 tree stmt = *stmt_p;
374 location_t locus = EXPR_LOCATION (stmt);
375 tree clab = begin_bc_block (bc_continue, locus);
377 cp_walk_tree (&OMP_FOR_BODY (stmt), cp_genericize_r, data, NULL);
378 cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_genericize_r, data, NULL);
379 cp_walk_tree (&OMP_FOR_INIT (stmt), cp_genericize_r, data, NULL);
380 cp_walk_tree (&OMP_FOR_COND (stmt), cp_genericize_r, data, NULL);
381 cp_walk_tree (&OMP_FOR_INCR (stmt), cp_genericize_r, data, NULL);
382 cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_genericize_r, data, NULL);
383 *walk_subtrees = 0;
385 finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab);
388 /* Hook into the middle of gimplifying an OMP_FOR node. */
390 static enum gimplify_status
391 cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
393 tree for_stmt = *expr_p;
394 gimple_seq seq = NULL;
396 /* Protect ourselves from recursion. */
397 if (OMP_FOR_GIMPLIFYING_P (for_stmt))
398 return GS_UNHANDLED;
399 OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
401 gimplify_and_add (for_stmt, &seq);
402 gimple_seq_add_seq (pre_p, seq);
404 OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
406 return GS_ALL_DONE;
409 /* Gimplify an EXPR_STMT node. */
411 static void
412 gimplify_expr_stmt (tree *stmt_p)
414 tree stmt = EXPR_STMT_EXPR (*stmt_p);
416 if (stmt == error_mark_node)
417 stmt = NULL;
419 /* Gimplification of a statement expression will nullify the
420 statement if all its side effects are moved to *PRE_P and *POST_P.
422 In this case we will not want to emit the gimplified statement.
423 However, we may still want to emit a warning, so we do that before
424 gimplification. */
425 if (stmt && warn_unused_value)
427 if (!TREE_SIDE_EFFECTS (stmt))
429 if (!IS_EMPTY_STMT (stmt)
430 && !VOID_TYPE_P (TREE_TYPE (stmt))
431 && !TREE_NO_WARNING (stmt))
432 warning (OPT_Wunused_value, "statement with no effect");
434 else
435 warn_if_unused_value (stmt, input_location);
438 if (stmt == NULL_TREE)
439 stmt = alloc_stmt_list ();
441 *stmt_p = stmt;
444 /* Gimplify initialization from an AGGR_INIT_EXPR. */
446 static void
447 cp_gimplify_init_expr (tree *expr_p)
449 tree from = TREE_OPERAND (*expr_p, 1);
450 tree to = TREE_OPERAND (*expr_p, 0);
451 tree t;
453 /* What about code that pulls out the temp and uses it elsewhere? I
454 think that such code never uses the TARGET_EXPR as an initializer. If
455 I'm wrong, we'll abort because the temp won't have any RTL. In that
456 case, I guess we'll need to replace references somehow. */
457 if (TREE_CODE (from) == TARGET_EXPR)
458 from = TARGET_EXPR_INITIAL (from);
460 /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
461 inside the TARGET_EXPR. */
462 for (t = from; t; )
464 tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
466 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
467 replace the slot operand with our target.
469 Should we add a target parm to gimplify_expr instead? No, as in this
470 case we want to replace the INIT_EXPR. */
471 if (TREE_CODE (sub) == AGGR_INIT_EXPR
472 || TREE_CODE (sub) == VEC_INIT_EXPR)
474 if (TREE_CODE (sub) == AGGR_INIT_EXPR)
475 AGGR_INIT_EXPR_SLOT (sub) = to;
476 else
477 VEC_INIT_EXPR_SLOT (sub) = to;
478 *expr_p = from;
480 /* The initialization is now a side-effect, so the container can
481 become void. */
482 if (from != sub)
483 TREE_TYPE (from) = void_type_node;
486 if (cxx_dialect >= cxx14 && TREE_CODE (sub) == CONSTRUCTOR)
487 /* Handle aggregate NSDMI. */
488 replace_placeholders (sub, to);
490 if (t == sub)
491 break;
492 else
493 t = TREE_OPERAND (t, 1);
498 /* Gimplify a MUST_NOT_THROW_EXPR. */
500 static enum gimplify_status
501 gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
503 tree stmt = *expr_p;
504 tree temp = voidify_wrapper_expr (stmt, NULL);
505 tree body = TREE_OPERAND (stmt, 0);
506 gimple_seq try_ = NULL;
507 gimple_seq catch_ = NULL;
508 gimple mnt;
510 gimplify_and_add (body, &try_);
511 mnt = gimple_build_eh_must_not_throw (terminate_node);
512 gimple_seq_add_stmt_without_update (&catch_, mnt);
513 mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
515 gimple_seq_add_stmt_without_update (pre_p, mnt);
516 if (temp)
518 *expr_p = temp;
519 return GS_OK;
522 *expr_p = NULL;
523 return GS_ALL_DONE;
526 /* Do C++-specific gimplification. Args are as for gimplify_expr. */
529 cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
531 int saved_stmts_are_full_exprs_p = 0;
532 enum tree_code code = TREE_CODE (*expr_p);
533 enum gimplify_status ret;
535 if (STATEMENT_CODE_P (code))
537 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
538 current_stmt_tree ()->stmts_are_full_exprs_p
539 = STMT_IS_FULL_EXPR_P (*expr_p);
542 switch (code)
544 case PTRMEM_CST:
545 *expr_p = cplus_expand_constant (*expr_p);
546 ret = GS_OK;
547 break;
549 case AGGR_INIT_EXPR:
550 simplify_aggr_init_expr (expr_p);
551 ret = GS_OK;
552 break;
554 case VEC_INIT_EXPR:
556 location_t loc = input_location;
557 tree init = VEC_INIT_EXPR_INIT (*expr_p);
558 int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
559 gcc_assert (EXPR_HAS_LOCATION (*expr_p));
560 input_location = EXPR_LOCATION (*expr_p);
561 *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
562 init, VEC_INIT_EXPR_VALUE_INIT (*expr_p),
563 from_array,
564 tf_warning_or_error);
565 cp_genericize_tree (expr_p);
566 ret = GS_OK;
567 input_location = loc;
569 break;
571 case THROW_EXPR:
572 /* FIXME communicate throw type to back end, probably by moving
573 THROW_EXPR into ../tree.def. */
574 *expr_p = TREE_OPERAND (*expr_p, 0);
575 ret = GS_OK;
576 break;
578 case MUST_NOT_THROW_EXPR:
579 ret = gimplify_must_not_throw_expr (expr_p, pre_p);
580 break;
582 /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
583 LHS of an assignment might also be involved in the RHS, as in bug
584 25979. */
585 case INIT_EXPR:
586 if (fn_contains_cilk_spawn_p (cfun)
587 && cilk_detect_spawn_and_unwrap (expr_p)
588 && !seen_error ())
589 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
590 cp_gimplify_init_expr (expr_p);
591 if (TREE_CODE (*expr_p) != INIT_EXPR)
592 return GS_OK;
593 /* Otherwise fall through. */
594 case MODIFY_EXPR:
596 if (fn_contains_cilk_spawn_p (cfun)
597 && cilk_detect_spawn_and_unwrap (expr_p)
598 && !seen_error ())
599 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
601 /* If the back end isn't clever enough to know that the lhs and rhs
602 types are the same, add an explicit conversion. */
603 tree op0 = TREE_OPERAND (*expr_p, 0);
604 tree op1 = TREE_OPERAND (*expr_p, 1);
606 if (!error_operand_p (op0)
607 && !error_operand_p (op1)
608 && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
609 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
610 && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
611 TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
612 TREE_TYPE (op0), op1);
614 else if ((is_gimple_lvalue (op1) || INDIRECT_REF_P (op1)
615 || (TREE_CODE (op1) == CONSTRUCTOR
616 && CONSTRUCTOR_NELTS (op1) == 0
617 && !TREE_CLOBBER_P (op1))
618 || (TREE_CODE (op1) == CALL_EXPR
619 && !CALL_EXPR_RETURN_SLOT_OPT (op1)))
620 && is_really_empty_class (TREE_TYPE (op0)))
622 /* Remove any copies of empty classes. We check that the RHS
623 has a simple form so that TARGET_EXPRs and non-empty
624 CONSTRUCTORs get reduced properly, and we leave the return
625 slot optimization alone because it isn't a copy (FIXME so it
626 shouldn't be represented as one).
628 Also drop volatile variables on the RHS to avoid infinite
629 recursion from gimplify_expr trying to load the value. */
630 if (!TREE_SIDE_EFFECTS (op1))
631 *expr_p = op0;
632 else if (TREE_THIS_VOLATILE (op1)
633 && (REFERENCE_CLASS_P (op1) || DECL_P (op1)))
634 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
635 build_fold_addr_expr (op1), op0);
636 else
637 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
638 op0, op1);
641 ret = GS_OK;
642 break;
644 case EMPTY_CLASS_EXPR:
645 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
646 *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
647 ret = GS_OK;
648 break;
650 case BASELINK:
651 *expr_p = BASELINK_FUNCTIONS (*expr_p);
652 ret = GS_OK;
653 break;
655 case TRY_BLOCK:
656 genericize_try_block (expr_p);
657 ret = GS_OK;
658 break;
660 case HANDLER:
661 genericize_catch_block (expr_p);
662 ret = GS_OK;
663 break;
665 case EH_SPEC_BLOCK:
666 genericize_eh_spec_block (expr_p);
667 ret = GS_OK;
668 break;
670 case USING_STMT:
671 gcc_unreachable ();
673 case FOR_STMT:
674 case WHILE_STMT:
675 case DO_STMT:
676 case SWITCH_STMT:
677 case CONTINUE_STMT:
678 case BREAK_STMT:
679 gcc_unreachable ();
681 case OMP_FOR:
682 case OMP_SIMD:
683 case OMP_DISTRIBUTE:
684 ret = cp_gimplify_omp_for (expr_p, pre_p);
685 break;
687 case EXPR_STMT:
688 gimplify_expr_stmt (expr_p);
689 ret = GS_OK;
690 break;
692 case UNARY_PLUS_EXPR:
694 tree arg = TREE_OPERAND (*expr_p, 0);
695 tree type = TREE_TYPE (*expr_p);
696 *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
697 : arg;
698 ret = GS_OK;
700 break;
702 case CILK_SPAWN_STMT:
703 gcc_assert
704 (fn_contains_cilk_spawn_p (cfun)
705 && cilk_detect_spawn_and_unwrap (expr_p));
707 /* If errors are seen, then just process it as a CALL_EXPR. */
708 if (!seen_error ())
709 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
711 case CALL_EXPR:
712 if (fn_contains_cilk_spawn_p (cfun)
713 && cilk_detect_spawn_and_unwrap (expr_p)
714 && !seen_error ())
715 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
717 /* DR 1030 says that we need to evaluate the elements of an
718 initializer-list in forward order even when it's used as arguments to
719 a constructor. So if the target wants to evaluate them in reverse
720 order and there's more than one argument other than 'this', gimplify
721 them in order. */
722 ret = GS_OK;
723 if (PUSH_ARGS_REVERSED && CALL_EXPR_LIST_INIT_P (*expr_p)
724 && call_expr_nargs (*expr_p) > 2)
726 int nargs = call_expr_nargs (*expr_p);
727 location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location);
728 for (int i = 1; i < nargs; ++i)
730 enum gimplify_status t
731 = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc);
732 if (t == GS_ERROR)
733 ret = GS_ERROR;
736 break;
738 default:
739 ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
740 break;
743 /* Restore saved state. */
744 if (STATEMENT_CODE_P (code))
745 current_stmt_tree ()->stmts_are_full_exprs_p
746 = saved_stmts_are_full_exprs_p;
748 return ret;
751 static inline bool
752 is_invisiref_parm (const_tree t)
754 return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
755 && DECL_BY_REFERENCE (t));
758 /* Return true if the uid in both int tree maps are equal. */
760 bool
761 cxx_int_tree_map_hasher::equal (cxx_int_tree_map *a, cxx_int_tree_map *b)
763 return (a->uid == b->uid);
766 /* Hash a UID in a cxx_int_tree_map. */
768 unsigned int
769 cxx_int_tree_map_hasher::hash (cxx_int_tree_map *item)
771 return item->uid;
774 /* A stable comparison routine for use with splay trees and DECLs. */
776 static int
777 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
779 tree a = (tree) xa;
780 tree b = (tree) xb;
782 return DECL_UID (a) - DECL_UID (b);
785 /* OpenMP context during genericization. */
787 struct cp_genericize_omp_taskreg
789 bool is_parallel;
790 bool default_shared;
791 struct cp_genericize_omp_taskreg *outer;
792 splay_tree variables;
795 /* Return true if genericization should try to determine if
796 DECL is firstprivate or shared within task regions. */
798 static bool
799 omp_var_to_track (tree decl)
801 tree type = TREE_TYPE (decl);
802 if (is_invisiref_parm (decl))
803 type = TREE_TYPE (type);
804 while (TREE_CODE (type) == ARRAY_TYPE)
805 type = TREE_TYPE (type);
806 if (type == error_mark_node || !CLASS_TYPE_P (type))
807 return false;
808 if (VAR_P (decl) && DECL_THREAD_LOCAL_P (decl))
809 return false;
810 if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
811 return false;
812 return true;
815 /* Note DECL use in OpenMP region OMP_CTX during genericization. */
817 static void
818 omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl)
820 splay_tree_node n = splay_tree_lookup (omp_ctx->variables,
821 (splay_tree_key) decl);
822 if (n == NULL)
824 int flags = OMP_CLAUSE_DEFAULT_SHARED;
825 if (omp_ctx->outer)
826 omp_cxx_notice_variable (omp_ctx->outer, decl);
827 if (!omp_ctx->default_shared)
829 struct cp_genericize_omp_taskreg *octx;
831 for (octx = omp_ctx->outer; octx; octx = octx->outer)
833 n = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
834 if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED)
836 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
837 break;
839 if (octx->is_parallel)
840 break;
842 if (octx == NULL
843 && (TREE_CODE (decl) == PARM_DECL
844 || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl))
845 && DECL_CONTEXT (decl) == current_function_decl)))
846 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
847 if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
849 /* DECL is implicitly determined firstprivate in
850 the current task construct. Ensure copy ctor and
851 dtor are instantiated, because during gimplification
852 it will be already too late. */
853 tree type = TREE_TYPE (decl);
854 if (is_invisiref_parm (decl))
855 type = TREE_TYPE (type);
856 while (TREE_CODE (type) == ARRAY_TYPE)
857 type = TREE_TYPE (type);
858 get_copy_ctor (type, tf_none);
859 get_dtor (type, tf_none);
862 splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags);
866 /* Genericization context. */
868 struct cp_genericize_data
870 hash_set<tree> *p_set;
871 vec<tree> bind_expr_stack;
872 struct cp_genericize_omp_taskreg *omp_ctx;
875 /* Perform any pre-gimplification lowering of C++ front end trees to
876 GENERIC. */
878 static tree
879 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
881 tree stmt = *stmt_p;
882 struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
883 hash_set<tree> *p_set = wtd->p_set;
885 /* If in an OpenMP context, note var uses. */
886 if (__builtin_expect (wtd->omp_ctx != NULL, 0)
887 && (VAR_P (stmt)
888 || TREE_CODE (stmt) == PARM_DECL
889 || TREE_CODE (stmt) == RESULT_DECL)
890 && omp_var_to_track (stmt))
891 omp_cxx_notice_variable (wtd->omp_ctx, stmt);
893 if (is_invisiref_parm (stmt)
894 /* Don't dereference parms in a thunk, pass the references through. */
895 && !(DECL_THUNK_P (current_function_decl)
896 && TREE_CODE (stmt) == PARM_DECL))
898 *stmt_p = convert_from_reference (stmt);
899 *walk_subtrees = 0;
900 return NULL;
903 /* Map block scope extern declarations to visible declarations with the
904 same name and type in outer scopes if any. */
905 if (cp_function_chain->extern_decl_map
906 && VAR_OR_FUNCTION_DECL_P (stmt)
907 && DECL_EXTERNAL (stmt))
909 struct cxx_int_tree_map *h, in;
910 in.uid = DECL_UID (stmt);
911 h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid);
912 if (h)
914 *stmt_p = h->to;
915 *walk_subtrees = 0;
916 return NULL;
920 /* Other than invisiref parms, don't walk the same tree twice. */
921 if (p_set->contains (stmt))
923 *walk_subtrees = 0;
924 return NULL_TREE;
927 if (TREE_CODE (stmt) == ADDR_EXPR
928 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
930 /* If in an OpenMP context, note var uses. */
931 if (__builtin_expect (wtd->omp_ctx != NULL, 0)
932 && omp_var_to_track (TREE_OPERAND (stmt, 0)))
933 omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
934 *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
935 *walk_subtrees = 0;
937 else if (TREE_CODE (stmt) == RETURN_EXPR
938 && TREE_OPERAND (stmt, 0)
939 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
940 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */
941 *walk_subtrees = 0;
942 else if (TREE_CODE (stmt) == OMP_CLAUSE)
943 switch (OMP_CLAUSE_CODE (stmt))
945 case OMP_CLAUSE_LASTPRIVATE:
946 /* Don't dereference an invisiref in OpenMP clauses. */
947 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
949 *walk_subtrees = 0;
950 if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
951 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
952 cp_genericize_r, data, NULL);
954 break;
955 case OMP_CLAUSE_PRIVATE:
956 /* Don't dereference an invisiref in OpenMP clauses. */
957 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
958 *walk_subtrees = 0;
959 else if (wtd->omp_ctx != NULL)
961 /* Private clause doesn't cause any references to the
962 var in outer contexts, avoid calling
963 omp_cxx_notice_variable for it. */
964 struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
965 wtd->omp_ctx = NULL;
966 cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
967 data, NULL);
968 wtd->omp_ctx = old;
969 *walk_subtrees = 0;
971 break;
972 case OMP_CLAUSE_SHARED:
973 case OMP_CLAUSE_FIRSTPRIVATE:
974 case OMP_CLAUSE_COPYIN:
975 case OMP_CLAUSE_COPYPRIVATE:
976 /* Don't dereference an invisiref in OpenMP clauses. */
977 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
978 *walk_subtrees = 0;
979 break;
980 case OMP_CLAUSE_REDUCTION:
981 /* Don't dereference an invisiref in reduction clause's
982 OMP_CLAUSE_DECL either. OMP_CLAUSE_REDUCTION_{INIT,MERGE}
983 still needs to be genericized. */
984 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
986 *walk_subtrees = 0;
987 if (OMP_CLAUSE_REDUCTION_INIT (stmt))
988 cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
989 cp_genericize_r, data, NULL);
990 if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
991 cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
992 cp_genericize_r, data, NULL);
994 break;
995 default:
996 break;
998 else if (IS_TYPE_OR_DECL_P (stmt))
999 *walk_subtrees = 0;
1001 /* Due to the way voidify_wrapper_expr is written, we don't get a chance
1002 to lower this construct before scanning it, so we need to lower these
1003 before doing anything else. */
1004 else if (TREE_CODE (stmt) == CLEANUP_STMT)
1005 *stmt_p = build2_loc (EXPR_LOCATION (stmt),
1006 CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
1007 : TRY_FINALLY_EXPR,
1008 void_type_node,
1009 CLEANUP_BODY (stmt),
1010 CLEANUP_EXPR (stmt));
1012 else if (TREE_CODE (stmt) == IF_STMT)
1014 genericize_if_stmt (stmt_p);
1015 /* *stmt_p has changed, tail recurse to handle it again. */
1016 return cp_genericize_r (stmt_p, walk_subtrees, data);
1019 /* COND_EXPR might have incompatible types in branches if one or both
1020 arms are bitfields. Fix it up now. */
1021 else if (TREE_CODE (stmt) == COND_EXPR)
1023 tree type_left
1024 = (TREE_OPERAND (stmt, 1)
1025 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
1026 : NULL_TREE);
1027 tree type_right
1028 = (TREE_OPERAND (stmt, 2)
1029 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
1030 : NULL_TREE);
1031 if (type_left
1032 && !useless_type_conversion_p (TREE_TYPE (stmt),
1033 TREE_TYPE (TREE_OPERAND (stmt, 1))))
1035 TREE_OPERAND (stmt, 1)
1036 = fold_convert (type_left, TREE_OPERAND (stmt, 1));
1037 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1038 type_left));
1040 if (type_right
1041 && !useless_type_conversion_p (TREE_TYPE (stmt),
1042 TREE_TYPE (TREE_OPERAND (stmt, 2))))
1044 TREE_OPERAND (stmt, 2)
1045 = fold_convert (type_right, TREE_OPERAND (stmt, 2));
1046 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1047 type_right));
1051 else if (TREE_CODE (stmt) == BIND_EXPR)
1053 if (__builtin_expect (wtd->omp_ctx != NULL, 0))
1055 tree decl;
1056 for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
1057 if (VAR_P (decl)
1058 && !DECL_EXTERNAL (decl)
1059 && omp_var_to_track (decl))
1061 splay_tree_node n
1062 = splay_tree_lookup (wtd->omp_ctx->variables,
1063 (splay_tree_key) decl);
1064 if (n == NULL)
1065 splay_tree_insert (wtd->omp_ctx->variables,
1066 (splay_tree_key) decl,
1067 TREE_STATIC (decl)
1068 ? OMP_CLAUSE_DEFAULT_SHARED
1069 : OMP_CLAUSE_DEFAULT_PRIVATE);
1072 wtd->bind_expr_stack.safe_push (stmt);
1073 cp_walk_tree (&BIND_EXPR_BODY (stmt),
1074 cp_genericize_r, data, NULL);
1075 wtd->bind_expr_stack.pop ();
1078 else if (TREE_CODE (stmt) == USING_STMT)
1080 tree block = NULL_TREE;
1082 /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
1083 BLOCK, and append an IMPORTED_DECL to its
1084 BLOCK_VARS chained list. */
1085 if (wtd->bind_expr_stack.exists ())
1087 int i;
1088 for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
1089 if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
1090 break;
1092 if (block)
1094 tree using_directive;
1095 gcc_assert (TREE_OPERAND (stmt, 0));
1097 using_directive = make_node (IMPORTED_DECL);
1098 TREE_TYPE (using_directive) = void_type_node;
1100 IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
1101 = TREE_OPERAND (stmt, 0);
1102 DECL_CHAIN (using_directive) = BLOCK_VARS (block);
1103 BLOCK_VARS (block) = using_directive;
1105 /* The USING_STMT won't appear in GENERIC. */
1106 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1107 *walk_subtrees = 0;
1110 else if (TREE_CODE (stmt) == DECL_EXPR
1111 && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
1113 /* Using decls inside DECL_EXPRs are just dropped on the floor. */
1114 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1115 *walk_subtrees = 0;
1117 else if (TREE_CODE (stmt) == OMP_PARALLEL || TREE_CODE (stmt) == OMP_TASK)
1119 struct cp_genericize_omp_taskreg omp_ctx;
1120 tree c, decl;
1121 splay_tree_node n;
1123 *walk_subtrees = 0;
1124 cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
1125 omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
1126 omp_ctx.default_shared = omp_ctx.is_parallel;
1127 omp_ctx.outer = wtd->omp_ctx;
1128 omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
1129 wtd->omp_ctx = &omp_ctx;
1130 for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
1131 switch (OMP_CLAUSE_CODE (c))
1133 case OMP_CLAUSE_SHARED:
1134 case OMP_CLAUSE_PRIVATE:
1135 case OMP_CLAUSE_FIRSTPRIVATE:
1136 case OMP_CLAUSE_LASTPRIVATE:
1137 decl = OMP_CLAUSE_DECL (c);
1138 if (decl == error_mark_node || !omp_var_to_track (decl))
1139 break;
1140 n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
1141 if (n != NULL)
1142 break;
1143 splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
1144 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
1145 ? OMP_CLAUSE_DEFAULT_SHARED
1146 : OMP_CLAUSE_DEFAULT_PRIVATE);
1147 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE
1148 && omp_ctx.outer)
1149 omp_cxx_notice_variable (omp_ctx.outer, decl);
1150 break;
1151 case OMP_CLAUSE_DEFAULT:
1152 if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
1153 omp_ctx.default_shared = true;
1154 default:
1155 break;
1157 cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
1158 wtd->omp_ctx = omp_ctx.outer;
1159 splay_tree_delete (omp_ctx.variables);
1161 else if (TREE_CODE (stmt) == CONVERT_EXPR)
1162 gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
1163 else if (TREE_CODE (stmt) == FOR_STMT)
1164 genericize_for_stmt (stmt_p, walk_subtrees, data);
1165 else if (TREE_CODE (stmt) == WHILE_STMT)
1166 genericize_while_stmt (stmt_p, walk_subtrees, data);
1167 else if (TREE_CODE (stmt) == DO_STMT)
1168 genericize_do_stmt (stmt_p, walk_subtrees, data);
1169 else if (TREE_CODE (stmt) == SWITCH_STMT)
1170 genericize_switch_stmt (stmt_p, walk_subtrees, data);
1171 else if (TREE_CODE (stmt) == CONTINUE_STMT)
1172 genericize_continue_stmt (stmt_p);
1173 else if (TREE_CODE (stmt) == BREAK_STMT)
1174 genericize_break_stmt (stmt_p);
1175 else if (TREE_CODE (stmt) == OMP_FOR
1176 || TREE_CODE (stmt) == OMP_SIMD
1177 || TREE_CODE (stmt) == OMP_DISTRIBUTE)
1178 genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
1179 else if (TREE_CODE (stmt) == SIZEOF_EXPR)
1181 if (SIZEOF_EXPR_TYPE_P (stmt))
1182 *stmt_p
1183 = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (stmt, 0)),
1184 SIZEOF_EXPR, false);
1185 else if (TYPE_P (TREE_OPERAND (stmt, 0)))
1186 *stmt_p = cxx_sizeof_or_alignof_type (TREE_OPERAND (stmt, 0),
1187 SIZEOF_EXPR, false);
1188 else
1189 *stmt_p = cxx_sizeof_or_alignof_expr (TREE_OPERAND (stmt, 0),
1190 SIZEOF_EXPR, false);
1191 if (*stmt_p == error_mark_node)
1192 *stmt_p = size_one_node;
1193 return NULL;
1195 else if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1197 if (TREE_CODE (stmt) == NOP_EXPR
1198 && TREE_CODE (TREE_TYPE (stmt)) == REFERENCE_TYPE)
1199 ubsan_maybe_instrument_reference (stmt);
1200 else if (TREE_CODE (stmt) == CALL_EXPR)
1202 tree fn = CALL_EXPR_FN (stmt);
1203 if (fn != NULL_TREE
1204 && !error_operand_p (fn)
1205 && POINTER_TYPE_P (TREE_TYPE (fn))
1206 && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE)
1208 bool is_ctor
1209 = TREE_CODE (fn) == ADDR_EXPR
1210 && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
1211 && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0));
1212 ubsan_maybe_instrument_member_call (stmt, is_ctor);
1217 p_set->add (*stmt_p);
1219 return NULL;
1222 /* Lower C++ front end trees to GENERIC in T_P. */
1224 static void
1225 cp_genericize_tree (tree* t_p)
1227 struct cp_genericize_data wtd;
1229 wtd.p_set = new hash_set<tree>;
1230 wtd.bind_expr_stack.create (0);
1231 wtd.omp_ctx = NULL;
1232 cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
1233 delete wtd.p_set;
1234 wtd.bind_expr_stack.release ();
1237 /* If a function that should end with a return in non-void
1238 function doesn't obviously end with return, add ubsan
1239 instrumentation code to verify it at runtime. */
1241 static void
1242 cp_ubsan_maybe_instrument_return (tree fndecl)
1244 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
1245 || DECL_CONSTRUCTOR_P (fndecl)
1246 || DECL_DESTRUCTOR_P (fndecl)
1247 || !targetm.warn_func_return (fndecl))
1248 return;
1250 tree t = DECL_SAVED_TREE (fndecl);
1251 while (t)
1253 switch (TREE_CODE (t))
1255 case BIND_EXPR:
1256 t = BIND_EXPR_BODY (t);
1257 continue;
1258 case TRY_FINALLY_EXPR:
1259 t = TREE_OPERAND (t, 0);
1260 continue;
1261 case STATEMENT_LIST:
1263 tree_stmt_iterator i = tsi_last (t);
1264 if (!tsi_end_p (i))
1266 t = tsi_stmt (i);
1267 continue;
1270 break;
1271 case RETURN_EXPR:
1272 return;
1273 default:
1274 break;
1276 break;
1278 if (t == NULL_TREE)
1279 return;
1280 t = DECL_SAVED_TREE (fndecl);
1281 if (TREE_CODE (t) == BIND_EXPR
1282 && TREE_CODE (BIND_EXPR_BODY (t)) == STATEMENT_LIST)
1284 tree_stmt_iterator i = tsi_last (BIND_EXPR_BODY (t));
1285 t = ubsan_instrument_return (DECL_SOURCE_LOCATION (fndecl));
1286 tsi_link_after (&i, t, TSI_NEW_STMT);
1290 void
1291 cp_genericize (tree fndecl)
1293 tree t;
1295 /* Fix up the types of parms passed by invisible reference. */
1296 for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
1297 if (TREE_ADDRESSABLE (TREE_TYPE (t)))
1299 /* If a function's arguments are copied to create a thunk,
1300 then DECL_BY_REFERENCE will be set -- but the type of the
1301 argument will be a pointer type, so we will never get
1302 here. */
1303 gcc_assert (!DECL_BY_REFERENCE (t));
1304 gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
1305 TREE_TYPE (t) = DECL_ARG_TYPE (t);
1306 DECL_BY_REFERENCE (t) = 1;
1307 TREE_ADDRESSABLE (t) = 0;
1308 relayout_decl (t);
1311 /* Do the same for the return value. */
1312 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
1314 t = DECL_RESULT (fndecl);
1315 TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
1316 DECL_BY_REFERENCE (t) = 1;
1317 TREE_ADDRESSABLE (t) = 0;
1318 relayout_decl (t);
1319 if (DECL_NAME (t))
1321 /* Adjust DECL_VALUE_EXPR of the original var. */
1322 tree outer = outer_curly_brace_block (current_function_decl);
1323 tree var;
1325 if (outer)
1326 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1327 if (DECL_NAME (t) == DECL_NAME (var)
1328 && DECL_HAS_VALUE_EXPR_P (var)
1329 && DECL_VALUE_EXPR (var) == t)
1331 tree val = convert_from_reference (t);
1332 SET_DECL_VALUE_EXPR (var, val);
1333 break;
1338 /* If we're a clone, the body is already GIMPLE. */
1339 if (DECL_CLONED_FUNCTION_P (fndecl))
1340 return;
1342 /* Expand all the array notations here. */
1343 if (flag_cilkplus
1344 && contains_array_notation_expr (DECL_SAVED_TREE (fndecl)))
1345 DECL_SAVED_TREE (fndecl) =
1346 expand_array_notation_exprs (DECL_SAVED_TREE (fndecl));
1348 /* We do want to see every occurrence of the parms, so we can't just use
1349 walk_tree's hash functionality. */
1350 cp_genericize_tree (&DECL_SAVED_TREE (fndecl));
1352 if (flag_sanitize & SANITIZE_RETURN
1353 && current_function_decl != NULL_TREE
1354 && !lookup_attribute ("no_sanitize_undefined",
1355 DECL_ATTRIBUTES (current_function_decl)))
1356 cp_ubsan_maybe_instrument_return (fndecl);
1358 /* Do everything else. */
1359 c_genericize (fndecl);
1361 gcc_assert (bc_label[bc_break] == NULL);
1362 gcc_assert (bc_label[bc_continue] == NULL);
1365 /* Build code to apply FN to each member of ARG1 and ARG2. FN may be
1366 NULL if there is in fact nothing to do. ARG2 may be null if FN
1367 actually only takes one argument. */
1369 static tree
1370 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
1372 tree defparm, parm, t;
1373 int i = 0;
1374 int nargs;
1375 tree *argarray;
1377 if (fn == NULL)
1378 return NULL;
1380 nargs = list_length (DECL_ARGUMENTS (fn));
1381 argarray = XALLOCAVEC (tree, nargs);
1383 defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
1384 if (arg2)
1385 defparm = TREE_CHAIN (defparm);
1387 if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
1389 tree inner_type = TREE_TYPE (arg1);
1390 tree start1, end1, p1;
1391 tree start2 = NULL, p2 = NULL;
1392 tree ret = NULL, lab;
1394 start1 = arg1;
1395 start2 = arg2;
1398 inner_type = TREE_TYPE (inner_type);
1399 start1 = build4 (ARRAY_REF, inner_type, start1,
1400 size_zero_node, NULL, NULL);
1401 if (arg2)
1402 start2 = build4 (ARRAY_REF, inner_type, start2,
1403 size_zero_node, NULL, NULL);
1405 while (TREE_CODE (inner_type) == ARRAY_TYPE);
1406 start1 = build_fold_addr_expr_loc (input_location, start1);
1407 if (arg2)
1408 start2 = build_fold_addr_expr_loc (input_location, start2);
1410 end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
1411 end1 = fold_build_pointer_plus (start1, end1);
1413 p1 = create_tmp_var (TREE_TYPE (start1), NULL);
1414 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
1415 append_to_statement_list (t, &ret);
1417 if (arg2)
1419 p2 = create_tmp_var (TREE_TYPE (start2), NULL);
1420 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
1421 append_to_statement_list (t, &ret);
1424 lab = create_artificial_label (input_location);
1425 t = build1 (LABEL_EXPR, void_type_node, lab);
1426 append_to_statement_list (t, &ret);
1428 argarray[i++] = p1;
1429 if (arg2)
1430 argarray[i++] = p2;
1431 /* Handle default arguments. */
1432 for (parm = defparm; parm && parm != void_list_node;
1433 parm = TREE_CHAIN (parm), i++)
1434 argarray[i] = convert_default_arg (TREE_VALUE (parm),
1435 TREE_PURPOSE (parm), fn, i,
1436 tf_warning_or_error);
1437 t = build_call_a (fn, i, argarray);
1438 t = fold_convert (void_type_node, t);
1439 t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1440 append_to_statement_list (t, &ret);
1442 t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type));
1443 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
1444 append_to_statement_list (t, &ret);
1446 if (arg2)
1448 t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type));
1449 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
1450 append_to_statement_list (t, &ret);
1453 t = build2 (NE_EXPR, boolean_type_node, p1, end1);
1454 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
1455 append_to_statement_list (t, &ret);
1457 return ret;
1459 else
1461 argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
1462 if (arg2)
1463 argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
1464 /* Handle default arguments. */
1465 for (parm = defparm; parm && parm != void_list_node;
1466 parm = TREE_CHAIN (parm), i++)
1467 argarray[i] = convert_default_arg (TREE_VALUE (parm),
1468 TREE_PURPOSE (parm),
1469 fn, i, tf_warning_or_error);
1470 t = build_call_a (fn, i, argarray);
1471 t = fold_convert (void_type_node, t);
1472 return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1476 /* Return code to initialize DECL with its default constructor, or
1477 NULL if there's nothing to do. */
1479 tree
1480 cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/)
1482 tree info = CP_OMP_CLAUSE_INFO (clause);
1483 tree ret = NULL;
1485 if (info)
1486 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
1488 return ret;
1491 /* Return code to initialize DST with a copy constructor from SRC. */
1493 tree
1494 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
1496 tree info = CP_OMP_CLAUSE_INFO (clause);
1497 tree ret = NULL;
1499 if (info)
1500 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
1501 if (ret == NULL)
1502 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1504 return ret;
1507 /* Similarly, except use an assignment operator instead. */
1509 tree
1510 cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
1512 tree info = CP_OMP_CLAUSE_INFO (clause);
1513 tree ret = NULL;
1515 if (info)
1516 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
1517 if (ret == NULL)
1518 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1520 return ret;
1523 /* Return code to destroy DECL. */
1525 tree
1526 cxx_omp_clause_dtor (tree clause, tree decl)
1528 tree info = CP_OMP_CLAUSE_INFO (clause);
1529 tree ret = NULL;
1531 if (info)
1532 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
1534 return ret;
1537 /* True if OpenMP should privatize what this DECL points to rather
1538 than the DECL itself. */
1540 bool
1541 cxx_omp_privatize_by_reference (const_tree decl)
1543 return (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
1544 || is_invisiref_parm (decl));
1547 /* Return true if DECL is const qualified var having no mutable member. */
1548 bool
1549 cxx_omp_const_qual_no_mutable (tree decl)
1551 tree type = TREE_TYPE (decl);
1552 if (TREE_CODE (type) == REFERENCE_TYPE)
1554 if (!is_invisiref_parm (decl))
1555 return false;
1556 type = TREE_TYPE (type);
1558 if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
1560 /* NVR doesn't preserve const qualification of the
1561 variable's type. */
1562 tree outer = outer_curly_brace_block (current_function_decl);
1563 tree var;
1565 if (outer)
1566 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1567 if (DECL_NAME (decl) == DECL_NAME (var)
1568 && (TYPE_MAIN_VARIANT (type)
1569 == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
1571 if (TYPE_READONLY (TREE_TYPE (var)))
1572 type = TREE_TYPE (var);
1573 break;
1578 if (type == error_mark_node)
1579 return false;
1581 /* Variables with const-qualified type having no mutable member
1582 are predetermined shared. */
1583 if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
1584 return true;
1586 return false;
1589 /* True if OpenMP sharing attribute of DECL is predetermined. */
1591 enum omp_clause_default_kind
1592 cxx_omp_predetermined_sharing (tree decl)
1594 /* Static data members are predetermined shared. */
1595 if (TREE_STATIC (decl))
1597 tree ctx = CP_DECL_CONTEXT (decl);
1598 if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
1599 return OMP_CLAUSE_DEFAULT_SHARED;
1602 /* Const qualified vars having no mutable member are predetermined
1603 shared. */
1604 if (cxx_omp_const_qual_no_mutable (decl))
1605 return OMP_CLAUSE_DEFAULT_SHARED;
1607 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1610 /* Finalize an implicitly determined clause. */
1612 void
1613 cxx_omp_finish_clause (tree c, gimple_seq *)
1615 tree decl, inner_type;
1616 bool make_shared = false;
1618 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
1619 return;
1621 decl = OMP_CLAUSE_DECL (c);
1622 decl = require_complete_type (decl);
1623 inner_type = TREE_TYPE (decl);
1624 if (decl == error_mark_node)
1625 make_shared = true;
1626 else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1628 if (is_invisiref_parm (decl))
1629 inner_type = TREE_TYPE (inner_type);
1630 else
1632 error ("%qE implicitly determined as %<firstprivate%> has reference type",
1633 decl);
1634 make_shared = true;
1638 /* We're interested in the base element, not arrays. */
1639 while (TREE_CODE (inner_type) == ARRAY_TYPE)
1640 inner_type = TREE_TYPE (inner_type);
1642 /* Check for special function availability by building a call to one.
1643 Save the results, because later we won't be in the right context
1644 for making these queries. */
1645 if (!make_shared
1646 && CLASS_TYPE_P (inner_type)
1647 && cxx_omp_create_clause_info (c, inner_type, false, true, false, true))
1648 make_shared = true;
1650 if (make_shared)
1651 OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;