DR 1391
[official-gcc.git] / gcc / cp / cp-gimplify.c
blobd5a64fc667f712e1e2cb50794fa60e9d17f28161
1 /* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
3 Copyright (C) 2002-2015 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 "hash-set.h"
27 #include "machmode.h"
28 #include "vec.h"
29 #include "double-int.h"
30 #include "input.h"
31 #include "alias.h"
32 #include "symtab.h"
33 #include "wide-int.h"
34 #include "inchash.h"
35 #include "tree.h"
36 #include "stor-layout.h"
37 #include "cp-tree.h"
38 #include "c-family/c-common.h"
39 #include "tree-iterator.h"
40 #include "predict.h"
41 #include "hard-reg-set.h"
42 #include "input.h"
43 #include "function.h"
44 #include "basic-block.h"
45 #include "tree-ssa-alias.h"
46 #include "internal-fn.h"
47 #include "gimple-expr.h"
48 #include "is-a.h"
49 #include "gimple.h"
50 #include "gimplify.h"
51 #include "flags.h"
52 #include "splay-tree.h"
53 #include "target.h"
54 #include "c-family/c-ubsan.h"
55 #include "cilk.h"
56 #include "gimplify.h"
57 #include "gimple-expr.h"
59 /* Forward declarations. */
61 static tree cp_genericize_r (tree *, int *, void *);
62 static void cp_genericize_tree (tree*);
64 /* Local declarations. */
66 enum bc_t { bc_break = 0, bc_continue = 1 };
68 /* Stack of labels which are targets for "break" or "continue",
69 linked through TREE_CHAIN. */
70 static tree bc_label[2];
72 /* Begin a scope which can be exited by a break or continue statement. BC
73 indicates which.
75 Just creates a label with location LOCATION and pushes it into the current
76 context. */
78 static tree
79 begin_bc_block (enum bc_t bc, location_t location)
81 tree label = create_artificial_label (location);
82 DECL_CHAIN (label) = bc_label[bc];
83 bc_label[bc] = label;
84 if (bc == bc_break)
85 LABEL_DECL_BREAK (label) = true;
86 else
87 LABEL_DECL_CONTINUE (label) = true;
88 return label;
91 /* Finish a scope which can be exited by a break or continue statement.
92 LABEL was returned from the most recent call to begin_bc_block. BLOCK is
93 an expression for the contents of the scope.
95 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
96 BLOCK. Otherwise, just forget the label. */
98 static void
99 finish_bc_block (tree *block, enum bc_t bc, tree label)
101 gcc_assert (label == bc_label[bc]);
103 if (TREE_USED (label))
104 append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label),
105 block);
107 bc_label[bc] = DECL_CHAIN (label);
108 DECL_CHAIN (label) = NULL_TREE;
111 /* Get the LABEL_EXPR to represent a break or continue statement
112 in the current block scope. BC indicates which. */
114 static tree
115 get_bc_label (enum bc_t bc)
117 tree label = bc_label[bc];
119 /* Mark the label used for finish_bc_block. */
120 TREE_USED (label) = 1;
121 return label;
124 /* Genericize a TRY_BLOCK. */
126 static void
127 genericize_try_block (tree *stmt_p)
129 tree body = TRY_STMTS (*stmt_p);
130 tree cleanup = TRY_HANDLERS (*stmt_p);
132 *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
135 /* Genericize a HANDLER by converting to a CATCH_EXPR. */
137 static void
138 genericize_catch_block (tree *stmt_p)
140 tree type = HANDLER_TYPE (*stmt_p);
141 tree body = HANDLER_BODY (*stmt_p);
143 /* FIXME should the caught type go in TREE_TYPE? */
144 *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
147 /* A terser interface for building a representation of an exception
148 specification. */
150 static tree
151 build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
153 tree t;
155 /* FIXME should the allowed types go in TREE_TYPE? */
156 t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
157 append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
159 t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
160 append_to_statement_list (body, &TREE_OPERAND (t, 0));
162 return t;
165 /* Genericize an EH_SPEC_BLOCK by converting it to a
166 TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
168 static void
169 genericize_eh_spec_block (tree *stmt_p)
171 tree body = EH_SPEC_STMTS (*stmt_p);
172 tree allowed = EH_SPEC_RAISES (*stmt_p);
173 tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ());
175 *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
176 TREE_NO_WARNING (*stmt_p) = true;
177 TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true;
180 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
182 static void
183 genericize_if_stmt (tree *stmt_p)
185 tree stmt, cond, then_, else_;
186 location_t locus = EXPR_LOCATION (*stmt_p);
188 stmt = *stmt_p;
189 cond = IF_COND (stmt);
190 then_ = THEN_CLAUSE (stmt);
191 else_ = ELSE_CLAUSE (stmt);
193 if (!then_)
194 then_ = build_empty_stmt (locus);
195 if (!else_)
196 else_ = build_empty_stmt (locus);
198 if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
199 stmt = then_;
200 else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
201 stmt = else_;
202 else
203 stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
204 if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt))
205 SET_EXPR_LOCATION (stmt, locus);
206 *stmt_p = stmt;
209 /* Build a generic representation of one of the C loop forms. COND is the
210 loop condition or NULL_TREE. BODY is the (possibly compound) statement
211 controlled by the loop. INCR is the increment expression of a for-loop,
212 or NULL_TREE. COND_IS_FIRST indicates whether the condition is
213 evaluated before the loop body as in while and for loops, or after the
214 loop body as in do-while loops. */
216 static void
217 genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
218 tree incr, bool cond_is_first, int *walk_subtrees,
219 void *data)
221 tree blab, clab;
222 tree exit = NULL;
223 tree stmt_list = NULL;
225 blab = begin_bc_block (bc_break, start_locus);
226 clab = begin_bc_block (bc_continue, start_locus);
228 if (incr && EXPR_P (incr))
229 SET_EXPR_LOCATION (incr, start_locus);
231 cp_walk_tree (&cond, cp_genericize_r, data, NULL);
232 cp_walk_tree (&body, cp_genericize_r, data, NULL);
233 cp_walk_tree (&incr, cp_genericize_r, data, NULL);
234 *walk_subtrees = 0;
236 if (cond && TREE_CODE (cond) != INTEGER_CST)
238 /* If COND is constant, don't bother building an exit. If it's false,
239 we won't build a loop. If it's true, any exits are in the body. */
240 location_t cloc = EXPR_LOC_OR_LOC (cond, start_locus);
241 exit = build1_loc (cloc, GOTO_EXPR, void_type_node,
242 get_bc_label (bc_break));
243 exit = fold_build3_loc (cloc, COND_EXPR, void_type_node, cond,
244 build_empty_stmt (cloc), exit);
247 if (exit && cond_is_first)
248 append_to_statement_list (exit, &stmt_list);
249 append_to_statement_list (body, &stmt_list);
250 finish_bc_block (&stmt_list, bc_continue, clab);
251 append_to_statement_list (incr, &stmt_list);
252 if (exit && !cond_is_first)
253 append_to_statement_list (exit, &stmt_list);
255 if (!stmt_list)
256 stmt_list = build_empty_stmt (start_locus);
258 tree loop;
259 if (cond && integer_zerop (cond))
261 if (cond_is_first)
262 loop = fold_build3_loc (start_locus, COND_EXPR,
263 void_type_node, cond, stmt_list,
264 build_empty_stmt (start_locus));
265 else
266 loop = stmt_list;
268 else
269 loop = build1_loc (start_locus, LOOP_EXPR, void_type_node, stmt_list);
271 stmt_list = NULL;
272 append_to_statement_list (loop, &stmt_list);
273 finish_bc_block (&stmt_list, bc_break, blab);
274 if (!stmt_list)
275 stmt_list = build_empty_stmt (start_locus);
277 *stmt_p = stmt_list;
280 /* Genericize a FOR_STMT node *STMT_P. */
282 static void
283 genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
285 tree stmt = *stmt_p;
286 tree expr = NULL;
287 tree loop;
288 tree init = FOR_INIT_STMT (stmt);
290 if (init)
292 cp_walk_tree (&init, cp_genericize_r, data, NULL);
293 append_to_statement_list (init, &expr);
296 genericize_cp_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
297 FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees, data);
298 append_to_statement_list (loop, &expr);
299 if (expr == NULL_TREE)
300 expr = loop;
301 *stmt_p = expr;
304 /* Genericize a WHILE_STMT node *STMT_P. */
306 static void
307 genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data)
309 tree stmt = *stmt_p;
310 genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt),
311 WHILE_BODY (stmt), NULL_TREE, 1, walk_subtrees, data);
314 /* Genericize a DO_STMT node *STMT_P. */
316 static void
317 genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data)
319 tree stmt = *stmt_p;
320 genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt),
321 DO_BODY (stmt), NULL_TREE, 0, walk_subtrees, data);
324 /* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR. */
326 static void
327 genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data)
329 tree stmt = *stmt_p;
330 tree break_block, body, cond, type;
331 location_t stmt_locus = EXPR_LOCATION (stmt);
333 break_block = begin_bc_block (bc_break, stmt_locus);
335 body = SWITCH_STMT_BODY (stmt);
336 if (!body)
337 body = build_empty_stmt (stmt_locus);
338 cond = SWITCH_STMT_COND (stmt);
339 type = SWITCH_STMT_TYPE (stmt);
341 cp_walk_tree (&body, cp_genericize_r, data, NULL);
342 cp_walk_tree (&cond, cp_genericize_r, data, NULL);
343 cp_walk_tree (&type, cp_genericize_r, data, NULL);
344 *walk_subtrees = 0;
346 *stmt_p = build3_loc (stmt_locus, SWITCH_EXPR, type, cond, body, NULL_TREE);
347 finish_bc_block (stmt_p, bc_break, break_block);
350 /* Genericize a CONTINUE_STMT node *STMT_P. */
352 static void
353 genericize_continue_stmt (tree *stmt_p)
355 tree stmt_list = NULL;
356 tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN);
357 tree label = get_bc_label (bc_continue);
358 location_t location = EXPR_LOCATION (*stmt_p);
359 tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label);
360 append_to_statement_list (pred, &stmt_list);
361 append_to_statement_list (jump, &stmt_list);
362 *stmt_p = stmt_list;
365 /* Genericize a BREAK_STMT node *STMT_P. */
367 static void
368 genericize_break_stmt (tree *stmt_p)
370 tree label = get_bc_label (bc_break);
371 location_t location = EXPR_LOCATION (*stmt_p);
372 *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label);
375 /* Genericize a OMP_FOR node *STMT_P. */
377 static void
378 genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
380 tree stmt = *stmt_p;
381 location_t locus = EXPR_LOCATION (stmt);
382 tree clab = begin_bc_block (bc_continue, locus);
384 cp_walk_tree (&OMP_FOR_BODY (stmt), cp_genericize_r, data, NULL);
385 cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_genericize_r, data, NULL);
386 cp_walk_tree (&OMP_FOR_INIT (stmt), cp_genericize_r, data, NULL);
387 cp_walk_tree (&OMP_FOR_COND (stmt), cp_genericize_r, data, NULL);
388 cp_walk_tree (&OMP_FOR_INCR (stmt), cp_genericize_r, data, NULL);
389 cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_genericize_r, data, NULL);
390 *walk_subtrees = 0;
392 finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab);
395 /* Hook into the middle of gimplifying an OMP_FOR node. */
397 static enum gimplify_status
398 cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
400 tree for_stmt = *expr_p;
401 gimple_seq seq = NULL;
403 /* Protect ourselves from recursion. */
404 if (OMP_FOR_GIMPLIFYING_P (for_stmt))
405 return GS_UNHANDLED;
406 OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
408 gimplify_and_add (for_stmt, &seq);
409 gimple_seq_add_seq (pre_p, seq);
411 OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
413 return GS_ALL_DONE;
416 /* Gimplify an EXPR_STMT node. */
418 static void
419 gimplify_expr_stmt (tree *stmt_p)
421 tree stmt = EXPR_STMT_EXPR (*stmt_p);
423 if (stmt == error_mark_node)
424 stmt = NULL;
426 /* Gimplification of a statement expression will nullify the
427 statement if all its side effects are moved to *PRE_P and *POST_P.
429 In this case we will not want to emit the gimplified statement.
430 However, we may still want to emit a warning, so we do that before
431 gimplification. */
432 if (stmt && warn_unused_value)
434 if (!TREE_SIDE_EFFECTS (stmt))
436 if (!IS_EMPTY_STMT (stmt)
437 && !VOID_TYPE_P (TREE_TYPE (stmt))
438 && !TREE_NO_WARNING (stmt))
439 warning (OPT_Wunused_value, "statement with no effect");
441 else
442 warn_if_unused_value (stmt, input_location);
445 if (stmt == NULL_TREE)
446 stmt = alloc_stmt_list ();
448 *stmt_p = stmt;
451 /* Gimplify initialization from an AGGR_INIT_EXPR. */
453 static void
454 cp_gimplify_init_expr (tree *expr_p)
456 tree from = TREE_OPERAND (*expr_p, 1);
457 tree to = TREE_OPERAND (*expr_p, 0);
458 tree t;
460 /* What about code that pulls out the temp and uses it elsewhere? I
461 think that such code never uses the TARGET_EXPR as an initializer. If
462 I'm wrong, we'll abort because the temp won't have any RTL. In that
463 case, I guess we'll need to replace references somehow. */
464 if (TREE_CODE (from) == TARGET_EXPR)
465 from = TARGET_EXPR_INITIAL (from);
467 /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
468 inside the TARGET_EXPR. */
469 for (t = from; t; )
471 tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
473 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
474 replace the slot operand with our target.
476 Should we add a target parm to gimplify_expr instead? No, as in this
477 case we want to replace the INIT_EXPR. */
478 if (TREE_CODE (sub) == AGGR_INIT_EXPR
479 || TREE_CODE (sub) == VEC_INIT_EXPR)
481 if (TREE_CODE (sub) == AGGR_INIT_EXPR)
482 AGGR_INIT_EXPR_SLOT (sub) = to;
483 else
484 VEC_INIT_EXPR_SLOT (sub) = to;
485 *expr_p = from;
487 /* The initialization is now a side-effect, so the container can
488 become void. */
489 if (from != sub)
490 TREE_TYPE (from) = void_type_node;
493 if (cxx_dialect >= cxx14 && TREE_CODE (sub) == CONSTRUCTOR)
494 /* Handle aggregate NSDMI. */
495 replace_placeholders (sub, to);
497 if (t == sub)
498 break;
499 else
500 t = TREE_OPERAND (t, 1);
505 /* Gimplify a MUST_NOT_THROW_EXPR. */
507 static enum gimplify_status
508 gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
510 tree stmt = *expr_p;
511 tree temp = voidify_wrapper_expr (stmt, NULL);
512 tree body = TREE_OPERAND (stmt, 0);
513 gimple_seq try_ = NULL;
514 gimple_seq catch_ = NULL;
515 gimple mnt;
517 gimplify_and_add (body, &try_);
518 mnt = gimple_build_eh_must_not_throw (terminate_node);
519 gimple_seq_add_stmt_without_update (&catch_, mnt);
520 mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
522 gimple_seq_add_stmt_without_update (pre_p, mnt);
523 if (temp)
525 *expr_p = temp;
526 return GS_OK;
529 *expr_p = NULL;
530 return GS_ALL_DONE;
533 /* Return TRUE if an operand (OP) of a given TYPE being copied is
534 really just an empty class copy.
536 Check that the operand has a simple form so that TARGET_EXPRs and
537 non-empty CONSTRUCTORs get reduced properly, and we leave the
538 return slot optimization alone because it isn't a copy. */
540 static bool
541 simple_empty_class_p (tree type, tree op)
543 return
544 ((TREE_CODE (op) == COMPOUND_EXPR
545 && simple_empty_class_p (type, TREE_OPERAND (op, 1)))
546 || is_gimple_lvalue (op)
547 || INDIRECT_REF_P (op)
548 || (TREE_CODE (op) == CONSTRUCTOR
549 && CONSTRUCTOR_NELTS (op) == 0
550 && !TREE_CLOBBER_P (op))
551 || (TREE_CODE (op) == CALL_EXPR
552 && !CALL_EXPR_RETURN_SLOT_OPT (op)))
553 && is_really_empty_class (type);
556 /* Do C++-specific gimplification. Args are as for gimplify_expr. */
559 cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
561 int saved_stmts_are_full_exprs_p = 0;
562 enum tree_code code = TREE_CODE (*expr_p);
563 enum gimplify_status ret;
565 if (STATEMENT_CODE_P (code))
567 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
568 current_stmt_tree ()->stmts_are_full_exprs_p
569 = STMT_IS_FULL_EXPR_P (*expr_p);
572 switch (code)
574 case PTRMEM_CST:
575 *expr_p = cplus_expand_constant (*expr_p);
576 ret = GS_OK;
577 break;
579 case AGGR_INIT_EXPR:
580 simplify_aggr_init_expr (expr_p);
581 ret = GS_OK;
582 break;
584 case VEC_INIT_EXPR:
586 location_t loc = input_location;
587 tree init = VEC_INIT_EXPR_INIT (*expr_p);
588 int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
589 gcc_assert (EXPR_HAS_LOCATION (*expr_p));
590 input_location = EXPR_LOCATION (*expr_p);
591 *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
592 init, VEC_INIT_EXPR_VALUE_INIT (*expr_p),
593 from_array,
594 tf_warning_or_error);
595 cp_genericize_tree (expr_p);
596 ret = GS_OK;
597 input_location = loc;
599 break;
601 case THROW_EXPR:
602 /* FIXME communicate throw type to back end, probably by moving
603 THROW_EXPR into ../tree.def. */
604 *expr_p = TREE_OPERAND (*expr_p, 0);
605 ret = GS_OK;
606 break;
608 case MUST_NOT_THROW_EXPR:
609 ret = gimplify_must_not_throw_expr (expr_p, pre_p);
610 break;
612 /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
613 LHS of an assignment might also be involved in the RHS, as in bug
614 25979. */
615 case INIT_EXPR:
616 if (fn_contains_cilk_spawn_p (cfun)
617 && cilk_detect_spawn_and_unwrap (expr_p)
618 && !seen_error ())
619 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
620 cp_gimplify_init_expr (expr_p);
621 if (TREE_CODE (*expr_p) != INIT_EXPR)
622 return GS_OK;
623 /* Otherwise fall through. */
624 case MODIFY_EXPR:
625 modify_expr_case:
627 if (fn_contains_cilk_spawn_p (cfun)
628 && cilk_detect_spawn_and_unwrap (expr_p)
629 && !seen_error ())
630 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
632 /* If the back end isn't clever enough to know that the lhs and rhs
633 types are the same, add an explicit conversion. */
634 tree op0 = TREE_OPERAND (*expr_p, 0);
635 tree op1 = TREE_OPERAND (*expr_p, 1);
637 if (!error_operand_p (op0)
638 && !error_operand_p (op1)
639 && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
640 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
641 && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
642 TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
643 TREE_TYPE (op0), op1);
645 else if (simple_empty_class_p (TREE_TYPE (op0), op1))
647 /* Remove any copies of empty classes. Also drop volatile
648 variables on the RHS to avoid infinite recursion from
649 gimplify_expr trying to load the value. */
650 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
651 is_gimple_lvalue, fb_lvalue);
652 if (TREE_SIDE_EFFECTS (op1))
654 if (TREE_THIS_VOLATILE (op1)
655 && (REFERENCE_CLASS_P (op1) || DECL_P (op1)))
656 op1 = build_fold_addr_expr (op1);
658 gimplify_and_add (op1, pre_p);
660 *expr_p = TREE_OPERAND (*expr_p, 0);
663 ret = GS_OK;
664 break;
666 case EMPTY_CLASS_EXPR:
667 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
668 *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
669 ret = GS_OK;
670 break;
672 case BASELINK:
673 *expr_p = BASELINK_FUNCTIONS (*expr_p);
674 ret = GS_OK;
675 break;
677 case TRY_BLOCK:
678 genericize_try_block (expr_p);
679 ret = GS_OK;
680 break;
682 case HANDLER:
683 genericize_catch_block (expr_p);
684 ret = GS_OK;
685 break;
687 case EH_SPEC_BLOCK:
688 genericize_eh_spec_block (expr_p);
689 ret = GS_OK;
690 break;
692 case USING_STMT:
693 gcc_unreachable ();
695 case FOR_STMT:
696 case WHILE_STMT:
697 case DO_STMT:
698 case SWITCH_STMT:
699 case CONTINUE_STMT:
700 case BREAK_STMT:
701 gcc_unreachable ();
703 case OMP_FOR:
704 case OMP_SIMD:
705 case OMP_DISTRIBUTE:
706 ret = cp_gimplify_omp_for (expr_p, pre_p);
707 break;
709 case EXPR_STMT:
710 gimplify_expr_stmt (expr_p);
711 ret = GS_OK;
712 break;
714 case UNARY_PLUS_EXPR:
716 tree arg = TREE_OPERAND (*expr_p, 0);
717 tree type = TREE_TYPE (*expr_p);
718 *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
719 : arg;
720 ret = GS_OK;
722 break;
724 case CILK_SPAWN_STMT:
725 gcc_assert
726 (fn_contains_cilk_spawn_p (cfun)
727 && cilk_detect_spawn_and_unwrap (expr_p));
729 /* If errors are seen, then just process it as a CALL_EXPR. */
730 if (!seen_error ())
731 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
733 case CALL_EXPR:
734 if (fn_contains_cilk_spawn_p (cfun)
735 && cilk_detect_spawn_and_unwrap (expr_p)
736 && !seen_error ())
737 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
739 /* DR 1030 says that we need to evaluate the elements of an
740 initializer-list in forward order even when it's used as arguments to
741 a constructor. So if the target wants to evaluate them in reverse
742 order and there's more than one argument other than 'this', gimplify
743 them in order. */
744 ret = GS_OK;
745 if (PUSH_ARGS_REVERSED && CALL_EXPR_LIST_INIT_P (*expr_p)
746 && call_expr_nargs (*expr_p) > 2)
748 int nargs = call_expr_nargs (*expr_p);
749 location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location);
750 for (int i = 1; i < nargs; ++i)
752 enum gimplify_status t
753 = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc);
754 if (t == GS_ERROR)
755 ret = GS_ERROR;
758 break;
760 case RETURN_EXPR:
761 if (TREE_OPERAND (*expr_p, 0)
762 && (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == INIT_EXPR
763 || TREE_CODE (TREE_OPERAND (*expr_p, 0)) == MODIFY_EXPR))
765 expr_p = &TREE_OPERAND (*expr_p, 0);
766 code = TREE_CODE (*expr_p);
767 /* Avoid going through the INIT_EXPR case, which can
768 degrade INIT_EXPRs into AGGR_INIT_EXPRs. */
769 goto modify_expr_case;
771 /* Fall through. */
773 default:
774 ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
775 break;
778 /* Restore saved state. */
779 if (STATEMENT_CODE_P (code))
780 current_stmt_tree ()->stmts_are_full_exprs_p
781 = saved_stmts_are_full_exprs_p;
783 return ret;
786 static inline bool
787 is_invisiref_parm (const_tree t)
789 return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
790 && DECL_BY_REFERENCE (t));
793 /* Return true if the uid in both int tree maps are equal. */
795 bool
796 cxx_int_tree_map_hasher::equal (cxx_int_tree_map *a, cxx_int_tree_map *b)
798 return (a->uid == b->uid);
801 /* Hash a UID in a cxx_int_tree_map. */
803 unsigned int
804 cxx_int_tree_map_hasher::hash (cxx_int_tree_map *item)
806 return item->uid;
809 /* A stable comparison routine for use with splay trees and DECLs. */
811 static int
812 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
814 tree a = (tree) xa;
815 tree b = (tree) xb;
817 return DECL_UID (a) - DECL_UID (b);
820 /* OpenMP context during genericization. */
822 struct cp_genericize_omp_taskreg
824 bool is_parallel;
825 bool default_shared;
826 struct cp_genericize_omp_taskreg *outer;
827 splay_tree variables;
830 /* Return true if genericization should try to determine if
831 DECL is firstprivate or shared within task regions. */
833 static bool
834 omp_var_to_track (tree decl)
836 tree type = TREE_TYPE (decl);
837 if (is_invisiref_parm (decl))
838 type = TREE_TYPE (type);
839 while (TREE_CODE (type) == ARRAY_TYPE)
840 type = TREE_TYPE (type);
841 if (type == error_mark_node || !CLASS_TYPE_P (type))
842 return false;
843 if (VAR_P (decl) && DECL_THREAD_LOCAL_P (decl))
844 return false;
845 if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
846 return false;
847 return true;
850 /* Note DECL use in OpenMP region OMP_CTX during genericization. */
852 static void
853 omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl)
855 splay_tree_node n = splay_tree_lookup (omp_ctx->variables,
856 (splay_tree_key) decl);
857 if (n == NULL)
859 int flags = OMP_CLAUSE_DEFAULT_SHARED;
860 if (omp_ctx->outer)
861 omp_cxx_notice_variable (omp_ctx->outer, decl);
862 if (!omp_ctx->default_shared)
864 struct cp_genericize_omp_taskreg *octx;
866 for (octx = omp_ctx->outer; octx; octx = octx->outer)
868 n = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
869 if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED)
871 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
872 break;
874 if (octx->is_parallel)
875 break;
877 if (octx == NULL
878 && (TREE_CODE (decl) == PARM_DECL
879 || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl))
880 && DECL_CONTEXT (decl) == current_function_decl)))
881 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
882 if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
884 /* DECL is implicitly determined firstprivate in
885 the current task construct. Ensure copy ctor and
886 dtor are instantiated, because during gimplification
887 it will be already too late. */
888 tree type = TREE_TYPE (decl);
889 if (is_invisiref_parm (decl))
890 type = TREE_TYPE (type);
891 while (TREE_CODE (type) == ARRAY_TYPE)
892 type = TREE_TYPE (type);
893 get_copy_ctor (type, tf_none);
894 get_dtor (type, tf_none);
897 splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags);
901 /* Genericization context. */
903 struct cp_genericize_data
905 hash_set<tree> *p_set;
906 vec<tree> bind_expr_stack;
907 struct cp_genericize_omp_taskreg *omp_ctx;
908 tree try_block;
911 /* Perform any pre-gimplification lowering of C++ front end trees to
912 GENERIC. */
914 static tree
915 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
917 tree stmt = *stmt_p;
918 struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
919 hash_set<tree> *p_set = wtd->p_set;
921 /* If in an OpenMP context, note var uses. */
922 if (__builtin_expect (wtd->omp_ctx != NULL, 0)
923 && (VAR_P (stmt)
924 || TREE_CODE (stmt) == PARM_DECL
925 || TREE_CODE (stmt) == RESULT_DECL)
926 && omp_var_to_track (stmt))
927 omp_cxx_notice_variable (wtd->omp_ctx, stmt);
929 if (is_invisiref_parm (stmt)
930 /* Don't dereference parms in a thunk, pass the references through. */
931 && !(DECL_THUNK_P (current_function_decl)
932 && TREE_CODE (stmt) == PARM_DECL))
934 *stmt_p = convert_from_reference (stmt);
935 *walk_subtrees = 0;
936 return NULL;
939 /* Map block scope extern declarations to visible declarations with the
940 same name and type in outer scopes if any. */
941 if (cp_function_chain->extern_decl_map
942 && VAR_OR_FUNCTION_DECL_P (stmt)
943 && DECL_EXTERNAL (stmt))
945 struct cxx_int_tree_map *h, in;
946 in.uid = DECL_UID (stmt);
947 h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid);
948 if (h)
950 *stmt_p = h->to;
951 *walk_subtrees = 0;
952 return NULL;
956 /* Other than invisiref parms, don't walk the same tree twice. */
957 if (p_set->contains (stmt))
959 *walk_subtrees = 0;
960 return NULL_TREE;
963 if (TREE_CODE (stmt) == ADDR_EXPR
964 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
966 /* If in an OpenMP context, note var uses. */
967 if (__builtin_expect (wtd->omp_ctx != NULL, 0)
968 && omp_var_to_track (TREE_OPERAND (stmt, 0)))
969 omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
970 *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
971 *walk_subtrees = 0;
973 else if (TREE_CODE (stmt) == RETURN_EXPR
974 && TREE_OPERAND (stmt, 0)
975 && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
976 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */
977 *walk_subtrees = 0;
978 else if (TREE_CODE (stmt) == OMP_CLAUSE)
979 switch (OMP_CLAUSE_CODE (stmt))
981 case OMP_CLAUSE_LASTPRIVATE:
982 /* Don't dereference an invisiref in OpenMP clauses. */
983 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
985 *walk_subtrees = 0;
986 if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
987 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
988 cp_genericize_r, data, NULL);
990 break;
991 case OMP_CLAUSE_PRIVATE:
992 /* Don't dereference an invisiref in OpenMP clauses. */
993 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
994 *walk_subtrees = 0;
995 else if (wtd->omp_ctx != NULL)
997 /* Private clause doesn't cause any references to the
998 var in outer contexts, avoid calling
999 omp_cxx_notice_variable for it. */
1000 struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
1001 wtd->omp_ctx = NULL;
1002 cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
1003 data, NULL);
1004 wtd->omp_ctx = old;
1005 *walk_subtrees = 0;
1007 break;
1008 case OMP_CLAUSE_SHARED:
1009 case OMP_CLAUSE_FIRSTPRIVATE:
1010 case OMP_CLAUSE_COPYIN:
1011 case OMP_CLAUSE_COPYPRIVATE:
1012 /* Don't dereference an invisiref in OpenMP clauses. */
1013 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1014 *walk_subtrees = 0;
1015 break;
1016 case OMP_CLAUSE_REDUCTION:
1017 /* Don't dereference an invisiref in reduction clause's
1018 OMP_CLAUSE_DECL either. OMP_CLAUSE_REDUCTION_{INIT,MERGE}
1019 still needs to be genericized. */
1020 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1022 *walk_subtrees = 0;
1023 if (OMP_CLAUSE_REDUCTION_INIT (stmt))
1024 cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
1025 cp_genericize_r, data, NULL);
1026 if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
1027 cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
1028 cp_genericize_r, data, NULL);
1030 break;
1031 default:
1032 break;
1034 else if (IS_TYPE_OR_DECL_P (stmt))
1035 *walk_subtrees = 0;
1037 /* Due to the way voidify_wrapper_expr is written, we don't get a chance
1038 to lower this construct before scanning it, so we need to lower these
1039 before doing anything else. */
1040 else if (TREE_CODE (stmt) == CLEANUP_STMT)
1041 *stmt_p = build2_loc (EXPR_LOCATION (stmt),
1042 CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
1043 : TRY_FINALLY_EXPR,
1044 void_type_node,
1045 CLEANUP_BODY (stmt),
1046 CLEANUP_EXPR (stmt));
1048 else if (TREE_CODE (stmt) == IF_STMT)
1050 genericize_if_stmt (stmt_p);
1051 /* *stmt_p has changed, tail recurse to handle it again. */
1052 return cp_genericize_r (stmt_p, walk_subtrees, data);
1055 /* COND_EXPR might have incompatible types in branches if one or both
1056 arms are bitfields. Fix it up now. */
1057 else if (TREE_CODE (stmt) == COND_EXPR)
1059 tree type_left
1060 = (TREE_OPERAND (stmt, 1)
1061 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
1062 : NULL_TREE);
1063 tree type_right
1064 = (TREE_OPERAND (stmt, 2)
1065 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
1066 : NULL_TREE);
1067 if (type_left
1068 && !useless_type_conversion_p (TREE_TYPE (stmt),
1069 TREE_TYPE (TREE_OPERAND (stmt, 1))))
1071 TREE_OPERAND (stmt, 1)
1072 = fold_convert (type_left, TREE_OPERAND (stmt, 1));
1073 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1074 type_left));
1076 if (type_right
1077 && !useless_type_conversion_p (TREE_TYPE (stmt),
1078 TREE_TYPE (TREE_OPERAND (stmt, 2))))
1080 TREE_OPERAND (stmt, 2)
1081 = fold_convert (type_right, TREE_OPERAND (stmt, 2));
1082 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1083 type_right));
1087 else if (TREE_CODE (stmt) == BIND_EXPR)
1089 if (__builtin_expect (wtd->omp_ctx != NULL, 0))
1091 tree decl;
1092 for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
1093 if (VAR_P (decl)
1094 && !DECL_EXTERNAL (decl)
1095 && omp_var_to_track (decl))
1097 splay_tree_node n
1098 = splay_tree_lookup (wtd->omp_ctx->variables,
1099 (splay_tree_key) decl);
1100 if (n == NULL)
1101 splay_tree_insert (wtd->omp_ctx->variables,
1102 (splay_tree_key) decl,
1103 TREE_STATIC (decl)
1104 ? OMP_CLAUSE_DEFAULT_SHARED
1105 : OMP_CLAUSE_DEFAULT_PRIVATE);
1108 wtd->bind_expr_stack.safe_push (stmt);
1109 cp_walk_tree (&BIND_EXPR_BODY (stmt),
1110 cp_genericize_r, data, NULL);
1111 wtd->bind_expr_stack.pop ();
1114 else if (TREE_CODE (stmt) == USING_STMT)
1116 tree block = NULL_TREE;
1118 /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
1119 BLOCK, and append an IMPORTED_DECL to its
1120 BLOCK_VARS chained list. */
1121 if (wtd->bind_expr_stack.exists ())
1123 int i;
1124 for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
1125 if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
1126 break;
1128 if (block)
1130 tree using_directive;
1131 gcc_assert (TREE_OPERAND (stmt, 0));
1133 using_directive = make_node (IMPORTED_DECL);
1134 TREE_TYPE (using_directive) = void_type_node;
1136 IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
1137 = TREE_OPERAND (stmt, 0);
1138 DECL_CHAIN (using_directive) = BLOCK_VARS (block);
1139 BLOCK_VARS (block) = using_directive;
1141 /* The USING_STMT won't appear in GENERIC. */
1142 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1143 *walk_subtrees = 0;
1146 else if (TREE_CODE (stmt) == DECL_EXPR
1147 && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
1149 /* Using decls inside DECL_EXPRs are just dropped on the floor. */
1150 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1151 *walk_subtrees = 0;
1153 else if (TREE_CODE (stmt) == OMP_PARALLEL || TREE_CODE (stmt) == OMP_TASK)
1155 struct cp_genericize_omp_taskreg omp_ctx;
1156 tree c, decl;
1157 splay_tree_node n;
1159 *walk_subtrees = 0;
1160 cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
1161 omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
1162 omp_ctx.default_shared = omp_ctx.is_parallel;
1163 omp_ctx.outer = wtd->omp_ctx;
1164 omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
1165 wtd->omp_ctx = &omp_ctx;
1166 for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
1167 switch (OMP_CLAUSE_CODE (c))
1169 case OMP_CLAUSE_SHARED:
1170 case OMP_CLAUSE_PRIVATE:
1171 case OMP_CLAUSE_FIRSTPRIVATE:
1172 case OMP_CLAUSE_LASTPRIVATE:
1173 decl = OMP_CLAUSE_DECL (c);
1174 if (decl == error_mark_node || !omp_var_to_track (decl))
1175 break;
1176 n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
1177 if (n != NULL)
1178 break;
1179 splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
1180 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
1181 ? OMP_CLAUSE_DEFAULT_SHARED
1182 : OMP_CLAUSE_DEFAULT_PRIVATE);
1183 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE
1184 && omp_ctx.outer)
1185 omp_cxx_notice_variable (omp_ctx.outer, decl);
1186 break;
1187 case OMP_CLAUSE_DEFAULT:
1188 if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
1189 omp_ctx.default_shared = true;
1190 default:
1191 break;
1193 cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
1194 wtd->omp_ctx = omp_ctx.outer;
1195 splay_tree_delete (omp_ctx.variables);
1197 else if (TREE_CODE (stmt) == TRY_BLOCK)
1199 *walk_subtrees = 0;
1200 tree try_block = wtd->try_block;
1201 wtd->try_block = stmt;
1202 cp_walk_tree (&TRY_STMTS (stmt), cp_genericize_r, data, NULL);
1203 wtd->try_block = try_block;
1204 cp_walk_tree (&TRY_HANDLERS (stmt), cp_genericize_r, data, NULL);
1206 else if (TREE_CODE (stmt) == MUST_NOT_THROW_EXPR)
1208 /* MUST_NOT_THROW_COND might be something else with TM. */
1209 if (MUST_NOT_THROW_COND (stmt) == NULL_TREE)
1211 *walk_subtrees = 0;
1212 tree try_block = wtd->try_block;
1213 wtd->try_block = stmt;
1214 cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
1215 wtd->try_block = try_block;
1218 else if (TREE_CODE (stmt) == THROW_EXPR)
1220 location_t loc = location_of (stmt);
1221 if (TREE_NO_WARNING (stmt))
1222 /* Never mind. */;
1223 else if (wtd->try_block)
1225 if (TREE_CODE (wtd->try_block) == MUST_NOT_THROW_EXPR
1226 && warning_at (loc, OPT_Wterminate,
1227 "throw will always call terminate()")
1228 && cxx_dialect >= cxx11
1229 && DECL_DESTRUCTOR_P (current_function_decl))
1230 inform (loc, "in C++11 destructors default to noexcept");
1232 else
1234 if (warn_cxx11_compat && cxx_dialect < cxx11
1235 && DECL_DESTRUCTOR_P (current_function_decl)
1236 && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))
1237 == NULL_TREE)
1238 && (get_defaulted_eh_spec (current_function_decl)
1239 == empty_except_spec))
1240 warning_at (loc, OPT_Wc__11_compat,
1241 "in C++11 this throw will terminate because "
1242 "destructors default to noexcept");
1245 else if (TREE_CODE (stmt) == CONVERT_EXPR)
1246 gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
1247 else if (TREE_CODE (stmt) == FOR_STMT)
1248 genericize_for_stmt (stmt_p, walk_subtrees, data);
1249 else if (TREE_CODE (stmt) == WHILE_STMT)
1250 genericize_while_stmt (stmt_p, walk_subtrees, data);
1251 else if (TREE_CODE (stmt) == DO_STMT)
1252 genericize_do_stmt (stmt_p, walk_subtrees, data);
1253 else if (TREE_CODE (stmt) == SWITCH_STMT)
1254 genericize_switch_stmt (stmt_p, walk_subtrees, data);
1255 else if (TREE_CODE (stmt) == CONTINUE_STMT)
1256 genericize_continue_stmt (stmt_p);
1257 else if (TREE_CODE (stmt) == BREAK_STMT)
1258 genericize_break_stmt (stmt_p);
1259 else if (TREE_CODE (stmt) == OMP_FOR
1260 || TREE_CODE (stmt) == OMP_SIMD
1261 || TREE_CODE (stmt) == OMP_DISTRIBUTE)
1262 genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
1263 else if (TREE_CODE (stmt) == SIZEOF_EXPR)
1265 if (SIZEOF_EXPR_TYPE_P (stmt))
1266 *stmt_p
1267 = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (stmt, 0)),
1268 SIZEOF_EXPR, false);
1269 else if (TYPE_P (TREE_OPERAND (stmt, 0)))
1270 *stmt_p = cxx_sizeof_or_alignof_type (TREE_OPERAND (stmt, 0),
1271 SIZEOF_EXPR, false);
1272 else
1273 *stmt_p = cxx_sizeof_or_alignof_expr (TREE_OPERAND (stmt, 0),
1274 SIZEOF_EXPR, false);
1275 if (*stmt_p == error_mark_node)
1276 *stmt_p = size_one_node;
1277 return NULL;
1279 else if (flag_sanitize
1280 & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
1282 if ((flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1283 && TREE_CODE (stmt) == NOP_EXPR
1284 && TREE_CODE (TREE_TYPE (stmt)) == REFERENCE_TYPE)
1285 ubsan_maybe_instrument_reference (stmt);
1286 else if (TREE_CODE (stmt) == CALL_EXPR)
1288 tree fn = CALL_EXPR_FN (stmt);
1289 if (fn != NULL_TREE
1290 && !error_operand_p (fn)
1291 && POINTER_TYPE_P (TREE_TYPE (fn))
1292 && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE)
1294 bool is_ctor
1295 = TREE_CODE (fn) == ADDR_EXPR
1296 && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
1297 && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0));
1298 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1299 ubsan_maybe_instrument_member_call (stmt, is_ctor);
1300 if ((flag_sanitize & SANITIZE_VPTR) && !is_ctor)
1301 cp_ubsan_maybe_instrument_member_call (stmt);
1306 p_set->add (*stmt_p);
1308 return NULL;
1311 /* Lower C++ front end trees to GENERIC in T_P. */
1313 static void
1314 cp_genericize_tree (tree* t_p)
1316 struct cp_genericize_data wtd;
1318 wtd.p_set = new hash_set<tree>;
1319 wtd.bind_expr_stack.create (0);
1320 wtd.omp_ctx = NULL;
1321 wtd.try_block = NULL_TREE;
1322 cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
1323 delete wtd.p_set;
1324 wtd.bind_expr_stack.release ();
1325 if (flag_sanitize & SANITIZE_VPTR)
1326 cp_ubsan_instrument_member_accesses (t_p);
1329 /* If a function that should end with a return in non-void
1330 function doesn't obviously end with return, add ubsan
1331 instrumentation code to verify it at runtime. */
1333 static void
1334 cp_ubsan_maybe_instrument_return (tree fndecl)
1336 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
1337 || DECL_CONSTRUCTOR_P (fndecl)
1338 || DECL_DESTRUCTOR_P (fndecl)
1339 || !targetm.warn_func_return (fndecl))
1340 return;
1342 tree t = DECL_SAVED_TREE (fndecl);
1343 while (t)
1345 switch (TREE_CODE (t))
1347 case BIND_EXPR:
1348 t = BIND_EXPR_BODY (t);
1349 continue;
1350 case TRY_FINALLY_EXPR:
1351 t = TREE_OPERAND (t, 0);
1352 continue;
1353 case STATEMENT_LIST:
1355 tree_stmt_iterator i = tsi_last (t);
1356 if (!tsi_end_p (i))
1358 t = tsi_stmt (i);
1359 continue;
1362 break;
1363 case RETURN_EXPR:
1364 return;
1365 default:
1366 break;
1368 break;
1370 if (t == NULL_TREE)
1371 return;
1372 t = DECL_SAVED_TREE (fndecl);
1373 if (TREE_CODE (t) == BIND_EXPR
1374 && TREE_CODE (BIND_EXPR_BODY (t)) == STATEMENT_LIST)
1376 tree_stmt_iterator i = tsi_last (BIND_EXPR_BODY (t));
1377 t = ubsan_instrument_return (DECL_SOURCE_LOCATION (fndecl));
1378 tsi_link_after (&i, t, TSI_NEW_STMT);
1382 void
1383 cp_genericize (tree fndecl)
1385 tree t;
1387 /* Fix up the types of parms passed by invisible reference. */
1388 for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
1389 if (TREE_ADDRESSABLE (TREE_TYPE (t)))
1391 /* If a function's arguments are copied to create a thunk,
1392 then DECL_BY_REFERENCE will be set -- but the type of the
1393 argument will be a pointer type, so we will never get
1394 here. */
1395 gcc_assert (!DECL_BY_REFERENCE (t));
1396 gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
1397 TREE_TYPE (t) = DECL_ARG_TYPE (t);
1398 DECL_BY_REFERENCE (t) = 1;
1399 TREE_ADDRESSABLE (t) = 0;
1400 relayout_decl (t);
1403 /* Do the same for the return value. */
1404 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
1406 t = DECL_RESULT (fndecl);
1407 TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
1408 DECL_BY_REFERENCE (t) = 1;
1409 TREE_ADDRESSABLE (t) = 0;
1410 relayout_decl (t);
1411 if (DECL_NAME (t))
1413 /* Adjust DECL_VALUE_EXPR of the original var. */
1414 tree outer = outer_curly_brace_block (current_function_decl);
1415 tree var;
1417 if (outer)
1418 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1419 if (DECL_NAME (t) == DECL_NAME (var)
1420 && DECL_HAS_VALUE_EXPR_P (var)
1421 && DECL_VALUE_EXPR (var) == t)
1423 tree val = convert_from_reference (t);
1424 SET_DECL_VALUE_EXPR (var, val);
1425 break;
1430 /* If we're a clone, the body is already GIMPLE. */
1431 if (DECL_CLONED_FUNCTION_P (fndecl))
1432 return;
1434 /* Expand all the array notations here. */
1435 if (flag_cilkplus
1436 && contains_array_notation_expr (DECL_SAVED_TREE (fndecl)))
1437 DECL_SAVED_TREE (fndecl) =
1438 expand_array_notation_exprs (DECL_SAVED_TREE (fndecl));
1440 /* We do want to see every occurrence of the parms, so we can't just use
1441 walk_tree's hash functionality. */
1442 cp_genericize_tree (&DECL_SAVED_TREE (fndecl));
1444 if (flag_sanitize & SANITIZE_RETURN
1445 && do_ubsan_in_current_function ())
1446 cp_ubsan_maybe_instrument_return (fndecl);
1448 /* Do everything else. */
1449 c_genericize (fndecl);
1451 gcc_assert (bc_label[bc_break] == NULL);
1452 gcc_assert (bc_label[bc_continue] == NULL);
1455 /* Build code to apply FN to each member of ARG1 and ARG2. FN may be
1456 NULL if there is in fact nothing to do. ARG2 may be null if FN
1457 actually only takes one argument. */
1459 static tree
1460 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
1462 tree defparm, parm, t;
1463 int i = 0;
1464 int nargs;
1465 tree *argarray;
1467 if (fn == NULL)
1468 return NULL;
1470 nargs = list_length (DECL_ARGUMENTS (fn));
1471 argarray = XALLOCAVEC (tree, nargs);
1473 defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
1474 if (arg2)
1475 defparm = TREE_CHAIN (defparm);
1477 if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
1479 tree inner_type = TREE_TYPE (arg1);
1480 tree start1, end1, p1;
1481 tree start2 = NULL, p2 = NULL;
1482 tree ret = NULL, lab;
1484 start1 = arg1;
1485 start2 = arg2;
1488 inner_type = TREE_TYPE (inner_type);
1489 start1 = build4 (ARRAY_REF, inner_type, start1,
1490 size_zero_node, NULL, NULL);
1491 if (arg2)
1492 start2 = build4 (ARRAY_REF, inner_type, start2,
1493 size_zero_node, NULL, NULL);
1495 while (TREE_CODE (inner_type) == ARRAY_TYPE);
1496 start1 = build_fold_addr_expr_loc (input_location, start1);
1497 if (arg2)
1498 start2 = build_fold_addr_expr_loc (input_location, start2);
1500 end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
1501 end1 = fold_build_pointer_plus (start1, end1);
1503 p1 = create_tmp_var (TREE_TYPE (start1));
1504 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
1505 append_to_statement_list (t, &ret);
1507 if (arg2)
1509 p2 = create_tmp_var (TREE_TYPE (start2));
1510 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
1511 append_to_statement_list (t, &ret);
1514 lab = create_artificial_label (input_location);
1515 t = build1 (LABEL_EXPR, void_type_node, lab);
1516 append_to_statement_list (t, &ret);
1518 argarray[i++] = p1;
1519 if (arg2)
1520 argarray[i++] = p2;
1521 /* Handle default arguments. */
1522 for (parm = defparm; parm && parm != void_list_node;
1523 parm = TREE_CHAIN (parm), i++)
1524 argarray[i] = convert_default_arg (TREE_VALUE (parm),
1525 TREE_PURPOSE (parm), fn, i,
1526 tf_warning_or_error);
1527 t = build_call_a (fn, i, argarray);
1528 t = fold_convert (void_type_node, t);
1529 t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1530 append_to_statement_list (t, &ret);
1532 t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type));
1533 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
1534 append_to_statement_list (t, &ret);
1536 if (arg2)
1538 t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type));
1539 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
1540 append_to_statement_list (t, &ret);
1543 t = build2 (NE_EXPR, boolean_type_node, p1, end1);
1544 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
1545 append_to_statement_list (t, &ret);
1547 return ret;
1549 else
1551 argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
1552 if (arg2)
1553 argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
1554 /* Handle default arguments. */
1555 for (parm = defparm; parm && parm != void_list_node;
1556 parm = TREE_CHAIN (parm), i++)
1557 argarray[i] = convert_default_arg (TREE_VALUE (parm),
1558 TREE_PURPOSE (parm),
1559 fn, i, tf_warning_or_error);
1560 t = build_call_a (fn, i, argarray);
1561 t = fold_convert (void_type_node, t);
1562 return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
1566 /* Return code to initialize DECL with its default constructor, or
1567 NULL if there's nothing to do. */
1569 tree
1570 cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/)
1572 tree info = CP_OMP_CLAUSE_INFO (clause);
1573 tree ret = NULL;
1575 if (info)
1576 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
1578 return ret;
1581 /* Return code to initialize DST with a copy constructor from SRC. */
1583 tree
1584 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
1586 tree info = CP_OMP_CLAUSE_INFO (clause);
1587 tree ret = NULL;
1589 if (info)
1590 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
1591 if (ret == NULL)
1592 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1594 return ret;
1597 /* Similarly, except use an assignment operator instead. */
1599 tree
1600 cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
1602 tree info = CP_OMP_CLAUSE_INFO (clause);
1603 tree ret = NULL;
1605 if (info)
1606 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
1607 if (ret == NULL)
1608 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
1610 return ret;
1613 /* Return code to destroy DECL. */
1615 tree
1616 cxx_omp_clause_dtor (tree clause, tree decl)
1618 tree info = CP_OMP_CLAUSE_INFO (clause);
1619 tree ret = NULL;
1621 if (info)
1622 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
1624 return ret;
1627 /* True if OpenMP should privatize what this DECL points to rather
1628 than the DECL itself. */
1630 bool
1631 cxx_omp_privatize_by_reference (const_tree decl)
1633 return (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
1634 || is_invisiref_parm (decl));
1637 /* Return true if DECL is const qualified var having no mutable member. */
1638 bool
1639 cxx_omp_const_qual_no_mutable (tree decl)
1641 tree type = TREE_TYPE (decl);
1642 if (TREE_CODE (type) == REFERENCE_TYPE)
1644 if (!is_invisiref_parm (decl))
1645 return false;
1646 type = TREE_TYPE (type);
1648 if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
1650 /* NVR doesn't preserve const qualification of the
1651 variable's type. */
1652 tree outer = outer_curly_brace_block (current_function_decl);
1653 tree var;
1655 if (outer)
1656 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1657 if (DECL_NAME (decl) == DECL_NAME (var)
1658 && (TYPE_MAIN_VARIANT (type)
1659 == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
1661 if (TYPE_READONLY (TREE_TYPE (var)))
1662 type = TREE_TYPE (var);
1663 break;
1668 if (type == error_mark_node)
1669 return false;
1671 /* Variables with const-qualified type having no mutable member
1672 are predetermined shared. */
1673 if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
1674 return true;
1676 return false;
1679 /* True if OpenMP sharing attribute of DECL is predetermined. */
1681 enum omp_clause_default_kind
1682 cxx_omp_predetermined_sharing (tree decl)
1684 /* Static data members are predetermined shared. */
1685 if (TREE_STATIC (decl))
1687 tree ctx = CP_DECL_CONTEXT (decl);
1688 if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
1689 return OMP_CLAUSE_DEFAULT_SHARED;
1692 /* Const qualified vars having no mutable member are predetermined
1693 shared. */
1694 if (cxx_omp_const_qual_no_mutable (decl))
1695 return OMP_CLAUSE_DEFAULT_SHARED;
1697 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1700 /* Finalize an implicitly determined clause. */
1702 void
1703 cxx_omp_finish_clause (tree c, gimple_seq *)
1705 tree decl, inner_type;
1706 bool make_shared = false;
1708 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
1709 return;
1711 decl = OMP_CLAUSE_DECL (c);
1712 decl = require_complete_type (decl);
1713 inner_type = TREE_TYPE (decl);
1714 if (decl == error_mark_node)
1715 make_shared = true;
1716 else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1718 if (is_invisiref_parm (decl))
1719 inner_type = TREE_TYPE (inner_type);
1720 else
1722 error ("%qE implicitly determined as %<firstprivate%> has reference type",
1723 decl);
1724 make_shared = true;
1728 /* We're interested in the base element, not arrays. */
1729 while (TREE_CODE (inner_type) == ARRAY_TYPE)
1730 inner_type = TREE_TYPE (inner_type);
1732 /* Check for special function availability by building a call to one.
1733 Save the results, because later we won't be in the right context
1734 for making these queries. */
1735 if (!make_shared
1736 && CLASS_TYPE_P (inner_type)
1737 && cxx_omp_create_clause_info (c, inner_type, false, true, false, true))
1738 make_shared = true;
1740 if (make_shared)
1741 OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;