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
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
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/>. */
24 #include "coretypes.h"
27 #include "stor-layout.h"
29 #include "c-family/c-common.h"
30 #include "tree-iterator.h"
36 #include "hard-reg-set.h"
39 #include "basic-block.h"
40 #include "tree-ssa-alias.h"
41 #include "internal-fn.h"
42 #include "gimple-expr.h"
47 #include "splay-tree.h"
49 #include "c-family/c-ubsan.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
68 Just creates a label with location LOCATION and pushes it into the current
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
];
78 LABEL_DECL_BREAK (label
) = true;
80 LABEL_DECL_CONTINUE (label
) = true;
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. */
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
),
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. */
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;
117 /* Genericize a TRY_BLOCK. */
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. */
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
144 build_gimple_eh_filter_tree (tree body
, tree allowed
, tree failure
)
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));
158 /* Genericize an EH_SPEC_BLOCK by converting it to a
159 TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
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. */
176 genericize_if_stmt (tree
*stmt_p
)
178 tree stmt
, cond
, then_
, else_
;
179 location_t locus
= EXPR_LOCATION (*stmt_p
);
182 cond
= IF_COND (stmt
);
183 then_
= THEN_CLAUSE (stmt
);
184 else_
= ELSE_CLAUSE (stmt
);
187 then_
= build_empty_stmt (locus
);
189 else_
= build_empty_stmt (locus
);
191 if (integer_nonzerop (cond
) && !TREE_SIDE_EFFECTS (else_
))
193 else if (integer_zerop (cond
) && !TREE_SIDE_EFFECTS (then_
))
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
);
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. */
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
,
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
);
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
);
249 stmt_list
= build_empty_stmt (start_locus
);
252 if (cond
&& integer_zerop (cond
))
255 loop
= fold_build3_loc (start_locus
, COND_EXPR
,
256 void_type_node
, cond
, stmt_list
,
257 build_empty_stmt (start_locus
));
262 loop
= build1_loc (start_locus
, LOOP_EXPR
, void_type_node
, stmt_list
);
265 append_to_statement_list (loop
, &stmt_list
);
266 finish_bc_block (&stmt_list
, bc_break
, blab
);
268 stmt_list
= build_empty_stmt (start_locus
);
273 /* Genericize a FOR_STMT node *STMT_P. */
276 genericize_for_stmt (tree
*stmt_p
, int *walk_subtrees
, void *data
)
281 tree init
= FOR_INIT_STMT (stmt
);
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
)
297 /* Genericize a WHILE_STMT node *STMT_P. */
300 genericize_while_stmt (tree
*stmt_p
, int *walk_subtrees
, void *data
)
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. */
310 genericize_do_stmt (tree
*stmt_p
, int *walk_subtrees
, void *data
)
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. */
320 genericize_switch_stmt (tree
*stmt_p
, int *walk_subtrees
, void *data
)
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
);
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
);
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. */
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
);
358 /* Genericize a BREAK_STMT node *STMT_P. */
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. */
371 genericize_omp_for_stmt (tree
*stmt_p
, int *walk_subtrees
, void *data
)
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
);
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
))
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;
409 /* Gimplify an EXPR_STMT node. */
412 gimplify_expr_stmt (tree
*stmt_p
)
414 tree stmt
= EXPR_STMT_EXPR (*stmt_p
);
416 if (stmt
== error_mark_node
)
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
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");
435 warn_if_unused_value (stmt
, input_location
);
438 if (stmt
== NULL_TREE
)
439 stmt
= alloc_stmt_list ();
444 /* Gimplify initialization from an AGGR_INIT_EXPR. */
447 cp_gimplify_init_expr (tree
*expr_p
)
449 tree from
= TREE_OPERAND (*expr_p
, 1);
450 tree to
= TREE_OPERAND (*expr_p
, 0);
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. */
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
;
477 VEC_INIT_EXPR_SLOT (sub
) = to
;
480 /* The initialization is now a side-effect, so the container can
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
);
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
)
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
;
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
);
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
);
545 *expr_p
= cplus_expand_constant (*expr_p
);
550 simplify_aggr_init_expr (expr_p
);
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
),
564 tf_warning_or_error
);
565 cp_genericize_tree (expr_p
);
567 input_location
= loc
;
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);
578 case MUST_NOT_THROW_EXPR
:
579 ret
= gimplify_must_not_throw_expr (expr_p
, pre_p
);
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
586 if (fn_contains_cilk_spawn_p (cfun
)
587 && cilk_detect_spawn_and_unwrap (expr_p
)
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
)
593 /* Otherwise fall through. */
596 if (fn_contains_cilk_spawn_p (cfun
)
597 && cilk_detect_spawn_and_unwrap (expr_p
)
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
))
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
);
637 *expr_p
= build2 (COMPOUND_EXPR
, TREE_TYPE (*expr_p
),
644 case EMPTY_CLASS_EXPR
:
645 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
646 *expr_p
= build_constructor (TREE_TYPE (*expr_p
), NULL
);
651 *expr_p
= BASELINK_FUNCTIONS (*expr_p
);
656 genericize_try_block (expr_p
);
661 genericize_catch_block (expr_p
);
666 genericize_eh_spec_block (expr_p
);
684 ret
= cp_gimplify_omp_for (expr_p
, pre_p
);
688 gimplify_expr_stmt (expr_p
);
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
)
702 case CILK_SPAWN_STMT
:
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. */
709 return (enum gimplify_status
) gimplify_cilk_spawn (expr_p
);
712 if (fn_contains_cilk_spawn_p (cfun
)
713 && cilk_detect_spawn_and_unwrap (expr_p
)
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
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
);
739 ret
= (enum gimplify_status
) c_gimplify_expr (expr_p
, pre_p
, post_p
);
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
;
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. */
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. */
769 cxx_int_tree_map_hasher::hash (cxx_int_tree_map
*item
)
774 /* A stable comparison routine for use with splay trees and DECLs. */
777 splay_tree_compare_decl_uid (splay_tree_key xa
, splay_tree_key xb
)
782 return DECL_UID (a
) - DECL_UID (b
);
785 /* OpenMP context during genericization. */
787 struct cp_genericize_omp_taskreg
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. */
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
))
808 if (VAR_P (decl
) && DECL_THREAD_LOCAL_P (decl
))
810 if (cxx_omp_predetermined_sharing (decl
) != OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
815 /* Note DECL use in OpenMP region OMP_CTX during genericization. */
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
);
824 int flags
= OMP_CLAUSE_DEFAULT_SHARED
;
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
;
839 if (octx
->is_parallel
)
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
879 cp_genericize_r (tree
*stmt_p
, int *walk_subtrees
, void *data
)
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)
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
);
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
);
920 /* Other than invisiref parms, don't walk the same tree twice. */
921 if (p_set
->contains (stmt
))
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));
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. */
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
)))
950 if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt
))
951 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt
),
952 cp_genericize_r
, data
, NULL
);
955 case OMP_CLAUSE_PRIVATE
:
956 /* Don't dereference an invisiref in OpenMP clauses. */
957 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt
)))
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
;
966 cp_walk_tree (&OMP_CLAUSE_DECL (stmt
), cp_genericize_r
,
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
)))
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
)))
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
);
998 else if (IS_TYPE_OR_DECL_P (stmt
))
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
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
)
1024 = (TREE_OPERAND (stmt
, 1)
1025 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt
, 1))
1028 = (TREE_OPERAND (stmt
, 2)
1029 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt
, 2))
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
),
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
),
1051 else if (TREE_CODE (stmt
) == BIND_EXPR
)
1053 if (__builtin_expect (wtd
->omp_ctx
!= NULL
, 0))
1056 for (decl
= BIND_EXPR_VARS (stmt
); decl
; decl
= DECL_CHAIN (decl
))
1058 && !DECL_EXTERNAL (decl
)
1059 && omp_var_to_track (decl
))
1062 = splay_tree_lookup (wtd
->omp_ctx
->variables
,
1063 (splay_tree_key
) decl
);
1065 splay_tree_insert (wtd
->omp_ctx
->variables
,
1066 (splay_tree_key
) 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 ())
1088 for (i
= wtd
->bind_expr_stack
.length () - 1; i
>= 0; i
--)
1089 if ((block
= BIND_EXPR_BLOCK (wtd
->bind_expr_stack
[i
])))
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
);
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
);
1117 else if (TREE_CODE (stmt
) == OMP_PARALLEL
|| TREE_CODE (stmt
) == OMP_TASK
)
1119 struct cp_genericize_omp_taskreg omp_ctx
;
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
))
1140 n
= splay_tree_lookup (omp_ctx
.variables
, (splay_tree_key
) decl
);
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
1149 omp_cxx_notice_variable (omp_ctx
.outer
, decl
);
1151 case OMP_CLAUSE_DEFAULT
:
1152 if (OMP_CLAUSE_DEFAULT_KIND (c
) == OMP_CLAUSE_DEFAULT_SHARED
)
1153 omp_ctx
.default_shared
= true;
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
))
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);
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
;
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
);
1204 && !error_operand_p (fn
)
1205 && POINTER_TYPE_P (TREE_TYPE (fn
))
1206 && TREE_CODE (TREE_TYPE (TREE_TYPE (fn
))) == METHOD_TYPE
)
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
);
1222 /* Lower C++ front end trees to GENERIC in T_P. */
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);
1232 cp_walk_tree (t_p
, cp_genericize_r
, &wtd
, NULL
);
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. */
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
))
1250 tree t
= DECL_SAVED_TREE (fndecl
);
1253 switch (TREE_CODE (t
))
1256 t
= BIND_EXPR_BODY (t
);
1258 case TRY_FINALLY_EXPR
:
1259 t
= TREE_OPERAND (t
, 0);
1261 case STATEMENT_LIST
:
1263 tree_stmt_iterator i
= tsi_last (t
);
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
);
1291 cp_genericize (tree fndecl
)
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
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;
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;
1321 /* Adjust DECL_VALUE_EXPR of the original var. */
1322 tree outer
= outer_curly_brace_block (current_function_decl
);
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
);
1338 /* If we're a clone, the body is already GIMPLE. */
1339 if (DECL_CLONED_FUNCTION_P (fndecl
))
1342 /* Expand all the array notations here. */
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. */
1370 cxx_omp_clause_apply_fn (tree fn
, tree arg1
, tree arg2
)
1372 tree defparm
, parm
, t
;
1380 nargs
= list_length (DECL_ARGUMENTS (fn
));
1381 argarray
= XALLOCAVEC (tree
, nargs
);
1383 defparm
= TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn
)));
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
;
1398 inner_type
= TREE_TYPE (inner_type
);
1399 start1
= build4 (ARRAY_REF
, inner_type
, start1
,
1400 size_zero_node
, NULL
, NULL
);
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
);
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
);
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
);
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
);
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
);
1461 argarray
[i
++] = build_fold_addr_expr_loc (input_location
, arg1
);
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. */
1480 cxx_omp_clause_default_ctor (tree clause
, tree decl
, tree
/*outer*/)
1482 tree info
= CP_OMP_CLAUSE_INFO (clause
);
1486 ret
= cxx_omp_clause_apply_fn (TREE_VEC_ELT (info
, 0), decl
, NULL
);
1491 /* Return code to initialize DST with a copy constructor from SRC. */
1494 cxx_omp_clause_copy_ctor (tree clause
, tree dst
, tree src
)
1496 tree info
= CP_OMP_CLAUSE_INFO (clause
);
1500 ret
= cxx_omp_clause_apply_fn (TREE_VEC_ELT (info
, 0), dst
, src
);
1502 ret
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
1507 /* Similarly, except use an assignment operator instead. */
1510 cxx_omp_clause_assign_op (tree clause
, tree dst
, tree src
)
1512 tree info
= CP_OMP_CLAUSE_INFO (clause
);
1516 ret
= cxx_omp_clause_apply_fn (TREE_VEC_ELT (info
, 2), dst
, src
);
1518 ret
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
1523 /* Return code to destroy DECL. */
1526 cxx_omp_clause_dtor (tree clause
, tree decl
)
1528 tree info
= CP_OMP_CLAUSE_INFO (clause
);
1532 ret
= cxx_omp_clause_apply_fn (TREE_VEC_ELT (info
, 1), decl
, NULL
);
1537 /* True if OpenMP should privatize what this DECL points to rather
1538 than the DECL itself. */
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. */
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
))
1556 type
= TREE_TYPE (type
);
1558 if (TREE_CODE (decl
) == RESULT_DECL
&& DECL_NAME (decl
))
1560 /* NVR doesn't preserve const qualification of the
1562 tree outer
= outer_curly_brace_block (current_function_decl
);
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
);
1578 if (type
== error_mark_node
)
1581 /* Variables with const-qualified type having no mutable member
1582 are predetermined shared. */
1583 if (TYPE_READONLY (type
) && !cp_has_mutable_p (type
))
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
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. */
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
)
1621 decl
= OMP_CLAUSE_DECL (c
);
1622 decl
= require_complete_type (decl
);
1623 inner_type
= TREE_TYPE (decl
);
1624 if (decl
== error_mark_node
)
1626 else if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
)
1628 if (is_invisiref_parm (decl
))
1629 inner_type
= TREE_TYPE (inner_type
);
1632 error ("%qE implicitly determined as %<firstprivate%> has reference type",
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. */
1646 && CLASS_TYPE_P (inner_type
)
1647 && cxx_omp_create_clause_info (c
, inner_type
, false, true, false, true))
1651 OMP_CLAUSE_CODE (c
) = OMP_CLAUSE_SHARED
;