annotate gcc/cp/cp-gimplify.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
kono
parents:
diff changeset
2
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3 Copyright (C) 2002-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
4 Contributed by Jason Merrill <jason@redhat.com>
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 This file is part of GCC.
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
9 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
10 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
11 version.
kono
parents:
diff changeset
12
kono
parents:
diff changeset
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
16 for more details.
kono
parents:
diff changeset
17
kono
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
19 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
20 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 #include "config.h"
kono
parents:
diff changeset
23 #include "system.h"
kono
parents:
diff changeset
24 #include "coretypes.h"
kono
parents:
diff changeset
25 #include "target.h"
kono
parents:
diff changeset
26 #include "basic-block.h"
kono
parents:
diff changeset
27 #include "cp-tree.h"
kono
parents:
diff changeset
28 #include "gimple.h"
kono
parents:
diff changeset
29 #include "predict.h"
kono
parents:
diff changeset
30 #include "stor-layout.h"
kono
parents:
diff changeset
31 #include "tree-iterator.h"
kono
parents:
diff changeset
32 #include "gimplify.h"
kono
parents:
diff changeset
33 #include "c-family/c-ubsan.h"
kono
parents:
diff changeset
34 #include "stringpool.h"
kono
parents:
diff changeset
35 #include "attribs.h"
kono
parents:
diff changeset
36 #include "asan.h"
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 /* Forward declarations. */
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 static tree cp_genericize_r (tree *, int *, void *);
kono
parents:
diff changeset
41 static tree cp_fold_r (tree *, int *, void *);
kono
parents:
diff changeset
42 static void cp_genericize_tree (tree*, bool);
kono
parents:
diff changeset
43 static tree cp_fold (tree);
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 /* Local declarations. */
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 enum bc_t { bc_break = 0, bc_continue = 1 };
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 /* Stack of labels which are targets for "break" or "continue",
kono
parents:
diff changeset
50 linked through TREE_CHAIN. */
kono
parents:
diff changeset
51 static tree bc_label[2];
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 /* Begin a scope which can be exited by a break or continue statement. BC
kono
parents:
diff changeset
54 indicates which.
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 Just creates a label with location LOCATION and pushes it into the current
kono
parents:
diff changeset
57 context. */
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 static tree
kono
parents:
diff changeset
60 begin_bc_block (enum bc_t bc, location_t location)
kono
parents:
diff changeset
61 {
kono
parents:
diff changeset
62 tree label = create_artificial_label (location);
kono
parents:
diff changeset
63 DECL_CHAIN (label) = bc_label[bc];
kono
parents:
diff changeset
64 bc_label[bc] = label;
kono
parents:
diff changeset
65 if (bc == bc_break)
kono
parents:
diff changeset
66 LABEL_DECL_BREAK (label) = true;
kono
parents:
diff changeset
67 else
kono
parents:
diff changeset
68 LABEL_DECL_CONTINUE (label) = true;
kono
parents:
diff changeset
69 return label;
kono
parents:
diff changeset
70 }
kono
parents:
diff changeset
71
kono
parents:
diff changeset
72 /* Finish a scope which can be exited by a break or continue statement.
kono
parents:
diff changeset
73 LABEL was returned from the most recent call to begin_bc_block. BLOCK is
kono
parents:
diff changeset
74 an expression for the contents of the scope.
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
kono
parents:
diff changeset
77 BLOCK. Otherwise, just forget the label. */
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 static void
kono
parents:
diff changeset
80 finish_bc_block (tree *block, enum bc_t bc, tree label)
kono
parents:
diff changeset
81 {
kono
parents:
diff changeset
82 gcc_assert (label == bc_label[bc]);
kono
parents:
diff changeset
83
kono
parents:
diff changeset
84 if (TREE_USED (label))
kono
parents:
diff changeset
85 append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label),
kono
parents:
diff changeset
86 block);
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 bc_label[bc] = DECL_CHAIN (label);
kono
parents:
diff changeset
89 DECL_CHAIN (label) = NULL_TREE;
kono
parents:
diff changeset
90 }
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 /* Get the LABEL_EXPR to represent a break or continue statement
kono
parents:
diff changeset
93 in the current block scope. BC indicates which. */
kono
parents:
diff changeset
94
kono
parents:
diff changeset
95 static tree
kono
parents:
diff changeset
96 get_bc_label (enum bc_t bc)
kono
parents:
diff changeset
97 {
kono
parents:
diff changeset
98 tree label = bc_label[bc];
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 /* Mark the label used for finish_bc_block. */
kono
parents:
diff changeset
101 TREE_USED (label) = 1;
kono
parents:
diff changeset
102 return label;
kono
parents:
diff changeset
103 }
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 /* Genericize a TRY_BLOCK. */
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107 static void
kono
parents:
diff changeset
108 genericize_try_block (tree *stmt_p)
kono
parents:
diff changeset
109 {
kono
parents:
diff changeset
110 tree body = TRY_STMTS (*stmt_p);
kono
parents:
diff changeset
111 tree cleanup = TRY_HANDLERS (*stmt_p);
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
kono
parents:
diff changeset
114 }
kono
parents:
diff changeset
115
kono
parents:
diff changeset
116 /* Genericize a HANDLER by converting to a CATCH_EXPR. */
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 static void
kono
parents:
diff changeset
119 genericize_catch_block (tree *stmt_p)
kono
parents:
diff changeset
120 {
kono
parents:
diff changeset
121 tree type = HANDLER_TYPE (*stmt_p);
kono
parents:
diff changeset
122 tree body = HANDLER_BODY (*stmt_p);
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 /* FIXME should the caught type go in TREE_TYPE? */
kono
parents:
diff changeset
125 *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
kono
parents:
diff changeset
126 }
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 /* A terser interface for building a representation of an exception
kono
parents:
diff changeset
129 specification. */
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 static tree
kono
parents:
diff changeset
132 build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
kono
parents:
diff changeset
133 {
kono
parents:
diff changeset
134 tree t;
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 /* FIXME should the allowed types go in TREE_TYPE? */
kono
parents:
diff changeset
137 t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
kono
parents:
diff changeset
138 append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
kono
parents:
diff changeset
141 append_to_statement_list (body, &TREE_OPERAND (t, 0));
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 return t;
kono
parents:
diff changeset
144 }
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 /* Genericize an EH_SPEC_BLOCK by converting it to a
kono
parents:
diff changeset
147 TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 static void
kono
parents:
diff changeset
150 genericize_eh_spec_block (tree *stmt_p)
kono
parents:
diff changeset
151 {
kono
parents:
diff changeset
152 tree body = EH_SPEC_STMTS (*stmt_p);
kono
parents:
diff changeset
153 tree allowed = EH_SPEC_RAISES (*stmt_p);
kono
parents:
diff changeset
154 tree failure = build_call_n (call_unexpected_fn, 1, build_exc_ptr ());
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
kono
parents:
diff changeset
157 TREE_NO_WARNING (*stmt_p) = true;
kono
parents:
diff changeset
158 TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true;
kono
parents:
diff changeset
159 }
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 static void
kono
parents:
diff changeset
164 genericize_if_stmt (tree *stmt_p)
kono
parents:
diff changeset
165 {
kono
parents:
diff changeset
166 tree stmt, cond, then_, else_;
kono
parents:
diff changeset
167 location_t locus = EXPR_LOCATION (*stmt_p);
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 stmt = *stmt_p;
kono
parents:
diff changeset
170 cond = IF_COND (stmt);
kono
parents:
diff changeset
171 then_ = THEN_CLAUSE (stmt);
kono
parents:
diff changeset
172 else_ = ELSE_CLAUSE (stmt);
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 if (!then_)
kono
parents:
diff changeset
175 then_ = build_empty_stmt (locus);
kono
parents:
diff changeset
176 if (!else_)
kono
parents:
diff changeset
177 else_ = build_empty_stmt (locus);
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
kono
parents:
diff changeset
180 stmt = then_;
kono
parents:
diff changeset
181 else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
kono
parents:
diff changeset
182 stmt = else_;
kono
parents:
diff changeset
183 else
kono
parents:
diff changeset
184 stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
kono
parents:
diff changeset
185 if (!EXPR_HAS_LOCATION (stmt))
kono
parents:
diff changeset
186 protected_set_expr_location (stmt, locus);
kono
parents:
diff changeset
187 *stmt_p = stmt;
kono
parents:
diff changeset
188 }
kono
parents:
diff changeset
189
kono
parents:
diff changeset
190 /* Build a generic representation of one of the C loop forms. COND is the
kono
parents:
diff changeset
191 loop condition or NULL_TREE. BODY is the (possibly compound) statement
kono
parents:
diff changeset
192 controlled by the loop. INCR is the increment expression of a for-loop,
kono
parents:
diff changeset
193 or NULL_TREE. COND_IS_FIRST indicates whether the condition is
kono
parents:
diff changeset
194 evaluated before the loop body as in while and for loops, or after the
kono
parents:
diff changeset
195 loop body as in do-while loops. */
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 static void
kono
parents:
diff changeset
198 genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
kono
parents:
diff changeset
199 tree incr, bool cond_is_first, int *walk_subtrees,
kono
parents:
diff changeset
200 void *data)
kono
parents:
diff changeset
201 {
kono
parents:
diff changeset
202 tree blab, clab;
kono
parents:
diff changeset
203 tree exit = NULL;
kono
parents:
diff changeset
204 tree stmt_list = NULL;
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 blab = begin_bc_block (bc_break, start_locus);
kono
parents:
diff changeset
207 clab = begin_bc_block (bc_continue, start_locus);
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 protected_set_expr_location (incr, start_locus);
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 cp_walk_tree (&cond, cp_genericize_r, data, NULL);
kono
parents:
diff changeset
212 cp_walk_tree (&body, cp_genericize_r, data, NULL);
kono
parents:
diff changeset
213 cp_walk_tree (&incr, cp_genericize_r, data, NULL);
kono
parents:
diff changeset
214 *walk_subtrees = 0;
kono
parents:
diff changeset
215
kono
parents:
diff changeset
216 if (cond && TREE_CODE (cond) != INTEGER_CST)
kono
parents:
diff changeset
217 {
kono
parents:
diff changeset
218 /* If COND is constant, don't bother building an exit. If it's false,
kono
parents:
diff changeset
219 we won't build a loop. If it's true, any exits are in the body. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
220 location_t cloc = cp_expr_loc_or_loc (cond, start_locus);
111
kono
parents:
diff changeset
221 exit = build1_loc (cloc, GOTO_EXPR, void_type_node,
kono
parents:
diff changeset
222 get_bc_label (bc_break));
kono
parents:
diff changeset
223 exit = fold_build3_loc (cloc, COND_EXPR, void_type_node, cond,
kono
parents:
diff changeset
224 build_empty_stmt (cloc), exit);
kono
parents:
diff changeset
225 }
kono
parents:
diff changeset
226
kono
parents:
diff changeset
227 if (exit && cond_is_first)
kono
parents:
diff changeset
228 append_to_statement_list (exit, &stmt_list);
kono
parents:
diff changeset
229 append_to_statement_list (body, &stmt_list);
kono
parents:
diff changeset
230 finish_bc_block (&stmt_list, bc_continue, clab);
kono
parents:
diff changeset
231 append_to_statement_list (incr, &stmt_list);
kono
parents:
diff changeset
232 if (exit && !cond_is_first)
kono
parents:
diff changeset
233 append_to_statement_list (exit, &stmt_list);
kono
parents:
diff changeset
234
kono
parents:
diff changeset
235 if (!stmt_list)
kono
parents:
diff changeset
236 stmt_list = build_empty_stmt (start_locus);
kono
parents:
diff changeset
237
kono
parents:
diff changeset
238 tree loop;
kono
parents:
diff changeset
239 if (cond && integer_zerop (cond))
kono
parents:
diff changeset
240 {
kono
parents:
diff changeset
241 if (cond_is_first)
kono
parents:
diff changeset
242 loop = fold_build3_loc (start_locus, COND_EXPR,
kono
parents:
diff changeset
243 void_type_node, cond, stmt_list,
kono
parents:
diff changeset
244 build_empty_stmt (start_locus));
kono
parents:
diff changeset
245 else
kono
parents:
diff changeset
246 loop = stmt_list;
kono
parents:
diff changeset
247 }
kono
parents:
diff changeset
248 else
kono
parents:
diff changeset
249 {
kono
parents:
diff changeset
250 location_t loc = start_locus;
kono
parents:
diff changeset
251 if (!cond || integer_nonzerop (cond))
kono
parents:
diff changeset
252 loc = EXPR_LOCATION (expr_first (body));
kono
parents:
diff changeset
253 if (loc == UNKNOWN_LOCATION)
kono
parents:
diff changeset
254 loc = start_locus;
kono
parents:
diff changeset
255 loop = build1_loc (loc, LOOP_EXPR, void_type_node, stmt_list);
kono
parents:
diff changeset
256 }
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 stmt_list = NULL;
kono
parents:
diff changeset
259 append_to_statement_list (loop, &stmt_list);
kono
parents:
diff changeset
260 finish_bc_block (&stmt_list, bc_break, blab);
kono
parents:
diff changeset
261 if (!stmt_list)
kono
parents:
diff changeset
262 stmt_list = build_empty_stmt (start_locus);
kono
parents:
diff changeset
263
kono
parents:
diff changeset
264 *stmt_p = stmt_list;
kono
parents:
diff changeset
265 }
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 /* Genericize a FOR_STMT node *STMT_P. */
kono
parents:
diff changeset
268
kono
parents:
diff changeset
269 static void
kono
parents:
diff changeset
270 genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
kono
parents:
diff changeset
271 {
kono
parents:
diff changeset
272 tree stmt = *stmt_p;
kono
parents:
diff changeset
273 tree expr = NULL;
kono
parents:
diff changeset
274 tree loop;
kono
parents:
diff changeset
275 tree init = FOR_INIT_STMT (stmt);
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 if (init)
kono
parents:
diff changeset
278 {
kono
parents:
diff changeset
279 cp_walk_tree (&init, cp_genericize_r, data, NULL);
kono
parents:
diff changeset
280 append_to_statement_list (init, &expr);
kono
parents:
diff changeset
281 }
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 genericize_cp_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
kono
parents:
diff changeset
284 FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees, data);
kono
parents:
diff changeset
285 append_to_statement_list (loop, &expr);
kono
parents:
diff changeset
286 if (expr == NULL_TREE)
kono
parents:
diff changeset
287 expr = loop;
kono
parents:
diff changeset
288 *stmt_p = expr;
kono
parents:
diff changeset
289 }
kono
parents:
diff changeset
290
kono
parents:
diff changeset
291 /* Genericize a WHILE_STMT node *STMT_P. */
kono
parents:
diff changeset
292
kono
parents:
diff changeset
293 static void
kono
parents:
diff changeset
294 genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data)
kono
parents:
diff changeset
295 {
kono
parents:
diff changeset
296 tree stmt = *stmt_p;
kono
parents:
diff changeset
297 genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt),
kono
parents:
diff changeset
298 WHILE_BODY (stmt), NULL_TREE, 1, walk_subtrees, data);
kono
parents:
diff changeset
299 }
kono
parents:
diff changeset
300
kono
parents:
diff changeset
301 /* Genericize a DO_STMT node *STMT_P. */
kono
parents:
diff changeset
302
kono
parents:
diff changeset
303 static void
kono
parents:
diff changeset
304 genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data)
kono
parents:
diff changeset
305 {
kono
parents:
diff changeset
306 tree stmt = *stmt_p;
kono
parents:
diff changeset
307 genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt),
kono
parents:
diff changeset
308 DO_BODY (stmt), NULL_TREE, 0, walk_subtrees, data);
kono
parents:
diff changeset
309 }
kono
parents:
diff changeset
310
kono
parents:
diff changeset
311 /* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR. */
kono
parents:
diff changeset
312
kono
parents:
diff changeset
313 static void
kono
parents:
diff changeset
314 genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data)
kono
parents:
diff changeset
315 {
kono
parents:
diff changeset
316 tree stmt = *stmt_p;
kono
parents:
diff changeset
317 tree break_block, body, cond, type;
kono
parents:
diff changeset
318 location_t stmt_locus = EXPR_LOCATION (stmt);
kono
parents:
diff changeset
319
kono
parents:
diff changeset
320 break_block = begin_bc_block (bc_break, stmt_locus);
kono
parents:
diff changeset
321
kono
parents:
diff changeset
322 body = SWITCH_STMT_BODY (stmt);
kono
parents:
diff changeset
323 if (!body)
kono
parents:
diff changeset
324 body = build_empty_stmt (stmt_locus);
kono
parents:
diff changeset
325 cond = SWITCH_STMT_COND (stmt);
kono
parents:
diff changeset
326 type = SWITCH_STMT_TYPE (stmt);
kono
parents:
diff changeset
327
kono
parents:
diff changeset
328 cp_walk_tree (&body, cp_genericize_r, data, NULL);
kono
parents:
diff changeset
329 cp_walk_tree (&cond, cp_genericize_r, data, NULL);
kono
parents:
diff changeset
330 cp_walk_tree (&type, cp_genericize_r, data, NULL);
kono
parents:
diff changeset
331 *walk_subtrees = 0;
kono
parents:
diff changeset
332
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
333 if (TREE_USED (break_block))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
334 SWITCH_BREAK_LABEL_P (break_block) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
335 finish_bc_block (&body, bc_break, break_block);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
336 *stmt_p = build2_loc (stmt_locus, SWITCH_EXPR, type, cond, body);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
337 SWITCH_ALL_CASES_P (*stmt_p) = SWITCH_STMT_ALL_CASES_P (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
338 gcc_checking_assert (!SWITCH_STMT_NO_BREAK_P (stmt)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
339 || !TREE_USED (break_block));
111
kono
parents:
diff changeset
340 }
kono
parents:
diff changeset
341
kono
parents:
diff changeset
342 /* Genericize a CONTINUE_STMT node *STMT_P. */
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 static void
kono
parents:
diff changeset
345 genericize_continue_stmt (tree *stmt_p)
kono
parents:
diff changeset
346 {
kono
parents:
diff changeset
347 tree stmt_list = NULL;
kono
parents:
diff changeset
348 tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN);
kono
parents:
diff changeset
349 tree label = get_bc_label (bc_continue);
kono
parents:
diff changeset
350 location_t location = EXPR_LOCATION (*stmt_p);
kono
parents:
diff changeset
351 tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label);
kono
parents:
diff changeset
352 append_to_statement_list_force (pred, &stmt_list);
kono
parents:
diff changeset
353 append_to_statement_list (jump, &stmt_list);
kono
parents:
diff changeset
354 *stmt_p = stmt_list;
kono
parents:
diff changeset
355 }
kono
parents:
diff changeset
356
kono
parents:
diff changeset
357 /* Genericize a BREAK_STMT node *STMT_P. */
kono
parents:
diff changeset
358
kono
parents:
diff changeset
359 static void
kono
parents:
diff changeset
360 genericize_break_stmt (tree *stmt_p)
kono
parents:
diff changeset
361 {
kono
parents:
diff changeset
362 tree label = get_bc_label (bc_break);
kono
parents:
diff changeset
363 location_t location = EXPR_LOCATION (*stmt_p);
kono
parents:
diff changeset
364 *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label);
kono
parents:
diff changeset
365 }
kono
parents:
diff changeset
366
kono
parents:
diff changeset
367 /* Genericize a OMP_FOR node *STMT_P. */
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 static void
kono
parents:
diff changeset
370 genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
kono
parents:
diff changeset
371 {
kono
parents:
diff changeset
372 tree stmt = *stmt_p;
kono
parents:
diff changeset
373 location_t locus = EXPR_LOCATION (stmt);
kono
parents:
diff changeset
374 tree clab = begin_bc_block (bc_continue, locus);
kono
parents:
diff changeset
375
kono
parents:
diff changeset
376 cp_walk_tree (&OMP_FOR_BODY (stmt), cp_genericize_r, data, NULL);
kono
parents:
diff changeset
377 if (TREE_CODE (stmt) != OMP_TASKLOOP)
kono
parents:
diff changeset
378 cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_genericize_r, data, NULL);
kono
parents:
diff changeset
379 cp_walk_tree (&OMP_FOR_INIT (stmt), cp_genericize_r, data, NULL);
kono
parents:
diff changeset
380 cp_walk_tree (&OMP_FOR_COND (stmt), cp_genericize_r, data, NULL);
kono
parents:
diff changeset
381 cp_walk_tree (&OMP_FOR_INCR (stmt), cp_genericize_r, data, NULL);
kono
parents:
diff changeset
382 cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_genericize_r, data, NULL);
kono
parents:
diff changeset
383 *walk_subtrees = 0;
kono
parents:
diff changeset
384
kono
parents:
diff changeset
385 finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab);
kono
parents:
diff changeset
386 }
kono
parents:
diff changeset
387
kono
parents:
diff changeset
388 /* Hook into the middle of gimplifying an OMP_FOR node. */
kono
parents:
diff changeset
389
kono
parents:
diff changeset
390 static enum gimplify_status
kono
parents:
diff changeset
391 cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
kono
parents:
diff changeset
392 {
kono
parents:
diff changeset
393 tree for_stmt = *expr_p;
kono
parents:
diff changeset
394 gimple_seq seq = NULL;
kono
parents:
diff changeset
395
kono
parents:
diff changeset
396 /* Protect ourselves from recursion. */
kono
parents:
diff changeset
397 if (OMP_FOR_GIMPLIFYING_P (for_stmt))
kono
parents:
diff changeset
398 return GS_UNHANDLED;
kono
parents:
diff changeset
399 OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
kono
parents:
diff changeset
400
kono
parents:
diff changeset
401 gimplify_and_add (for_stmt, &seq);
kono
parents:
diff changeset
402 gimple_seq_add_seq (pre_p, seq);
kono
parents:
diff changeset
403
kono
parents:
diff changeset
404 OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 return GS_ALL_DONE;
kono
parents:
diff changeset
407 }
kono
parents:
diff changeset
408
kono
parents:
diff changeset
409 /* Gimplify an EXPR_STMT node. */
kono
parents:
diff changeset
410
kono
parents:
diff changeset
411 static void
kono
parents:
diff changeset
412 gimplify_expr_stmt (tree *stmt_p)
kono
parents:
diff changeset
413 {
kono
parents:
diff changeset
414 tree stmt = EXPR_STMT_EXPR (*stmt_p);
kono
parents:
diff changeset
415
kono
parents:
diff changeset
416 if (stmt == error_mark_node)
kono
parents:
diff changeset
417 stmt = NULL;
kono
parents:
diff changeset
418
kono
parents:
diff changeset
419 /* Gimplification of a statement expression will nullify the
kono
parents:
diff changeset
420 statement if all its side effects are moved to *PRE_P and *POST_P.
kono
parents:
diff changeset
421
kono
parents:
diff changeset
422 In this case we will not want to emit the gimplified statement.
kono
parents:
diff changeset
423 However, we may still want to emit a warning, so we do that before
kono
parents:
diff changeset
424 gimplification. */
kono
parents:
diff changeset
425 if (stmt && warn_unused_value)
kono
parents:
diff changeset
426 {
kono
parents:
diff changeset
427 if (!TREE_SIDE_EFFECTS (stmt))
kono
parents:
diff changeset
428 {
kono
parents:
diff changeset
429 if (!IS_EMPTY_STMT (stmt)
kono
parents:
diff changeset
430 && !VOID_TYPE_P (TREE_TYPE (stmt))
kono
parents:
diff changeset
431 && !TREE_NO_WARNING (stmt))
kono
parents:
diff changeset
432 warning (OPT_Wunused_value, "statement with no effect");
kono
parents:
diff changeset
433 }
kono
parents:
diff changeset
434 else
kono
parents:
diff changeset
435 warn_if_unused_value (stmt, input_location);
kono
parents:
diff changeset
436 }
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 if (stmt == NULL_TREE)
kono
parents:
diff changeset
439 stmt = alloc_stmt_list ();
kono
parents:
diff changeset
440
kono
parents:
diff changeset
441 *stmt_p = stmt;
kono
parents:
diff changeset
442 }
kono
parents:
diff changeset
443
kono
parents:
diff changeset
444 /* Gimplify initialization from an AGGR_INIT_EXPR. */
kono
parents:
diff changeset
445
kono
parents:
diff changeset
446 static void
kono
parents:
diff changeset
447 cp_gimplify_init_expr (tree *expr_p)
kono
parents:
diff changeset
448 {
kono
parents:
diff changeset
449 tree from = TREE_OPERAND (*expr_p, 1);
kono
parents:
diff changeset
450 tree to = TREE_OPERAND (*expr_p, 0);
kono
parents:
diff changeset
451 tree t;
kono
parents:
diff changeset
452
kono
parents:
diff changeset
453 /* What about code that pulls out the temp and uses it elsewhere? I
kono
parents:
diff changeset
454 think that such code never uses the TARGET_EXPR as an initializer. If
kono
parents:
diff changeset
455 I'm wrong, we'll abort because the temp won't have any RTL. In that
kono
parents:
diff changeset
456 case, I guess we'll need to replace references somehow. */
kono
parents:
diff changeset
457 if (TREE_CODE (from) == TARGET_EXPR)
kono
parents:
diff changeset
458 from = TARGET_EXPR_INITIAL (from);
kono
parents:
diff changeset
459
kono
parents:
diff changeset
460 /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
kono
parents:
diff changeset
461 inside the TARGET_EXPR. */
kono
parents:
diff changeset
462 for (t = from; t; )
kono
parents:
diff changeset
463 {
kono
parents:
diff changeset
464 tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
kono
parents:
diff changeset
465
kono
parents:
diff changeset
466 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
kono
parents:
diff changeset
467 replace the slot operand with our target.
kono
parents:
diff changeset
468
kono
parents:
diff changeset
469 Should we add a target parm to gimplify_expr instead? No, as in this
kono
parents:
diff changeset
470 case we want to replace the INIT_EXPR. */
kono
parents:
diff changeset
471 if (TREE_CODE (sub) == AGGR_INIT_EXPR
kono
parents:
diff changeset
472 || TREE_CODE (sub) == VEC_INIT_EXPR)
kono
parents:
diff changeset
473 {
kono
parents:
diff changeset
474 if (TREE_CODE (sub) == AGGR_INIT_EXPR)
kono
parents:
diff changeset
475 AGGR_INIT_EXPR_SLOT (sub) = to;
kono
parents:
diff changeset
476 else
kono
parents:
diff changeset
477 VEC_INIT_EXPR_SLOT (sub) = to;
kono
parents:
diff changeset
478 *expr_p = from;
kono
parents:
diff changeset
479
kono
parents:
diff changeset
480 /* The initialization is now a side-effect, so the container can
kono
parents:
diff changeset
481 become void. */
kono
parents:
diff changeset
482 if (from != sub)
kono
parents:
diff changeset
483 TREE_TYPE (from) = void_type_node;
kono
parents:
diff changeset
484 }
kono
parents:
diff changeset
485
kono
parents:
diff changeset
486 /* Handle aggregate NSDMI. */
kono
parents:
diff changeset
487 replace_placeholders (sub, to);
kono
parents:
diff changeset
488
kono
parents:
diff changeset
489 if (t == sub)
kono
parents:
diff changeset
490 break;
kono
parents:
diff changeset
491 else
kono
parents:
diff changeset
492 t = TREE_OPERAND (t, 1);
kono
parents:
diff changeset
493 }
kono
parents:
diff changeset
494
kono
parents:
diff changeset
495 }
kono
parents:
diff changeset
496
kono
parents:
diff changeset
497 /* Gimplify a MUST_NOT_THROW_EXPR. */
kono
parents:
diff changeset
498
kono
parents:
diff changeset
499 static enum gimplify_status
kono
parents:
diff changeset
500 gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
kono
parents:
diff changeset
501 {
kono
parents:
diff changeset
502 tree stmt = *expr_p;
kono
parents:
diff changeset
503 tree temp = voidify_wrapper_expr (stmt, NULL);
kono
parents:
diff changeset
504 tree body = TREE_OPERAND (stmt, 0);
kono
parents:
diff changeset
505 gimple_seq try_ = NULL;
kono
parents:
diff changeset
506 gimple_seq catch_ = NULL;
kono
parents:
diff changeset
507 gimple *mnt;
kono
parents:
diff changeset
508
kono
parents:
diff changeset
509 gimplify_and_add (body, &try_);
kono
parents:
diff changeset
510 mnt = gimple_build_eh_must_not_throw (terminate_fn);
kono
parents:
diff changeset
511 gimple_seq_add_stmt_without_update (&catch_, mnt);
kono
parents:
diff changeset
512 mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
kono
parents:
diff changeset
513
kono
parents:
diff changeset
514 gimple_seq_add_stmt_without_update (pre_p, mnt);
kono
parents:
diff changeset
515 if (temp)
kono
parents:
diff changeset
516 {
kono
parents:
diff changeset
517 *expr_p = temp;
kono
parents:
diff changeset
518 return GS_OK;
kono
parents:
diff changeset
519 }
kono
parents:
diff changeset
520
kono
parents:
diff changeset
521 *expr_p = NULL;
kono
parents:
diff changeset
522 return GS_ALL_DONE;
kono
parents:
diff changeset
523 }
kono
parents:
diff changeset
524
kono
parents:
diff changeset
525 /* Return TRUE if an operand (OP) of a given TYPE being copied is
kono
parents:
diff changeset
526 really just an empty class copy.
kono
parents:
diff changeset
527
kono
parents:
diff changeset
528 Check that the operand has a simple form so that TARGET_EXPRs and
kono
parents:
diff changeset
529 non-empty CONSTRUCTORs get reduced properly, and we leave the
kono
parents:
diff changeset
530 return slot optimization alone because it isn't a copy. */
kono
parents:
diff changeset
531
kono
parents:
diff changeset
532 static bool
kono
parents:
diff changeset
533 simple_empty_class_p (tree type, tree op)
kono
parents:
diff changeset
534 {
kono
parents:
diff changeset
535 return
kono
parents:
diff changeset
536 ((TREE_CODE (op) == COMPOUND_EXPR
kono
parents:
diff changeset
537 && simple_empty_class_p (type, TREE_OPERAND (op, 1)))
kono
parents:
diff changeset
538 || TREE_CODE (op) == EMPTY_CLASS_EXPR
kono
parents:
diff changeset
539 || is_gimple_lvalue (op)
kono
parents:
diff changeset
540 || INDIRECT_REF_P (op)
kono
parents:
diff changeset
541 || (TREE_CODE (op) == CONSTRUCTOR
kono
parents:
diff changeset
542 && CONSTRUCTOR_NELTS (op) == 0
kono
parents:
diff changeset
543 && !TREE_CLOBBER_P (op))
kono
parents:
diff changeset
544 || (TREE_CODE (op) == CALL_EXPR
kono
parents:
diff changeset
545 && !CALL_EXPR_RETURN_SLOT_OPT (op)))
kono
parents:
diff changeset
546 && is_really_empty_class (type);
kono
parents:
diff changeset
547 }
kono
parents:
diff changeset
548
kono
parents:
diff changeset
549 /* Returns true if evaluating E as an lvalue has side-effects;
kono
parents:
diff changeset
550 specifically, a volatile lvalue has TREE_SIDE_EFFECTS, but it doesn't really
kono
parents:
diff changeset
551 have side-effects until there is a read or write through it. */
kono
parents:
diff changeset
552
kono
parents:
diff changeset
553 static bool
kono
parents:
diff changeset
554 lvalue_has_side_effects (tree e)
kono
parents:
diff changeset
555 {
kono
parents:
diff changeset
556 if (!TREE_SIDE_EFFECTS (e))
kono
parents:
diff changeset
557 return false;
kono
parents:
diff changeset
558 while (handled_component_p (e))
kono
parents:
diff changeset
559 {
kono
parents:
diff changeset
560 if (TREE_CODE (e) == ARRAY_REF
kono
parents:
diff changeset
561 && TREE_SIDE_EFFECTS (TREE_OPERAND (e, 1)))
kono
parents:
diff changeset
562 return true;
kono
parents:
diff changeset
563 e = TREE_OPERAND (e, 0);
kono
parents:
diff changeset
564 }
kono
parents:
diff changeset
565 if (DECL_P (e))
kono
parents:
diff changeset
566 /* Just naming a variable has no side-effects. */
kono
parents:
diff changeset
567 return false;
kono
parents:
diff changeset
568 else if (INDIRECT_REF_P (e))
kono
parents:
diff changeset
569 /* Similarly, indirection has no side-effects. */
kono
parents:
diff changeset
570 return TREE_SIDE_EFFECTS (TREE_OPERAND (e, 0));
kono
parents:
diff changeset
571 else
kono
parents:
diff changeset
572 /* For anything else, trust TREE_SIDE_EFFECTS. */
kono
parents:
diff changeset
573 return TREE_SIDE_EFFECTS (e);
kono
parents:
diff changeset
574 }
kono
parents:
diff changeset
575
kono
parents:
diff changeset
576 /* Do C++-specific gimplification. Args are as for gimplify_expr. */
kono
parents:
diff changeset
577
kono
parents:
diff changeset
578 int
kono
parents:
diff changeset
579 cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
kono
parents:
diff changeset
580 {
kono
parents:
diff changeset
581 int saved_stmts_are_full_exprs_p = 0;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
582 location_t loc = cp_expr_loc_or_loc (*expr_p, input_location);
111
kono
parents:
diff changeset
583 enum tree_code code = TREE_CODE (*expr_p);
kono
parents:
diff changeset
584 enum gimplify_status ret;
kono
parents:
diff changeset
585
kono
parents:
diff changeset
586 if (STATEMENT_CODE_P (code))
kono
parents:
diff changeset
587 {
kono
parents:
diff changeset
588 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
kono
parents:
diff changeset
589 current_stmt_tree ()->stmts_are_full_exprs_p
kono
parents:
diff changeset
590 = STMT_IS_FULL_EXPR_P (*expr_p);
kono
parents:
diff changeset
591 }
kono
parents:
diff changeset
592
kono
parents:
diff changeset
593 switch (code)
kono
parents:
diff changeset
594 {
kono
parents:
diff changeset
595 case AGGR_INIT_EXPR:
kono
parents:
diff changeset
596 simplify_aggr_init_expr (expr_p);
kono
parents:
diff changeset
597 ret = GS_OK;
kono
parents:
diff changeset
598 break;
kono
parents:
diff changeset
599
kono
parents:
diff changeset
600 case VEC_INIT_EXPR:
kono
parents:
diff changeset
601 {
kono
parents:
diff changeset
602 location_t loc = input_location;
kono
parents:
diff changeset
603 tree init = VEC_INIT_EXPR_INIT (*expr_p);
kono
parents:
diff changeset
604 int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
kono
parents:
diff changeset
605 gcc_assert (EXPR_HAS_LOCATION (*expr_p));
kono
parents:
diff changeset
606 input_location = EXPR_LOCATION (*expr_p);
kono
parents:
diff changeset
607 *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
kono
parents:
diff changeset
608 init, VEC_INIT_EXPR_VALUE_INIT (*expr_p),
kono
parents:
diff changeset
609 from_array,
kono
parents:
diff changeset
610 tf_warning_or_error);
kono
parents:
diff changeset
611 hash_set<tree> pset;
kono
parents:
diff changeset
612 cp_walk_tree (expr_p, cp_fold_r, &pset, NULL);
kono
parents:
diff changeset
613 cp_genericize_tree (expr_p, false);
kono
parents:
diff changeset
614 ret = GS_OK;
kono
parents:
diff changeset
615 input_location = loc;
kono
parents:
diff changeset
616 }
kono
parents:
diff changeset
617 break;
kono
parents:
diff changeset
618
kono
parents:
diff changeset
619 case THROW_EXPR:
kono
parents:
diff changeset
620 /* FIXME communicate throw type to back end, probably by moving
kono
parents:
diff changeset
621 THROW_EXPR into ../tree.def. */
kono
parents:
diff changeset
622 *expr_p = TREE_OPERAND (*expr_p, 0);
kono
parents:
diff changeset
623 ret = GS_OK;
kono
parents:
diff changeset
624 break;
kono
parents:
diff changeset
625
kono
parents:
diff changeset
626 case MUST_NOT_THROW_EXPR:
kono
parents:
diff changeset
627 ret = gimplify_must_not_throw_expr (expr_p, pre_p);
kono
parents:
diff changeset
628 break;
kono
parents:
diff changeset
629
kono
parents:
diff changeset
630 /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
kono
parents:
diff changeset
631 LHS of an assignment might also be involved in the RHS, as in bug
kono
parents:
diff changeset
632 25979. */
kono
parents:
diff changeset
633 case INIT_EXPR:
kono
parents:
diff changeset
634 cp_gimplify_init_expr (expr_p);
kono
parents:
diff changeset
635 if (TREE_CODE (*expr_p) != INIT_EXPR)
kono
parents:
diff changeset
636 return GS_OK;
kono
parents:
diff changeset
637 /* Fall through. */
kono
parents:
diff changeset
638 case MODIFY_EXPR:
kono
parents:
diff changeset
639 modify_expr_case:
kono
parents:
diff changeset
640 {
kono
parents:
diff changeset
641 /* If the back end isn't clever enough to know that the lhs and rhs
kono
parents:
diff changeset
642 types are the same, add an explicit conversion. */
kono
parents:
diff changeset
643 tree op0 = TREE_OPERAND (*expr_p, 0);
kono
parents:
diff changeset
644 tree op1 = TREE_OPERAND (*expr_p, 1);
kono
parents:
diff changeset
645
kono
parents:
diff changeset
646 if (!error_operand_p (op0)
kono
parents:
diff changeset
647 && !error_operand_p (op1)
kono
parents:
diff changeset
648 && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
kono
parents:
diff changeset
649 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
kono
parents:
diff changeset
650 && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
kono
parents:
diff changeset
651 TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
kono
parents:
diff changeset
652 TREE_TYPE (op0), op1);
kono
parents:
diff changeset
653
kono
parents:
diff changeset
654 else if (simple_empty_class_p (TREE_TYPE (op0), op1))
kono
parents:
diff changeset
655 {
kono
parents:
diff changeset
656 /* Remove any copies of empty classes. Also drop volatile
kono
parents:
diff changeset
657 variables on the RHS to avoid infinite recursion from
kono
parents:
diff changeset
658 gimplify_expr trying to load the value. */
kono
parents:
diff changeset
659 if (TREE_SIDE_EFFECTS (op1))
kono
parents:
diff changeset
660 {
kono
parents:
diff changeset
661 if (TREE_THIS_VOLATILE (op1)
kono
parents:
diff changeset
662 && (REFERENCE_CLASS_P (op1) || DECL_P (op1)))
kono
parents:
diff changeset
663 op1 = build_fold_addr_expr (op1);
kono
parents:
diff changeset
664
kono
parents:
diff changeset
665 gimplify_and_add (op1, pre_p);
kono
parents:
diff changeset
666 }
kono
parents:
diff changeset
667 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
kono
parents:
diff changeset
668 is_gimple_lvalue, fb_lvalue);
kono
parents:
diff changeset
669 *expr_p = TREE_OPERAND (*expr_p, 0);
kono
parents:
diff changeset
670 }
kono
parents:
diff changeset
671 /* P0145 says that the RHS is sequenced before the LHS.
kono
parents:
diff changeset
672 gimplify_modify_expr gimplifies the RHS before the LHS, but that
kono
parents:
diff changeset
673 isn't quite strong enough in two cases:
kono
parents:
diff changeset
674
kono
parents:
diff changeset
675 1) gimplify.c wants to leave a CALL_EXPR on the RHS, which would
kono
parents:
diff changeset
676 mean it's evaluated after the LHS.
kono
parents:
diff changeset
677
kono
parents:
diff changeset
678 2) the value calculation of the RHS is also sequenced before the
kono
parents:
diff changeset
679 LHS, so for scalar assignment we need to preevaluate if the
kono
parents:
diff changeset
680 RHS could be affected by LHS side-effects even if it has no
kono
parents:
diff changeset
681 side-effects of its own. We don't need this for classes because
kono
parents:
diff changeset
682 class assignment takes its RHS by reference. */
kono
parents:
diff changeset
683 else if (flag_strong_eval_order > 1
kono
parents:
diff changeset
684 && TREE_CODE (*expr_p) == MODIFY_EXPR
kono
parents:
diff changeset
685 && lvalue_has_side_effects (op0)
kono
parents:
diff changeset
686 && (TREE_CODE (op1) == CALL_EXPR
kono
parents:
diff changeset
687 || (SCALAR_TYPE_P (TREE_TYPE (op1))
kono
parents:
diff changeset
688 && !TREE_CONSTANT (op1))))
kono
parents:
diff changeset
689 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (op1, pre_p);
kono
parents:
diff changeset
690 }
kono
parents:
diff changeset
691 ret = GS_OK;
kono
parents:
diff changeset
692 break;
kono
parents:
diff changeset
693
kono
parents:
diff changeset
694 case EMPTY_CLASS_EXPR:
kono
parents:
diff changeset
695 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
kono
parents:
diff changeset
696 *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
kono
parents:
diff changeset
697 ret = GS_OK;
kono
parents:
diff changeset
698 break;
kono
parents:
diff changeset
699
kono
parents:
diff changeset
700 case BASELINK:
kono
parents:
diff changeset
701 *expr_p = BASELINK_FUNCTIONS (*expr_p);
kono
parents:
diff changeset
702 ret = GS_OK;
kono
parents:
diff changeset
703 break;
kono
parents:
diff changeset
704
kono
parents:
diff changeset
705 case TRY_BLOCK:
kono
parents:
diff changeset
706 genericize_try_block (expr_p);
kono
parents:
diff changeset
707 ret = GS_OK;
kono
parents:
diff changeset
708 break;
kono
parents:
diff changeset
709
kono
parents:
diff changeset
710 case HANDLER:
kono
parents:
diff changeset
711 genericize_catch_block (expr_p);
kono
parents:
diff changeset
712 ret = GS_OK;
kono
parents:
diff changeset
713 break;
kono
parents:
diff changeset
714
kono
parents:
diff changeset
715 case EH_SPEC_BLOCK:
kono
parents:
diff changeset
716 genericize_eh_spec_block (expr_p);
kono
parents:
diff changeset
717 ret = GS_OK;
kono
parents:
diff changeset
718 break;
kono
parents:
diff changeset
719
kono
parents:
diff changeset
720 case USING_STMT:
kono
parents:
diff changeset
721 gcc_unreachable ();
kono
parents:
diff changeset
722
kono
parents:
diff changeset
723 case FOR_STMT:
kono
parents:
diff changeset
724 case WHILE_STMT:
kono
parents:
diff changeset
725 case DO_STMT:
kono
parents:
diff changeset
726 case SWITCH_STMT:
kono
parents:
diff changeset
727 case CONTINUE_STMT:
kono
parents:
diff changeset
728 case BREAK_STMT:
kono
parents:
diff changeset
729 gcc_unreachable ();
kono
parents:
diff changeset
730
kono
parents:
diff changeset
731 case OMP_FOR:
kono
parents:
diff changeset
732 case OMP_SIMD:
kono
parents:
diff changeset
733 case OMP_DISTRIBUTE:
kono
parents:
diff changeset
734 case OMP_TASKLOOP:
kono
parents:
diff changeset
735 ret = cp_gimplify_omp_for (expr_p, pre_p);
kono
parents:
diff changeset
736 break;
kono
parents:
diff changeset
737
kono
parents:
diff changeset
738 case EXPR_STMT:
kono
parents:
diff changeset
739 gimplify_expr_stmt (expr_p);
kono
parents:
diff changeset
740 ret = GS_OK;
kono
parents:
diff changeset
741 break;
kono
parents:
diff changeset
742
kono
parents:
diff changeset
743 case UNARY_PLUS_EXPR:
kono
parents:
diff changeset
744 {
kono
parents:
diff changeset
745 tree arg = TREE_OPERAND (*expr_p, 0);
kono
parents:
diff changeset
746 tree type = TREE_TYPE (*expr_p);
kono
parents:
diff changeset
747 *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
kono
parents:
diff changeset
748 : arg;
kono
parents:
diff changeset
749 ret = GS_OK;
kono
parents:
diff changeset
750 }
kono
parents:
diff changeset
751 break;
kono
parents:
diff changeset
752
kono
parents:
diff changeset
753 case CALL_EXPR:
kono
parents:
diff changeset
754 ret = GS_OK;
kono
parents:
diff changeset
755 if (!CALL_EXPR_FN (*expr_p))
kono
parents:
diff changeset
756 /* Internal function call. */;
kono
parents:
diff changeset
757 else if (CALL_EXPR_REVERSE_ARGS (*expr_p))
kono
parents:
diff changeset
758 {
kono
parents:
diff changeset
759 /* This is a call to a (compound) assignment operator that used
kono
parents:
diff changeset
760 the operator syntax; gimplify the RHS first. */
kono
parents:
diff changeset
761 gcc_assert (call_expr_nargs (*expr_p) == 2);
kono
parents:
diff changeset
762 gcc_assert (!CALL_EXPR_ORDERED_ARGS (*expr_p));
kono
parents:
diff changeset
763 enum gimplify_status t
kono
parents:
diff changeset
764 = gimplify_arg (&CALL_EXPR_ARG (*expr_p, 1), pre_p, loc);
kono
parents:
diff changeset
765 if (t == GS_ERROR)
kono
parents:
diff changeset
766 ret = GS_ERROR;
kono
parents:
diff changeset
767 }
kono
parents:
diff changeset
768 else if (CALL_EXPR_ORDERED_ARGS (*expr_p))
kono
parents:
diff changeset
769 {
kono
parents:
diff changeset
770 /* Leave the last argument for gimplify_call_expr, to avoid problems
kono
parents:
diff changeset
771 with __builtin_va_arg_pack(). */
kono
parents:
diff changeset
772 int nargs = call_expr_nargs (*expr_p) - 1;
kono
parents:
diff changeset
773 for (int i = 0; i < nargs; ++i)
kono
parents:
diff changeset
774 {
kono
parents:
diff changeset
775 enum gimplify_status t
kono
parents:
diff changeset
776 = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc);
kono
parents:
diff changeset
777 if (t == GS_ERROR)
kono
parents:
diff changeset
778 ret = GS_ERROR;
kono
parents:
diff changeset
779 }
kono
parents:
diff changeset
780 }
kono
parents:
diff changeset
781 else if (flag_strong_eval_order
kono
parents:
diff changeset
782 && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p))
kono
parents:
diff changeset
783 {
kono
parents:
diff changeset
784 /* If flag_strong_eval_order, evaluate the object argument first. */
kono
parents:
diff changeset
785 tree fntype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
786 if (INDIRECT_TYPE_P (fntype))
111
kono
parents:
diff changeset
787 fntype = TREE_TYPE (fntype);
kono
parents:
diff changeset
788 if (TREE_CODE (fntype) == METHOD_TYPE)
kono
parents:
diff changeset
789 {
kono
parents:
diff changeset
790 enum gimplify_status t
kono
parents:
diff changeset
791 = gimplify_arg (&CALL_EXPR_ARG (*expr_p, 0), pre_p, loc);
kono
parents:
diff changeset
792 if (t == GS_ERROR)
kono
parents:
diff changeset
793 ret = GS_ERROR;
kono
parents:
diff changeset
794 }
kono
parents:
diff changeset
795 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
796 if (ret != GS_ERROR)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
797 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
798 tree decl = cp_get_callee_fndecl_nofold (*expr_p);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
799 if (decl
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
800 && fndecl_built_in_p (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
801 BUILT_IN_FRONTEND))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
802 *expr_p = boolean_false_node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
803 }
111
kono
parents:
diff changeset
804 break;
kono
parents:
diff changeset
805
kono
parents:
diff changeset
806 case RETURN_EXPR:
kono
parents:
diff changeset
807 if (TREE_OPERAND (*expr_p, 0)
kono
parents:
diff changeset
808 && (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == INIT_EXPR
kono
parents:
diff changeset
809 || TREE_CODE (TREE_OPERAND (*expr_p, 0)) == MODIFY_EXPR))
kono
parents:
diff changeset
810 {
kono
parents:
diff changeset
811 expr_p = &TREE_OPERAND (*expr_p, 0);
kono
parents:
diff changeset
812 code = TREE_CODE (*expr_p);
kono
parents:
diff changeset
813 /* Avoid going through the INIT_EXPR case, which can
kono
parents:
diff changeset
814 degrade INIT_EXPRs into AGGR_INIT_EXPRs. */
kono
parents:
diff changeset
815 goto modify_expr_case;
kono
parents:
diff changeset
816 }
kono
parents:
diff changeset
817 /* Fall through. */
kono
parents:
diff changeset
818
kono
parents:
diff changeset
819 default:
kono
parents:
diff changeset
820 ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
kono
parents:
diff changeset
821 break;
kono
parents:
diff changeset
822 }
kono
parents:
diff changeset
823
kono
parents:
diff changeset
824 /* Restore saved state. */
kono
parents:
diff changeset
825 if (STATEMENT_CODE_P (code))
kono
parents:
diff changeset
826 current_stmt_tree ()->stmts_are_full_exprs_p
kono
parents:
diff changeset
827 = saved_stmts_are_full_exprs_p;
kono
parents:
diff changeset
828
kono
parents:
diff changeset
829 return ret;
kono
parents:
diff changeset
830 }
kono
parents:
diff changeset
831
kono
parents:
diff changeset
832 static inline bool
kono
parents:
diff changeset
833 is_invisiref_parm (const_tree t)
kono
parents:
diff changeset
834 {
kono
parents:
diff changeset
835 return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
kono
parents:
diff changeset
836 && DECL_BY_REFERENCE (t));
kono
parents:
diff changeset
837 }
kono
parents:
diff changeset
838
kono
parents:
diff changeset
839 /* Return true if the uid in both int tree maps are equal. */
kono
parents:
diff changeset
840
kono
parents:
diff changeset
841 bool
kono
parents:
diff changeset
842 cxx_int_tree_map_hasher::equal (cxx_int_tree_map *a, cxx_int_tree_map *b)
kono
parents:
diff changeset
843 {
kono
parents:
diff changeset
844 return (a->uid == b->uid);
kono
parents:
diff changeset
845 }
kono
parents:
diff changeset
846
kono
parents:
diff changeset
847 /* Hash a UID in a cxx_int_tree_map. */
kono
parents:
diff changeset
848
kono
parents:
diff changeset
849 unsigned int
kono
parents:
diff changeset
850 cxx_int_tree_map_hasher::hash (cxx_int_tree_map *item)
kono
parents:
diff changeset
851 {
kono
parents:
diff changeset
852 return item->uid;
kono
parents:
diff changeset
853 }
kono
parents:
diff changeset
854
kono
parents:
diff changeset
855 /* A stable comparison routine for use with splay trees and DECLs. */
kono
parents:
diff changeset
856
kono
parents:
diff changeset
857 static int
kono
parents:
diff changeset
858 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
kono
parents:
diff changeset
859 {
kono
parents:
diff changeset
860 tree a = (tree) xa;
kono
parents:
diff changeset
861 tree b = (tree) xb;
kono
parents:
diff changeset
862
kono
parents:
diff changeset
863 return DECL_UID (a) - DECL_UID (b);
kono
parents:
diff changeset
864 }
kono
parents:
diff changeset
865
kono
parents:
diff changeset
866 /* OpenMP context during genericization. */
kono
parents:
diff changeset
867
kono
parents:
diff changeset
868 struct cp_genericize_omp_taskreg
kono
parents:
diff changeset
869 {
kono
parents:
diff changeset
870 bool is_parallel;
kono
parents:
diff changeset
871 bool default_shared;
kono
parents:
diff changeset
872 struct cp_genericize_omp_taskreg *outer;
kono
parents:
diff changeset
873 splay_tree variables;
kono
parents:
diff changeset
874 };
kono
parents:
diff changeset
875
kono
parents:
diff changeset
876 /* Return true if genericization should try to determine if
kono
parents:
diff changeset
877 DECL is firstprivate or shared within task regions. */
kono
parents:
diff changeset
878
kono
parents:
diff changeset
879 static bool
kono
parents:
diff changeset
880 omp_var_to_track (tree decl)
kono
parents:
diff changeset
881 {
kono
parents:
diff changeset
882 tree type = TREE_TYPE (decl);
kono
parents:
diff changeset
883 if (is_invisiref_parm (decl))
kono
parents:
diff changeset
884 type = TREE_TYPE (type);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
885 else if (TYPE_REF_P (type))
111
kono
parents:
diff changeset
886 type = TREE_TYPE (type);
kono
parents:
diff changeset
887 while (TREE_CODE (type) == ARRAY_TYPE)
kono
parents:
diff changeset
888 type = TREE_TYPE (type);
kono
parents:
diff changeset
889 if (type == error_mark_node || !CLASS_TYPE_P (type))
kono
parents:
diff changeset
890 return false;
kono
parents:
diff changeset
891 if (VAR_P (decl) && CP_DECL_THREAD_LOCAL_P (decl))
kono
parents:
diff changeset
892 return false;
kono
parents:
diff changeset
893 if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
kono
parents:
diff changeset
894 return false;
kono
parents:
diff changeset
895 return true;
kono
parents:
diff changeset
896 }
kono
parents:
diff changeset
897
kono
parents:
diff changeset
898 /* Note DECL use in OpenMP region OMP_CTX during genericization. */
kono
parents:
diff changeset
899
kono
parents:
diff changeset
900 static void
kono
parents:
diff changeset
901 omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl)
kono
parents:
diff changeset
902 {
kono
parents:
diff changeset
903 splay_tree_node n = splay_tree_lookup (omp_ctx->variables,
kono
parents:
diff changeset
904 (splay_tree_key) decl);
kono
parents:
diff changeset
905 if (n == NULL)
kono
parents:
diff changeset
906 {
kono
parents:
diff changeset
907 int flags = OMP_CLAUSE_DEFAULT_SHARED;
kono
parents:
diff changeset
908 if (omp_ctx->outer)
kono
parents:
diff changeset
909 omp_cxx_notice_variable (omp_ctx->outer, decl);
kono
parents:
diff changeset
910 if (!omp_ctx->default_shared)
kono
parents:
diff changeset
911 {
kono
parents:
diff changeset
912 struct cp_genericize_omp_taskreg *octx;
kono
parents:
diff changeset
913
kono
parents:
diff changeset
914 for (octx = omp_ctx->outer; octx; octx = octx->outer)
kono
parents:
diff changeset
915 {
kono
parents:
diff changeset
916 n = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
kono
parents:
diff changeset
917 if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED)
kono
parents:
diff changeset
918 {
kono
parents:
diff changeset
919 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
kono
parents:
diff changeset
920 break;
kono
parents:
diff changeset
921 }
kono
parents:
diff changeset
922 if (octx->is_parallel)
kono
parents:
diff changeset
923 break;
kono
parents:
diff changeset
924 }
kono
parents:
diff changeset
925 if (octx == NULL
kono
parents:
diff changeset
926 && (TREE_CODE (decl) == PARM_DECL
kono
parents:
diff changeset
927 || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl))
kono
parents:
diff changeset
928 && DECL_CONTEXT (decl) == current_function_decl)))
kono
parents:
diff changeset
929 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
kono
parents:
diff changeset
930 if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
kono
parents:
diff changeset
931 {
kono
parents:
diff changeset
932 /* DECL is implicitly determined firstprivate in
kono
parents:
diff changeset
933 the current task construct. Ensure copy ctor and
kono
parents:
diff changeset
934 dtor are instantiated, because during gimplification
kono
parents:
diff changeset
935 it will be already too late. */
kono
parents:
diff changeset
936 tree type = TREE_TYPE (decl);
kono
parents:
diff changeset
937 if (is_invisiref_parm (decl))
kono
parents:
diff changeset
938 type = TREE_TYPE (type);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
939 else if (TYPE_REF_P (type))
111
kono
parents:
diff changeset
940 type = TREE_TYPE (type);
kono
parents:
diff changeset
941 while (TREE_CODE (type) == ARRAY_TYPE)
kono
parents:
diff changeset
942 type = TREE_TYPE (type);
kono
parents:
diff changeset
943 get_copy_ctor (type, tf_none);
kono
parents:
diff changeset
944 get_dtor (type, tf_none);
kono
parents:
diff changeset
945 }
kono
parents:
diff changeset
946 }
kono
parents:
diff changeset
947 splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags);
kono
parents:
diff changeset
948 }
kono
parents:
diff changeset
949 }
kono
parents:
diff changeset
950
kono
parents:
diff changeset
951 /* Genericization context. */
kono
parents:
diff changeset
952
kono
parents:
diff changeset
953 struct cp_genericize_data
kono
parents:
diff changeset
954 {
kono
parents:
diff changeset
955 hash_set<tree> *p_set;
kono
parents:
diff changeset
956 vec<tree> bind_expr_stack;
kono
parents:
diff changeset
957 struct cp_genericize_omp_taskreg *omp_ctx;
kono
parents:
diff changeset
958 tree try_block;
kono
parents:
diff changeset
959 bool no_sanitize_p;
kono
parents:
diff changeset
960 bool handle_invisiref_parm_p;
kono
parents:
diff changeset
961 };
kono
parents:
diff changeset
962
kono
parents:
diff changeset
963 /* Perform any pre-gimplification folding of C++ front end trees to
kono
parents:
diff changeset
964 GENERIC.
kono
parents:
diff changeset
965 Note: The folding of none-omp cases is something to move into
kono
parents:
diff changeset
966 the middle-end. As for now we have most foldings only on GENERIC
kono
parents:
diff changeset
967 in fold-const, we need to perform this before transformation to
kono
parents:
diff changeset
968 GIMPLE-form. */
kono
parents:
diff changeset
969
kono
parents:
diff changeset
970 static tree
kono
parents:
diff changeset
971 cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data)
kono
parents:
diff changeset
972 {
kono
parents:
diff changeset
973 tree stmt;
kono
parents:
diff changeset
974 enum tree_code code;
kono
parents:
diff changeset
975
kono
parents:
diff changeset
976 *stmt_p = stmt = cp_fold (*stmt_p);
kono
parents:
diff changeset
977
kono
parents:
diff changeset
978 if (((hash_set<tree> *) data)->add (stmt))
kono
parents:
diff changeset
979 {
kono
parents:
diff changeset
980 /* Don't walk subtrees of stmts we've already walked once, otherwise
kono
parents:
diff changeset
981 we can have exponential complexity with e.g. lots of nested
kono
parents:
diff changeset
982 SAVE_EXPRs or TARGET_EXPRs. cp_fold uses a cache and will return
kono
parents:
diff changeset
983 always the same tree, which the first time cp_fold_r has been
kono
parents:
diff changeset
984 called on it had the subtrees walked. */
kono
parents:
diff changeset
985 *walk_subtrees = 0;
kono
parents:
diff changeset
986 return NULL;
kono
parents:
diff changeset
987 }
kono
parents:
diff changeset
988
kono
parents:
diff changeset
989 code = TREE_CODE (stmt);
kono
parents:
diff changeset
990 if (code == OMP_FOR || code == OMP_SIMD || code == OMP_DISTRIBUTE
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
991 || code == OMP_TASKLOOP || code == OACC_LOOP)
111
kono
parents:
diff changeset
992 {
kono
parents:
diff changeset
993 tree x;
kono
parents:
diff changeset
994 int i, n;
kono
parents:
diff changeset
995
kono
parents:
diff changeset
996 cp_walk_tree (&OMP_FOR_BODY (stmt), cp_fold_r, data, NULL);
kono
parents:
diff changeset
997 cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_fold_r, data, NULL);
kono
parents:
diff changeset
998 cp_walk_tree (&OMP_FOR_INIT (stmt), cp_fold_r, data, NULL);
kono
parents:
diff changeset
999 x = OMP_FOR_COND (stmt);
kono
parents:
diff changeset
1000 if (x && TREE_CODE_CLASS (TREE_CODE (x)) == tcc_comparison)
kono
parents:
diff changeset
1001 {
kono
parents:
diff changeset
1002 cp_walk_tree (&TREE_OPERAND (x, 0), cp_fold_r, data, NULL);
kono
parents:
diff changeset
1003 cp_walk_tree (&TREE_OPERAND (x, 1), cp_fold_r, data, NULL);
kono
parents:
diff changeset
1004 }
kono
parents:
diff changeset
1005 else if (x && TREE_CODE (x) == TREE_VEC)
kono
parents:
diff changeset
1006 {
kono
parents:
diff changeset
1007 n = TREE_VEC_LENGTH (x);
kono
parents:
diff changeset
1008 for (i = 0; i < n; i++)
kono
parents:
diff changeset
1009 {
kono
parents:
diff changeset
1010 tree o = TREE_VEC_ELT (x, i);
kono
parents:
diff changeset
1011 if (o && TREE_CODE_CLASS (TREE_CODE (o)) == tcc_comparison)
kono
parents:
diff changeset
1012 cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL);
kono
parents:
diff changeset
1013 }
kono
parents:
diff changeset
1014 }
kono
parents:
diff changeset
1015 x = OMP_FOR_INCR (stmt);
kono
parents:
diff changeset
1016 if (x && TREE_CODE (x) == TREE_VEC)
kono
parents:
diff changeset
1017 {
kono
parents:
diff changeset
1018 n = TREE_VEC_LENGTH (x);
kono
parents:
diff changeset
1019 for (i = 0; i < n; i++)
kono
parents:
diff changeset
1020 {
kono
parents:
diff changeset
1021 tree o = TREE_VEC_ELT (x, i);
kono
parents:
diff changeset
1022 if (o && TREE_CODE (o) == MODIFY_EXPR)
kono
parents:
diff changeset
1023 o = TREE_OPERAND (o, 1);
kono
parents:
diff changeset
1024 if (o && (TREE_CODE (o) == PLUS_EXPR || TREE_CODE (o) == MINUS_EXPR
kono
parents:
diff changeset
1025 || TREE_CODE (o) == POINTER_PLUS_EXPR))
kono
parents:
diff changeset
1026 {
kono
parents:
diff changeset
1027 cp_walk_tree (&TREE_OPERAND (o, 0), cp_fold_r, data, NULL);
kono
parents:
diff changeset
1028 cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL);
kono
parents:
diff changeset
1029 }
kono
parents:
diff changeset
1030 }
kono
parents:
diff changeset
1031 }
kono
parents:
diff changeset
1032 cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_fold_r, data, NULL);
kono
parents:
diff changeset
1033 *walk_subtrees = 0;
kono
parents:
diff changeset
1034 }
kono
parents:
diff changeset
1035
kono
parents:
diff changeset
1036 return NULL;
kono
parents:
diff changeset
1037 }
kono
parents:
diff changeset
1038
kono
parents:
diff changeset
1039 /* Fold ALL the trees! FIXME we should be able to remove this, but
kono
parents:
diff changeset
1040 apparently that still causes optimization regressions. */
kono
parents:
diff changeset
1041
kono
parents:
diff changeset
1042 void
kono
parents:
diff changeset
1043 cp_fold_function (tree fndecl)
kono
parents:
diff changeset
1044 {
kono
parents:
diff changeset
1045 hash_set<tree> pset;
kono
parents:
diff changeset
1046 cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &pset, NULL);
kono
parents:
diff changeset
1047 }
kono
parents:
diff changeset
1048
kono
parents:
diff changeset
1049 /* Perform any pre-gimplification lowering of C++ front end trees to
kono
parents:
diff changeset
1050 GENERIC. */
kono
parents:
diff changeset
1051
kono
parents:
diff changeset
1052 static tree
kono
parents:
diff changeset
1053 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
kono
parents:
diff changeset
1054 {
kono
parents:
diff changeset
1055 tree stmt = *stmt_p;
kono
parents:
diff changeset
1056 struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
kono
parents:
diff changeset
1057 hash_set<tree> *p_set = wtd->p_set;
kono
parents:
diff changeset
1058
kono
parents:
diff changeset
1059 /* If in an OpenMP context, note var uses. */
kono
parents:
diff changeset
1060 if (__builtin_expect (wtd->omp_ctx != NULL, 0)
kono
parents:
diff changeset
1061 && (VAR_P (stmt)
kono
parents:
diff changeset
1062 || TREE_CODE (stmt) == PARM_DECL
kono
parents:
diff changeset
1063 || TREE_CODE (stmt) == RESULT_DECL)
kono
parents:
diff changeset
1064 && omp_var_to_track (stmt))
kono
parents:
diff changeset
1065 omp_cxx_notice_variable (wtd->omp_ctx, stmt);
kono
parents:
diff changeset
1066
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1067 /* Don't dereference parms in a thunk, pass the references through. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1068 if ((TREE_CODE (stmt) == CALL_EXPR && CALL_FROM_THUNK_P (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1069 || (TREE_CODE (stmt) == AGGR_INIT_EXPR && AGGR_INIT_FROM_THUNK_P (stmt)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1070 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1071 *walk_subtrees = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1072 return NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1073 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1074
111
kono
parents:
diff changeset
1075 /* Dereference invisible reference parms. */
kono
parents:
diff changeset
1076 if (wtd->handle_invisiref_parm_p && is_invisiref_parm (stmt))
kono
parents:
diff changeset
1077 {
kono
parents:
diff changeset
1078 *stmt_p = convert_from_reference (stmt);
kono
parents:
diff changeset
1079 p_set->add (*stmt_p);
kono
parents:
diff changeset
1080 *walk_subtrees = 0;
kono
parents:
diff changeset
1081 return NULL;
kono
parents:
diff changeset
1082 }
kono
parents:
diff changeset
1083
kono
parents:
diff changeset
1084 /* Map block scope extern declarations to visible declarations with the
kono
parents:
diff changeset
1085 same name and type in outer scopes if any. */
kono
parents:
diff changeset
1086 if (cp_function_chain->extern_decl_map
kono
parents:
diff changeset
1087 && VAR_OR_FUNCTION_DECL_P (stmt)
kono
parents:
diff changeset
1088 && DECL_EXTERNAL (stmt))
kono
parents:
diff changeset
1089 {
kono
parents:
diff changeset
1090 struct cxx_int_tree_map *h, in;
kono
parents:
diff changeset
1091 in.uid = DECL_UID (stmt);
kono
parents:
diff changeset
1092 h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid);
kono
parents:
diff changeset
1093 if (h)
kono
parents:
diff changeset
1094 {
kono
parents:
diff changeset
1095 *stmt_p = h->to;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1096 TREE_USED (h->to) |= TREE_USED (stmt);
111
kono
parents:
diff changeset
1097 *walk_subtrees = 0;
kono
parents:
diff changeset
1098 return NULL;
kono
parents:
diff changeset
1099 }
kono
parents:
diff changeset
1100 }
kono
parents:
diff changeset
1101
kono
parents:
diff changeset
1102 if (TREE_CODE (stmt) == INTEGER_CST
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1103 && TYPE_REF_P (TREE_TYPE (stmt))
111
kono
parents:
diff changeset
1104 && (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
kono
parents:
diff changeset
1105 && !wtd->no_sanitize_p)
kono
parents:
diff changeset
1106 {
kono
parents:
diff changeset
1107 ubsan_maybe_instrument_reference (stmt_p);
kono
parents:
diff changeset
1108 if (*stmt_p != stmt)
kono
parents:
diff changeset
1109 {
kono
parents:
diff changeset
1110 *walk_subtrees = 0;
kono
parents:
diff changeset
1111 return NULL_TREE;
kono
parents:
diff changeset
1112 }
kono
parents:
diff changeset
1113 }
kono
parents:
diff changeset
1114
kono
parents:
diff changeset
1115 /* Other than invisiref parms, don't walk the same tree twice. */
kono
parents:
diff changeset
1116 if (p_set->contains (stmt))
kono
parents:
diff changeset
1117 {
kono
parents:
diff changeset
1118 *walk_subtrees = 0;
kono
parents:
diff changeset
1119 return NULL_TREE;
kono
parents:
diff changeset
1120 }
kono
parents:
diff changeset
1121
kono
parents:
diff changeset
1122 switch (TREE_CODE (stmt))
kono
parents:
diff changeset
1123 {
kono
parents:
diff changeset
1124 case ADDR_EXPR:
kono
parents:
diff changeset
1125 if (is_invisiref_parm (TREE_OPERAND (stmt, 0)))
kono
parents:
diff changeset
1126 {
kono
parents:
diff changeset
1127 /* If in an OpenMP context, note var uses. */
kono
parents:
diff changeset
1128 if (__builtin_expect (wtd->omp_ctx != NULL, 0)
kono
parents:
diff changeset
1129 && omp_var_to_track (TREE_OPERAND (stmt, 0)))
kono
parents:
diff changeset
1130 omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
kono
parents:
diff changeset
1131 *stmt_p = fold_convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
kono
parents:
diff changeset
1132 *walk_subtrees = 0;
kono
parents:
diff changeset
1133 }
kono
parents:
diff changeset
1134 break;
kono
parents:
diff changeset
1135
kono
parents:
diff changeset
1136 case RETURN_EXPR:
kono
parents:
diff changeset
1137 if (TREE_OPERAND (stmt, 0) && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
kono
parents:
diff changeset
1138 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */
kono
parents:
diff changeset
1139 *walk_subtrees = 0;
kono
parents:
diff changeset
1140 break;
kono
parents:
diff changeset
1141
kono
parents:
diff changeset
1142 case OMP_CLAUSE:
kono
parents:
diff changeset
1143 switch (OMP_CLAUSE_CODE (stmt))
kono
parents:
diff changeset
1144 {
kono
parents:
diff changeset
1145 case OMP_CLAUSE_LASTPRIVATE:
kono
parents:
diff changeset
1146 /* Don't dereference an invisiref in OpenMP clauses. */
kono
parents:
diff changeset
1147 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
kono
parents:
diff changeset
1148 {
kono
parents:
diff changeset
1149 *walk_subtrees = 0;
kono
parents:
diff changeset
1150 if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
kono
parents:
diff changeset
1151 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
kono
parents:
diff changeset
1152 cp_genericize_r, data, NULL);
kono
parents:
diff changeset
1153 }
kono
parents:
diff changeset
1154 break;
kono
parents:
diff changeset
1155 case OMP_CLAUSE_PRIVATE:
kono
parents:
diff changeset
1156 /* Don't dereference an invisiref in OpenMP clauses. */
kono
parents:
diff changeset
1157 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
kono
parents:
diff changeset
1158 *walk_subtrees = 0;
kono
parents:
diff changeset
1159 else if (wtd->omp_ctx != NULL)
kono
parents:
diff changeset
1160 {
kono
parents:
diff changeset
1161 /* Private clause doesn't cause any references to the
kono
parents:
diff changeset
1162 var in outer contexts, avoid calling
kono
parents:
diff changeset
1163 omp_cxx_notice_variable for it. */
kono
parents:
diff changeset
1164 struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
kono
parents:
diff changeset
1165 wtd->omp_ctx = NULL;
kono
parents:
diff changeset
1166 cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
kono
parents:
diff changeset
1167 data, NULL);
kono
parents:
diff changeset
1168 wtd->omp_ctx = old;
kono
parents:
diff changeset
1169 *walk_subtrees = 0;
kono
parents:
diff changeset
1170 }
kono
parents:
diff changeset
1171 break;
kono
parents:
diff changeset
1172 case OMP_CLAUSE_SHARED:
kono
parents:
diff changeset
1173 case OMP_CLAUSE_FIRSTPRIVATE:
kono
parents:
diff changeset
1174 case OMP_CLAUSE_COPYIN:
kono
parents:
diff changeset
1175 case OMP_CLAUSE_COPYPRIVATE:
kono
parents:
diff changeset
1176 /* Don't dereference an invisiref in OpenMP clauses. */
kono
parents:
diff changeset
1177 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
kono
parents:
diff changeset
1178 *walk_subtrees = 0;
kono
parents:
diff changeset
1179 break;
kono
parents:
diff changeset
1180 case OMP_CLAUSE_REDUCTION:
kono
parents:
diff changeset
1181 /* Don't dereference an invisiref in reduction clause's
kono
parents:
diff changeset
1182 OMP_CLAUSE_DECL either. OMP_CLAUSE_REDUCTION_{INIT,MERGE}
kono
parents:
diff changeset
1183 still needs to be genericized. */
kono
parents:
diff changeset
1184 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
kono
parents:
diff changeset
1185 {
kono
parents:
diff changeset
1186 *walk_subtrees = 0;
kono
parents:
diff changeset
1187 if (OMP_CLAUSE_REDUCTION_INIT (stmt))
kono
parents:
diff changeset
1188 cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
kono
parents:
diff changeset
1189 cp_genericize_r, data, NULL);
kono
parents:
diff changeset
1190 if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
kono
parents:
diff changeset
1191 cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
kono
parents:
diff changeset
1192 cp_genericize_r, data, NULL);
kono
parents:
diff changeset
1193 }
kono
parents:
diff changeset
1194 break;
kono
parents:
diff changeset
1195 default:
kono
parents:
diff changeset
1196 break;
kono
parents:
diff changeset
1197 }
kono
parents:
diff changeset
1198 break;
kono
parents:
diff changeset
1199
kono
parents:
diff changeset
1200 /* Due to the way voidify_wrapper_expr is written, we don't get a chance
kono
parents:
diff changeset
1201 to lower this construct before scanning it, so we need to lower these
kono
parents:
diff changeset
1202 before doing anything else. */
kono
parents:
diff changeset
1203 case CLEANUP_STMT:
kono
parents:
diff changeset
1204 *stmt_p = build2_loc (EXPR_LOCATION (stmt),
kono
parents:
diff changeset
1205 CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
kono
parents:
diff changeset
1206 : TRY_FINALLY_EXPR,
kono
parents:
diff changeset
1207 void_type_node,
kono
parents:
diff changeset
1208 CLEANUP_BODY (stmt),
kono
parents:
diff changeset
1209 CLEANUP_EXPR (stmt));
kono
parents:
diff changeset
1210 break;
kono
parents:
diff changeset
1211
kono
parents:
diff changeset
1212 case IF_STMT:
kono
parents:
diff changeset
1213 genericize_if_stmt (stmt_p);
kono
parents:
diff changeset
1214 /* *stmt_p has changed, tail recurse to handle it again. */
kono
parents:
diff changeset
1215 return cp_genericize_r (stmt_p, walk_subtrees, data);
kono
parents:
diff changeset
1216
kono
parents:
diff changeset
1217 /* COND_EXPR might have incompatible types in branches if one or both
kono
parents:
diff changeset
1218 arms are bitfields. Fix it up now. */
kono
parents:
diff changeset
1219 case COND_EXPR:
kono
parents:
diff changeset
1220 {
kono
parents:
diff changeset
1221 tree type_left
kono
parents:
diff changeset
1222 = (TREE_OPERAND (stmt, 1)
kono
parents:
diff changeset
1223 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
kono
parents:
diff changeset
1224 : NULL_TREE);
kono
parents:
diff changeset
1225 tree type_right
kono
parents:
diff changeset
1226 = (TREE_OPERAND (stmt, 2)
kono
parents:
diff changeset
1227 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
kono
parents:
diff changeset
1228 : NULL_TREE);
kono
parents:
diff changeset
1229 if (type_left
kono
parents:
diff changeset
1230 && !useless_type_conversion_p (TREE_TYPE (stmt),
kono
parents:
diff changeset
1231 TREE_TYPE (TREE_OPERAND (stmt, 1))))
kono
parents:
diff changeset
1232 {
kono
parents:
diff changeset
1233 TREE_OPERAND (stmt, 1)
kono
parents:
diff changeset
1234 = fold_convert (type_left, TREE_OPERAND (stmt, 1));
kono
parents:
diff changeset
1235 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
kono
parents:
diff changeset
1236 type_left));
kono
parents:
diff changeset
1237 }
kono
parents:
diff changeset
1238 if (type_right
kono
parents:
diff changeset
1239 && !useless_type_conversion_p (TREE_TYPE (stmt),
kono
parents:
diff changeset
1240 TREE_TYPE (TREE_OPERAND (stmt, 2))))
kono
parents:
diff changeset
1241 {
kono
parents:
diff changeset
1242 TREE_OPERAND (stmt, 2)
kono
parents:
diff changeset
1243 = fold_convert (type_right, TREE_OPERAND (stmt, 2));
kono
parents:
diff changeset
1244 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
kono
parents:
diff changeset
1245 type_right));
kono
parents:
diff changeset
1246 }
kono
parents:
diff changeset
1247 }
kono
parents:
diff changeset
1248 break;
kono
parents:
diff changeset
1249
kono
parents:
diff changeset
1250 case BIND_EXPR:
kono
parents:
diff changeset
1251 if (__builtin_expect (wtd->omp_ctx != NULL, 0))
kono
parents:
diff changeset
1252 {
kono
parents:
diff changeset
1253 tree decl;
kono
parents:
diff changeset
1254 for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
kono
parents:
diff changeset
1255 if (VAR_P (decl)
kono
parents:
diff changeset
1256 && !DECL_EXTERNAL (decl)
kono
parents:
diff changeset
1257 && omp_var_to_track (decl))
kono
parents:
diff changeset
1258 {
kono
parents:
diff changeset
1259 splay_tree_node n
kono
parents:
diff changeset
1260 = splay_tree_lookup (wtd->omp_ctx->variables,
kono
parents:
diff changeset
1261 (splay_tree_key) decl);
kono
parents:
diff changeset
1262 if (n == NULL)
kono
parents:
diff changeset
1263 splay_tree_insert (wtd->omp_ctx->variables,
kono
parents:
diff changeset
1264 (splay_tree_key) decl,
kono
parents:
diff changeset
1265 TREE_STATIC (decl)
kono
parents:
diff changeset
1266 ? OMP_CLAUSE_DEFAULT_SHARED
kono
parents:
diff changeset
1267 : OMP_CLAUSE_DEFAULT_PRIVATE);
kono
parents:
diff changeset
1268 }
kono
parents:
diff changeset
1269 }
kono
parents:
diff changeset
1270 if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
kono
parents:
diff changeset
1271 {
kono
parents:
diff changeset
1272 /* The point here is to not sanitize static initializers. */
kono
parents:
diff changeset
1273 bool no_sanitize_p = wtd->no_sanitize_p;
kono
parents:
diff changeset
1274 wtd->no_sanitize_p = true;
kono
parents:
diff changeset
1275 for (tree decl = BIND_EXPR_VARS (stmt);
kono
parents:
diff changeset
1276 decl;
kono
parents:
diff changeset
1277 decl = DECL_CHAIN (decl))
kono
parents:
diff changeset
1278 if (VAR_P (decl)
kono
parents:
diff changeset
1279 && TREE_STATIC (decl)
kono
parents:
diff changeset
1280 && DECL_INITIAL (decl))
kono
parents:
diff changeset
1281 cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL);
kono
parents:
diff changeset
1282 wtd->no_sanitize_p = no_sanitize_p;
kono
parents:
diff changeset
1283 }
kono
parents:
diff changeset
1284 wtd->bind_expr_stack.safe_push (stmt);
kono
parents:
diff changeset
1285 cp_walk_tree (&BIND_EXPR_BODY (stmt),
kono
parents:
diff changeset
1286 cp_genericize_r, data, NULL);
kono
parents:
diff changeset
1287 wtd->bind_expr_stack.pop ();
kono
parents:
diff changeset
1288 break;
kono
parents:
diff changeset
1289
kono
parents:
diff changeset
1290 case USING_STMT:
kono
parents:
diff changeset
1291 {
kono
parents:
diff changeset
1292 tree block = NULL_TREE;
kono
parents:
diff changeset
1293
kono
parents:
diff changeset
1294 /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
kono
parents:
diff changeset
1295 BLOCK, and append an IMPORTED_DECL to its
kono
parents:
diff changeset
1296 BLOCK_VARS chained list. */
kono
parents:
diff changeset
1297 if (wtd->bind_expr_stack.exists ())
kono
parents:
diff changeset
1298 {
kono
parents:
diff changeset
1299 int i;
kono
parents:
diff changeset
1300 for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
kono
parents:
diff changeset
1301 if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
kono
parents:
diff changeset
1302 break;
kono
parents:
diff changeset
1303 }
kono
parents:
diff changeset
1304 if (block)
kono
parents:
diff changeset
1305 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1306 tree decl = TREE_OPERAND (stmt, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1307 gcc_assert (decl);
111
kono
parents:
diff changeset
1308
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1309 if (undeduced_auto_decl (decl))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1310 /* Omit from the GENERIC, the back-end can't handle it. */;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1311 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1312 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1313 tree using_directive = make_node (IMPORTED_DECL);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1314 TREE_TYPE (using_directive) = void_type_node;
111
kono
parents:
diff changeset
1315
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1316 IMPORTED_DECL_ASSOCIATED_DECL (using_directive) = decl;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1317 DECL_CHAIN (using_directive) = BLOCK_VARS (block);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1318 BLOCK_VARS (block) = using_directive;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1319 }
111
kono
parents:
diff changeset
1320 }
kono
parents:
diff changeset
1321 /* The USING_STMT won't appear in GENERIC. */
kono
parents:
diff changeset
1322 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
kono
parents:
diff changeset
1323 *walk_subtrees = 0;
kono
parents:
diff changeset
1324 }
kono
parents:
diff changeset
1325 break;
kono
parents:
diff changeset
1326
kono
parents:
diff changeset
1327 case DECL_EXPR:
kono
parents:
diff changeset
1328 if (TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
kono
parents:
diff changeset
1329 {
kono
parents:
diff changeset
1330 /* Using decls inside DECL_EXPRs are just dropped on the floor. */
kono
parents:
diff changeset
1331 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
kono
parents:
diff changeset
1332 *walk_subtrees = 0;
kono
parents:
diff changeset
1333 }
kono
parents:
diff changeset
1334 else
kono
parents:
diff changeset
1335 {
kono
parents:
diff changeset
1336 tree d = DECL_EXPR_DECL (stmt);
kono
parents:
diff changeset
1337 if (VAR_P (d))
kono
parents:
diff changeset
1338 gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P (d));
kono
parents:
diff changeset
1339 }
kono
parents:
diff changeset
1340 break;
kono
parents:
diff changeset
1341
kono
parents:
diff changeset
1342 case OMP_PARALLEL:
kono
parents:
diff changeset
1343 case OMP_TASK:
kono
parents:
diff changeset
1344 case OMP_TASKLOOP:
kono
parents:
diff changeset
1345 {
kono
parents:
diff changeset
1346 struct cp_genericize_omp_taskreg omp_ctx;
kono
parents:
diff changeset
1347 tree c, decl;
kono
parents:
diff changeset
1348 splay_tree_node n;
kono
parents:
diff changeset
1349
kono
parents:
diff changeset
1350 *walk_subtrees = 0;
kono
parents:
diff changeset
1351 cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
kono
parents:
diff changeset
1352 omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
kono
parents:
diff changeset
1353 omp_ctx.default_shared = omp_ctx.is_parallel;
kono
parents:
diff changeset
1354 omp_ctx.outer = wtd->omp_ctx;
kono
parents:
diff changeset
1355 omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
kono
parents:
diff changeset
1356 wtd->omp_ctx = &omp_ctx;
kono
parents:
diff changeset
1357 for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
kono
parents:
diff changeset
1358 switch (OMP_CLAUSE_CODE (c))
kono
parents:
diff changeset
1359 {
kono
parents:
diff changeset
1360 case OMP_CLAUSE_SHARED:
kono
parents:
diff changeset
1361 case OMP_CLAUSE_PRIVATE:
kono
parents:
diff changeset
1362 case OMP_CLAUSE_FIRSTPRIVATE:
kono
parents:
diff changeset
1363 case OMP_CLAUSE_LASTPRIVATE:
kono
parents:
diff changeset
1364 decl = OMP_CLAUSE_DECL (c);
kono
parents:
diff changeset
1365 if (decl == error_mark_node || !omp_var_to_track (decl))
kono
parents:
diff changeset
1366 break;
kono
parents:
diff changeset
1367 n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
kono
parents:
diff changeset
1368 if (n != NULL)
kono
parents:
diff changeset
1369 break;
kono
parents:
diff changeset
1370 splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
kono
parents:
diff changeset
1371 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
kono
parents:
diff changeset
1372 ? OMP_CLAUSE_DEFAULT_SHARED
kono
parents:
diff changeset
1373 : OMP_CLAUSE_DEFAULT_PRIVATE);
kono
parents:
diff changeset
1374 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE && omp_ctx.outer)
kono
parents:
diff changeset
1375 omp_cxx_notice_variable (omp_ctx.outer, decl);
kono
parents:
diff changeset
1376 break;
kono
parents:
diff changeset
1377 case OMP_CLAUSE_DEFAULT:
kono
parents:
diff changeset
1378 if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
kono
parents:
diff changeset
1379 omp_ctx.default_shared = true;
kono
parents:
diff changeset
1380 default:
kono
parents:
diff changeset
1381 break;
kono
parents:
diff changeset
1382 }
kono
parents:
diff changeset
1383 if (TREE_CODE (stmt) == OMP_TASKLOOP)
kono
parents:
diff changeset
1384 genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
kono
parents:
diff changeset
1385 else
kono
parents:
diff changeset
1386 cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
kono
parents:
diff changeset
1387 wtd->omp_ctx = omp_ctx.outer;
kono
parents:
diff changeset
1388 splay_tree_delete (omp_ctx.variables);
kono
parents:
diff changeset
1389 }
kono
parents:
diff changeset
1390 break;
kono
parents:
diff changeset
1391
kono
parents:
diff changeset
1392 case TRY_BLOCK:
kono
parents:
diff changeset
1393 {
kono
parents:
diff changeset
1394 *walk_subtrees = 0;
kono
parents:
diff changeset
1395 tree try_block = wtd->try_block;
kono
parents:
diff changeset
1396 wtd->try_block = stmt;
kono
parents:
diff changeset
1397 cp_walk_tree (&TRY_STMTS (stmt), cp_genericize_r, data, NULL);
kono
parents:
diff changeset
1398 wtd->try_block = try_block;
kono
parents:
diff changeset
1399 cp_walk_tree (&TRY_HANDLERS (stmt), cp_genericize_r, data, NULL);
kono
parents:
diff changeset
1400 }
kono
parents:
diff changeset
1401 break;
kono
parents:
diff changeset
1402
kono
parents:
diff changeset
1403 case MUST_NOT_THROW_EXPR:
kono
parents:
diff changeset
1404 /* MUST_NOT_THROW_COND might be something else with TM. */
kono
parents:
diff changeset
1405 if (MUST_NOT_THROW_COND (stmt) == NULL_TREE)
kono
parents:
diff changeset
1406 {
kono
parents:
diff changeset
1407 *walk_subtrees = 0;
kono
parents:
diff changeset
1408 tree try_block = wtd->try_block;
kono
parents:
diff changeset
1409 wtd->try_block = stmt;
kono
parents:
diff changeset
1410 cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
kono
parents:
diff changeset
1411 wtd->try_block = try_block;
kono
parents:
diff changeset
1412 }
kono
parents:
diff changeset
1413 break;
kono
parents:
diff changeset
1414
kono
parents:
diff changeset
1415 case THROW_EXPR:
kono
parents:
diff changeset
1416 {
kono
parents:
diff changeset
1417 location_t loc = location_of (stmt);
kono
parents:
diff changeset
1418 if (TREE_NO_WARNING (stmt))
kono
parents:
diff changeset
1419 /* Never mind. */;
kono
parents:
diff changeset
1420 else if (wtd->try_block)
kono
parents:
diff changeset
1421 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1422 if (TREE_CODE (wtd->try_block) == MUST_NOT_THROW_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1423 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1424 auto_diagnostic_group d;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1425 if (warning_at (loc, OPT_Wterminate,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1426 "throw will always call terminate()")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1427 && cxx_dialect >= cxx11
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1428 && DECL_DESTRUCTOR_P (current_function_decl))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1429 inform (loc, "in C++11 destructors default to noexcept");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1430 }
111
kono
parents:
diff changeset
1431 }
kono
parents:
diff changeset
1432 else
kono
parents:
diff changeset
1433 {
kono
parents:
diff changeset
1434 if (warn_cxx11_compat && cxx_dialect < cxx11
kono
parents:
diff changeset
1435 && DECL_DESTRUCTOR_P (current_function_decl)
kono
parents:
diff changeset
1436 && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))
kono
parents:
diff changeset
1437 == NULL_TREE)
kono
parents:
diff changeset
1438 && (get_defaulted_eh_spec (current_function_decl)
kono
parents:
diff changeset
1439 == empty_except_spec))
kono
parents:
diff changeset
1440 warning_at (loc, OPT_Wc__11_compat,
kono
parents:
diff changeset
1441 "in C++11 this throw will terminate because "
kono
parents:
diff changeset
1442 "destructors default to noexcept");
kono
parents:
diff changeset
1443 }
kono
parents:
diff changeset
1444 }
kono
parents:
diff changeset
1445 break;
kono
parents:
diff changeset
1446
kono
parents:
diff changeset
1447 case CONVERT_EXPR:
kono
parents:
diff changeset
1448 gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
kono
parents:
diff changeset
1449 break;
kono
parents:
diff changeset
1450
kono
parents:
diff changeset
1451 case FOR_STMT:
kono
parents:
diff changeset
1452 genericize_for_stmt (stmt_p, walk_subtrees, data);
kono
parents:
diff changeset
1453 break;
kono
parents:
diff changeset
1454
kono
parents:
diff changeset
1455 case WHILE_STMT:
kono
parents:
diff changeset
1456 genericize_while_stmt (stmt_p, walk_subtrees, data);
kono
parents:
diff changeset
1457 break;
kono
parents:
diff changeset
1458
kono
parents:
diff changeset
1459 case DO_STMT:
kono
parents:
diff changeset
1460 genericize_do_stmt (stmt_p, walk_subtrees, data);
kono
parents:
diff changeset
1461 break;
kono
parents:
diff changeset
1462
kono
parents:
diff changeset
1463 case SWITCH_STMT:
kono
parents:
diff changeset
1464 genericize_switch_stmt (stmt_p, walk_subtrees, data);
kono
parents:
diff changeset
1465 break;
kono
parents:
diff changeset
1466
kono
parents:
diff changeset
1467 case CONTINUE_STMT:
kono
parents:
diff changeset
1468 genericize_continue_stmt (stmt_p);
kono
parents:
diff changeset
1469 break;
kono
parents:
diff changeset
1470
kono
parents:
diff changeset
1471 case BREAK_STMT:
kono
parents:
diff changeset
1472 genericize_break_stmt (stmt_p);
kono
parents:
diff changeset
1473 break;
kono
parents:
diff changeset
1474
kono
parents:
diff changeset
1475 case OMP_FOR:
kono
parents:
diff changeset
1476 case OMP_SIMD:
kono
parents:
diff changeset
1477 case OMP_DISTRIBUTE:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1478 case OACC_LOOP:
111
kono
parents:
diff changeset
1479 genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
kono
parents:
diff changeset
1480 break;
kono
parents:
diff changeset
1481
kono
parents:
diff changeset
1482 case PTRMEM_CST:
kono
parents:
diff changeset
1483 /* By the time we get here we're handing off to the back end, so we don't
kono
parents:
diff changeset
1484 need or want to preserve PTRMEM_CST anymore. */
kono
parents:
diff changeset
1485 *stmt_p = cplus_expand_constant (stmt);
kono
parents:
diff changeset
1486 *walk_subtrees = 0;
kono
parents:
diff changeset
1487 break;
kono
parents:
diff changeset
1488
kono
parents:
diff changeset
1489 case MEM_REF:
kono
parents:
diff changeset
1490 /* For MEM_REF, make sure not to sanitize the second operand even
kono
parents:
diff changeset
1491 if it has reference type. It is just an offset with a type
kono
parents:
diff changeset
1492 holding other information. There is no other processing we
kono
parents:
diff changeset
1493 need to do for INTEGER_CSTs, so just ignore the second argument
kono
parents:
diff changeset
1494 unconditionally. */
kono
parents:
diff changeset
1495 cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
kono
parents:
diff changeset
1496 *walk_subtrees = 0;
kono
parents:
diff changeset
1497 break;
kono
parents:
diff changeset
1498
kono
parents:
diff changeset
1499 case NOP_EXPR:
kono
parents:
diff changeset
1500 if (!wtd->no_sanitize_p
kono
parents:
diff changeset
1501 && sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1502 && TYPE_REF_P (TREE_TYPE (stmt)))
111
kono
parents:
diff changeset
1503 ubsan_maybe_instrument_reference (stmt_p);
kono
parents:
diff changeset
1504 break;
kono
parents:
diff changeset
1505
kono
parents:
diff changeset
1506 case CALL_EXPR:
kono
parents:
diff changeset
1507 if (!wtd->no_sanitize_p
kono
parents:
diff changeset
1508 && sanitize_flags_p ((SANITIZE_NULL
kono
parents:
diff changeset
1509 | SANITIZE_ALIGNMENT | SANITIZE_VPTR)))
kono
parents:
diff changeset
1510 {
kono
parents:
diff changeset
1511 tree fn = CALL_EXPR_FN (stmt);
kono
parents:
diff changeset
1512 if (fn != NULL_TREE
kono
parents:
diff changeset
1513 && !error_operand_p (fn)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1514 && INDIRECT_TYPE_P (TREE_TYPE (fn))
111
kono
parents:
diff changeset
1515 && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE)
kono
parents:
diff changeset
1516 {
kono
parents:
diff changeset
1517 bool is_ctor
kono
parents:
diff changeset
1518 = TREE_CODE (fn) == ADDR_EXPR
kono
parents:
diff changeset
1519 && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
kono
parents:
diff changeset
1520 && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0));
kono
parents:
diff changeset
1521 if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT))
kono
parents:
diff changeset
1522 ubsan_maybe_instrument_member_call (stmt, is_ctor);
kono
parents:
diff changeset
1523 if (sanitize_flags_p (SANITIZE_VPTR) && !is_ctor)
kono
parents:
diff changeset
1524 cp_ubsan_maybe_instrument_member_call (stmt);
kono
parents:
diff changeset
1525 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1526 else if (fn == NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1527 && CALL_EXPR_IFN (stmt) == IFN_UBSAN_NULL
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1528 && TREE_CODE (CALL_EXPR_ARG (stmt, 0)) == INTEGER_CST
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1529 && TYPE_REF_P (TREE_TYPE (CALL_EXPR_ARG (stmt, 0))))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1530 *walk_subtrees = 0;
111
kono
parents:
diff changeset
1531 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1532 /* Fall through. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1533 case AGGR_INIT_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1534 /* For calls to a multi-versioned function, overload resolution
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1535 returns the function with the highest target priority, that is,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1536 the version that will checked for dispatching first. If this
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1537 version is inlinable, a direct call to this version can be made
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1538 otherwise the call should go through the dispatcher. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1539 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1540 tree fn = cp_get_callee_fndecl_nofold (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1541 if (fn && DECL_FUNCTION_VERSIONED (fn)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1542 && (current_function_decl == NULL
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1543 || !targetm.target_option.can_inline_p (current_function_decl,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1544 fn)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1545 if (tree dis = get_function_version_dispatcher (fn))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1546 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1547 mark_versions_used (dis);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1548 dis = build_address (dis);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1549 if (TREE_CODE (stmt) == CALL_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1550 CALL_EXPR_FN (stmt) = dis;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1551 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1552 AGGR_INIT_EXPR_FN (stmt) = dis;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1553 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1554 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1555 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1556
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1557 case TARGET_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1558 if (TARGET_EXPR_INITIAL (stmt)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1559 && TREE_CODE (TARGET_EXPR_INITIAL (stmt)) == CONSTRUCTOR
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1560 && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (TARGET_EXPR_INITIAL (stmt)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1561 TARGET_EXPR_NO_ELIDE (stmt) = 1;
111
kono
parents:
diff changeset
1562 break;
kono
parents:
diff changeset
1563
kono
parents:
diff changeset
1564 default:
kono
parents:
diff changeset
1565 if (IS_TYPE_OR_DECL_P (stmt))
kono
parents:
diff changeset
1566 *walk_subtrees = 0;
kono
parents:
diff changeset
1567 break;
kono
parents:
diff changeset
1568 }
kono
parents:
diff changeset
1569
kono
parents:
diff changeset
1570 p_set->add (*stmt_p);
kono
parents:
diff changeset
1571
kono
parents:
diff changeset
1572 return NULL;
kono
parents:
diff changeset
1573 }
kono
parents:
diff changeset
1574
kono
parents:
diff changeset
1575 /* Lower C++ front end trees to GENERIC in T_P. */
kono
parents:
diff changeset
1576
kono
parents:
diff changeset
1577 static void
kono
parents:
diff changeset
1578 cp_genericize_tree (tree* t_p, bool handle_invisiref_parm_p)
kono
parents:
diff changeset
1579 {
kono
parents:
diff changeset
1580 struct cp_genericize_data wtd;
kono
parents:
diff changeset
1581
kono
parents:
diff changeset
1582 wtd.p_set = new hash_set<tree>;
kono
parents:
diff changeset
1583 wtd.bind_expr_stack.create (0);
kono
parents:
diff changeset
1584 wtd.omp_ctx = NULL;
kono
parents:
diff changeset
1585 wtd.try_block = NULL_TREE;
kono
parents:
diff changeset
1586 wtd.no_sanitize_p = false;
kono
parents:
diff changeset
1587 wtd.handle_invisiref_parm_p = handle_invisiref_parm_p;
kono
parents:
diff changeset
1588 cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
kono
parents:
diff changeset
1589 delete wtd.p_set;
kono
parents:
diff changeset
1590 wtd.bind_expr_stack.release ();
kono
parents:
diff changeset
1591 if (sanitize_flags_p (SANITIZE_VPTR))
kono
parents:
diff changeset
1592 cp_ubsan_instrument_member_accesses (t_p);
kono
parents:
diff changeset
1593 }
kono
parents:
diff changeset
1594
kono
parents:
diff changeset
1595 /* If a function that should end with a return in non-void
kono
parents:
diff changeset
1596 function doesn't obviously end with return, add ubsan
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1597 instrumentation code to verify it at runtime. If -fsanitize=return
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1598 is not enabled, instrument __builtin_unreachable. */
111
kono
parents:
diff changeset
1599
kono
parents:
diff changeset
1600 static void
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1601 cp_maybe_instrument_return (tree fndecl)
111
kono
parents:
diff changeset
1602 {
kono
parents:
diff changeset
1603 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
kono
parents:
diff changeset
1604 || DECL_CONSTRUCTOR_P (fndecl)
kono
parents:
diff changeset
1605 || DECL_DESTRUCTOR_P (fndecl)
kono
parents:
diff changeset
1606 || !targetm.warn_func_return (fndecl))
kono
parents:
diff changeset
1607 return;
kono
parents:
diff changeset
1608
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1609 if (!sanitize_flags_p (SANITIZE_RETURN, fndecl)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1610 /* Don't add __builtin_unreachable () if not optimizing, it will not
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1611 improve any optimizations in that case, just break UB code.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1612 Don't add it if -fsanitize=unreachable -fno-sanitize=return either,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1613 UBSan covers this with ubsan_instrument_return above where sufficient
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1614 information is provided, while the __builtin_unreachable () below
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1615 if return sanitization is disabled will just result in hard to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1616 understand runtime error without location. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1617 && (!optimize
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1618 || sanitize_flags_p (SANITIZE_UNREACHABLE, fndecl)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1619 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1620
111
kono
parents:
diff changeset
1621 tree t = DECL_SAVED_TREE (fndecl);
kono
parents:
diff changeset
1622 while (t)
kono
parents:
diff changeset
1623 {
kono
parents:
diff changeset
1624 switch (TREE_CODE (t))
kono
parents:
diff changeset
1625 {
kono
parents:
diff changeset
1626 case BIND_EXPR:
kono
parents:
diff changeset
1627 t = BIND_EXPR_BODY (t);
kono
parents:
diff changeset
1628 continue;
kono
parents:
diff changeset
1629 case TRY_FINALLY_EXPR:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1630 case CLEANUP_POINT_EXPR:
111
kono
parents:
diff changeset
1631 t = TREE_OPERAND (t, 0);
kono
parents:
diff changeset
1632 continue;
kono
parents:
diff changeset
1633 case STATEMENT_LIST:
kono
parents:
diff changeset
1634 {
kono
parents:
diff changeset
1635 tree_stmt_iterator i = tsi_last (t);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1636 while (!tsi_end_p (i))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1637 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1638 tree p = tsi_stmt (i);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1639 if (TREE_CODE (p) != DEBUG_BEGIN_STMT)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1640 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1641 tsi_prev (&i);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1642 }
111
kono
parents:
diff changeset
1643 if (!tsi_end_p (i))
kono
parents:
diff changeset
1644 {
kono
parents:
diff changeset
1645 t = tsi_stmt (i);
kono
parents:
diff changeset
1646 continue;
kono
parents:
diff changeset
1647 }
kono
parents:
diff changeset
1648 }
kono
parents:
diff changeset
1649 break;
kono
parents:
diff changeset
1650 case RETURN_EXPR:
kono
parents:
diff changeset
1651 return;
kono
parents:
diff changeset
1652 default:
kono
parents:
diff changeset
1653 break;
kono
parents:
diff changeset
1654 }
kono
parents:
diff changeset
1655 break;
kono
parents:
diff changeset
1656 }
kono
parents:
diff changeset
1657 if (t == NULL_TREE)
kono
parents:
diff changeset
1658 return;
kono
parents:
diff changeset
1659 tree *p = &DECL_SAVED_TREE (fndecl);
kono
parents:
diff changeset
1660 if (TREE_CODE (*p) == BIND_EXPR)
kono
parents:
diff changeset
1661 p = &BIND_EXPR_BODY (*p);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1662
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1663 location_t loc = DECL_SOURCE_LOCATION (fndecl);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1664 if (sanitize_flags_p (SANITIZE_RETURN, fndecl))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1665 t = ubsan_instrument_return (loc);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1666 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1667 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1668 tree fndecl = builtin_decl_explicit (BUILT_IN_UNREACHABLE);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1669 t = build_call_expr_loc (BUILTINS_LOCATION, fndecl, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1670 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1671
111
kono
parents:
diff changeset
1672 append_to_statement_list (t, p);
kono
parents:
diff changeset
1673 }
kono
parents:
diff changeset
1674
kono
parents:
diff changeset
1675 void
kono
parents:
diff changeset
1676 cp_genericize (tree fndecl)
kono
parents:
diff changeset
1677 {
kono
parents:
diff changeset
1678 tree t;
kono
parents:
diff changeset
1679
kono
parents:
diff changeset
1680 /* Fix up the types of parms passed by invisible reference. */
kono
parents:
diff changeset
1681 for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
kono
parents:
diff changeset
1682 if (TREE_ADDRESSABLE (TREE_TYPE (t)))
kono
parents:
diff changeset
1683 {
kono
parents:
diff changeset
1684 /* If a function's arguments are copied to create a thunk,
kono
parents:
diff changeset
1685 then DECL_BY_REFERENCE will be set -- but the type of the
kono
parents:
diff changeset
1686 argument will be a pointer type, so we will never get
kono
parents:
diff changeset
1687 here. */
kono
parents:
diff changeset
1688 gcc_assert (!DECL_BY_REFERENCE (t));
kono
parents:
diff changeset
1689 gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
kono
parents:
diff changeset
1690 TREE_TYPE (t) = DECL_ARG_TYPE (t);
kono
parents:
diff changeset
1691 DECL_BY_REFERENCE (t) = 1;
kono
parents:
diff changeset
1692 TREE_ADDRESSABLE (t) = 0;
kono
parents:
diff changeset
1693 relayout_decl (t);
kono
parents:
diff changeset
1694 }
kono
parents:
diff changeset
1695
kono
parents:
diff changeset
1696 /* Do the same for the return value. */
kono
parents:
diff changeset
1697 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
kono
parents:
diff changeset
1698 {
kono
parents:
diff changeset
1699 t = DECL_RESULT (fndecl);
kono
parents:
diff changeset
1700 TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
kono
parents:
diff changeset
1701 DECL_BY_REFERENCE (t) = 1;
kono
parents:
diff changeset
1702 TREE_ADDRESSABLE (t) = 0;
kono
parents:
diff changeset
1703 relayout_decl (t);
kono
parents:
diff changeset
1704 if (DECL_NAME (t))
kono
parents:
diff changeset
1705 {
kono
parents:
diff changeset
1706 /* Adjust DECL_VALUE_EXPR of the original var. */
kono
parents:
diff changeset
1707 tree outer = outer_curly_brace_block (current_function_decl);
kono
parents:
diff changeset
1708 tree var;
kono
parents:
diff changeset
1709
kono
parents:
diff changeset
1710 if (outer)
kono
parents:
diff changeset
1711 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
kono
parents:
diff changeset
1712 if (VAR_P (var)
kono
parents:
diff changeset
1713 && DECL_NAME (t) == DECL_NAME (var)
kono
parents:
diff changeset
1714 && DECL_HAS_VALUE_EXPR_P (var)
kono
parents:
diff changeset
1715 && DECL_VALUE_EXPR (var) == t)
kono
parents:
diff changeset
1716 {
kono
parents:
diff changeset
1717 tree val = convert_from_reference (t);
kono
parents:
diff changeset
1718 SET_DECL_VALUE_EXPR (var, val);
kono
parents:
diff changeset
1719 break;
kono
parents:
diff changeset
1720 }
kono
parents:
diff changeset
1721 }
kono
parents:
diff changeset
1722 }
kono
parents:
diff changeset
1723
kono
parents:
diff changeset
1724 /* If we're a clone, the body is already GIMPLE. */
kono
parents:
diff changeset
1725 if (DECL_CLONED_FUNCTION_P (fndecl))
kono
parents:
diff changeset
1726 return;
kono
parents:
diff changeset
1727
kono
parents:
diff changeset
1728 /* Allow cp_genericize calls to be nested. */
kono
parents:
diff changeset
1729 tree save_bc_label[2];
kono
parents:
diff changeset
1730 save_bc_label[bc_break] = bc_label[bc_break];
kono
parents:
diff changeset
1731 save_bc_label[bc_continue] = bc_label[bc_continue];
kono
parents:
diff changeset
1732 bc_label[bc_break] = NULL_TREE;
kono
parents:
diff changeset
1733 bc_label[bc_continue] = NULL_TREE;
kono
parents:
diff changeset
1734
kono
parents:
diff changeset
1735 /* We do want to see every occurrence of the parms, so we can't just use
kono
parents:
diff changeset
1736 walk_tree's hash functionality. */
kono
parents:
diff changeset
1737 cp_genericize_tree (&DECL_SAVED_TREE (fndecl), true);
kono
parents:
diff changeset
1738
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1739 cp_maybe_instrument_return (fndecl);
111
kono
parents:
diff changeset
1740
kono
parents:
diff changeset
1741 /* Do everything else. */
kono
parents:
diff changeset
1742 c_genericize (fndecl);
kono
parents:
diff changeset
1743
kono
parents:
diff changeset
1744 gcc_assert (bc_label[bc_break] == NULL);
kono
parents:
diff changeset
1745 gcc_assert (bc_label[bc_continue] == NULL);
kono
parents:
diff changeset
1746 bc_label[bc_break] = save_bc_label[bc_break];
kono
parents:
diff changeset
1747 bc_label[bc_continue] = save_bc_label[bc_continue];
kono
parents:
diff changeset
1748 }
kono
parents:
diff changeset
1749
kono
parents:
diff changeset
1750 /* Build code to apply FN to each member of ARG1 and ARG2. FN may be
kono
parents:
diff changeset
1751 NULL if there is in fact nothing to do. ARG2 may be null if FN
kono
parents:
diff changeset
1752 actually only takes one argument. */
kono
parents:
diff changeset
1753
kono
parents:
diff changeset
1754 static tree
kono
parents:
diff changeset
1755 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
kono
parents:
diff changeset
1756 {
kono
parents:
diff changeset
1757 tree defparm, parm, t;
kono
parents:
diff changeset
1758 int i = 0;
kono
parents:
diff changeset
1759 int nargs;
kono
parents:
diff changeset
1760 tree *argarray;
kono
parents:
diff changeset
1761
kono
parents:
diff changeset
1762 if (fn == NULL)
kono
parents:
diff changeset
1763 return NULL;
kono
parents:
diff changeset
1764
kono
parents:
diff changeset
1765 nargs = list_length (DECL_ARGUMENTS (fn));
kono
parents:
diff changeset
1766 argarray = XALLOCAVEC (tree, nargs);
kono
parents:
diff changeset
1767
kono
parents:
diff changeset
1768 defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
kono
parents:
diff changeset
1769 if (arg2)
kono
parents:
diff changeset
1770 defparm = TREE_CHAIN (defparm);
kono
parents:
diff changeset
1771
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1772 bool is_method = TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE;
111
kono
parents:
diff changeset
1773 if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
kono
parents:
diff changeset
1774 {
kono
parents:
diff changeset
1775 tree inner_type = TREE_TYPE (arg1);
kono
parents:
diff changeset
1776 tree start1, end1, p1;
kono
parents:
diff changeset
1777 tree start2 = NULL, p2 = NULL;
kono
parents:
diff changeset
1778 tree ret = NULL, lab;
kono
parents:
diff changeset
1779
kono
parents:
diff changeset
1780 start1 = arg1;
kono
parents:
diff changeset
1781 start2 = arg2;
kono
parents:
diff changeset
1782 do
kono
parents:
diff changeset
1783 {
kono
parents:
diff changeset
1784 inner_type = TREE_TYPE (inner_type);
kono
parents:
diff changeset
1785 start1 = build4 (ARRAY_REF, inner_type, start1,
kono
parents:
diff changeset
1786 size_zero_node, NULL, NULL);
kono
parents:
diff changeset
1787 if (arg2)
kono
parents:
diff changeset
1788 start2 = build4 (ARRAY_REF, inner_type, start2,
kono
parents:
diff changeset
1789 size_zero_node, NULL, NULL);
kono
parents:
diff changeset
1790 }
kono
parents:
diff changeset
1791 while (TREE_CODE (inner_type) == ARRAY_TYPE);
kono
parents:
diff changeset
1792 start1 = build_fold_addr_expr_loc (input_location, start1);
kono
parents:
diff changeset
1793 if (arg2)
kono
parents:
diff changeset
1794 start2 = build_fold_addr_expr_loc (input_location, start2);
kono
parents:
diff changeset
1795
kono
parents:
diff changeset
1796 end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
kono
parents:
diff changeset
1797 end1 = fold_build_pointer_plus (start1, end1);
kono
parents:
diff changeset
1798
kono
parents:
diff changeset
1799 p1 = create_tmp_var (TREE_TYPE (start1));
kono
parents:
diff changeset
1800 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
kono
parents:
diff changeset
1801 append_to_statement_list (t, &ret);
kono
parents:
diff changeset
1802
kono
parents:
diff changeset
1803 if (arg2)
kono
parents:
diff changeset
1804 {
kono
parents:
diff changeset
1805 p2 = create_tmp_var (TREE_TYPE (start2));
kono
parents:
diff changeset
1806 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
kono
parents:
diff changeset
1807 append_to_statement_list (t, &ret);
kono
parents:
diff changeset
1808 }
kono
parents:
diff changeset
1809
kono
parents:
diff changeset
1810 lab = create_artificial_label (input_location);
kono
parents:
diff changeset
1811 t = build1 (LABEL_EXPR, void_type_node, lab);
kono
parents:
diff changeset
1812 append_to_statement_list (t, &ret);
kono
parents:
diff changeset
1813
kono
parents:
diff changeset
1814 argarray[i++] = p1;
kono
parents:
diff changeset
1815 if (arg2)
kono
parents:
diff changeset
1816 argarray[i++] = p2;
kono
parents:
diff changeset
1817 /* Handle default arguments. */
kono
parents:
diff changeset
1818 for (parm = defparm; parm && parm != void_list_node;
kono
parents:
diff changeset
1819 parm = TREE_CHAIN (parm), i++)
kono
parents:
diff changeset
1820 argarray[i] = convert_default_arg (TREE_VALUE (parm),
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1821 TREE_PURPOSE (parm), fn,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1822 i - is_method, tf_warning_or_error);
111
kono
parents:
diff changeset
1823 t = build_call_a (fn, i, argarray);
kono
parents:
diff changeset
1824 t = fold_convert (void_type_node, t);
kono
parents:
diff changeset
1825 t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
kono
parents:
diff changeset
1826 append_to_statement_list (t, &ret);
kono
parents:
diff changeset
1827
kono
parents:
diff changeset
1828 t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type));
kono
parents:
diff changeset
1829 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
kono
parents:
diff changeset
1830 append_to_statement_list (t, &ret);
kono
parents:
diff changeset
1831
kono
parents:
diff changeset
1832 if (arg2)
kono
parents:
diff changeset
1833 {
kono
parents:
diff changeset
1834 t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type));
kono
parents:
diff changeset
1835 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
kono
parents:
diff changeset
1836 append_to_statement_list (t, &ret);
kono
parents:
diff changeset
1837 }
kono
parents:
diff changeset
1838
kono
parents:
diff changeset
1839 t = build2 (NE_EXPR, boolean_type_node, p1, end1);
kono
parents:
diff changeset
1840 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
kono
parents:
diff changeset
1841 append_to_statement_list (t, &ret);
kono
parents:
diff changeset
1842
kono
parents:
diff changeset
1843 return ret;
kono
parents:
diff changeset
1844 }
kono
parents:
diff changeset
1845 else
kono
parents:
diff changeset
1846 {
kono
parents:
diff changeset
1847 argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
kono
parents:
diff changeset
1848 if (arg2)
kono
parents:
diff changeset
1849 argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
kono
parents:
diff changeset
1850 /* Handle default arguments. */
kono
parents:
diff changeset
1851 for (parm = defparm; parm && parm != void_list_node;
kono
parents:
diff changeset
1852 parm = TREE_CHAIN (parm), i++)
kono
parents:
diff changeset
1853 argarray[i] = convert_default_arg (TREE_VALUE (parm),
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1854 TREE_PURPOSE (parm), fn,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1855 i - is_method, tf_warning_or_error);
111
kono
parents:
diff changeset
1856 t = build_call_a (fn, i, argarray);
kono
parents:
diff changeset
1857 t = fold_convert (void_type_node, t);
kono
parents:
diff changeset
1858 return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
kono
parents:
diff changeset
1859 }
kono
parents:
diff changeset
1860 }
kono
parents:
diff changeset
1861
kono
parents:
diff changeset
1862 /* Return code to initialize DECL with its default constructor, or
kono
parents:
diff changeset
1863 NULL if there's nothing to do. */
kono
parents:
diff changeset
1864
kono
parents:
diff changeset
1865 tree
kono
parents:
diff changeset
1866 cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/)
kono
parents:
diff changeset
1867 {
kono
parents:
diff changeset
1868 tree info = CP_OMP_CLAUSE_INFO (clause);
kono
parents:
diff changeset
1869 tree ret = NULL;
kono
parents:
diff changeset
1870
kono
parents:
diff changeset
1871 if (info)
kono
parents:
diff changeset
1872 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
kono
parents:
diff changeset
1873
kono
parents:
diff changeset
1874 return ret;
kono
parents:
diff changeset
1875 }
kono
parents:
diff changeset
1876
kono
parents:
diff changeset
1877 /* Return code to initialize DST with a copy constructor from SRC. */
kono
parents:
diff changeset
1878
kono
parents:
diff changeset
1879 tree
kono
parents:
diff changeset
1880 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
kono
parents:
diff changeset
1881 {
kono
parents:
diff changeset
1882 tree info = CP_OMP_CLAUSE_INFO (clause);
kono
parents:
diff changeset
1883 tree ret = NULL;
kono
parents:
diff changeset
1884
kono
parents:
diff changeset
1885 if (info)
kono
parents:
diff changeset
1886 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
kono
parents:
diff changeset
1887 if (ret == NULL)
kono
parents:
diff changeset
1888 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
kono
parents:
diff changeset
1889
kono
parents:
diff changeset
1890 return ret;
kono
parents:
diff changeset
1891 }
kono
parents:
diff changeset
1892
kono
parents:
diff changeset
1893 /* Similarly, except use an assignment operator instead. */
kono
parents:
diff changeset
1894
kono
parents:
diff changeset
1895 tree
kono
parents:
diff changeset
1896 cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
kono
parents:
diff changeset
1897 {
kono
parents:
diff changeset
1898 tree info = CP_OMP_CLAUSE_INFO (clause);
kono
parents:
diff changeset
1899 tree ret = NULL;
kono
parents:
diff changeset
1900
kono
parents:
diff changeset
1901 if (info)
kono
parents:
diff changeset
1902 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
kono
parents:
diff changeset
1903 if (ret == NULL)
kono
parents:
diff changeset
1904 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
kono
parents:
diff changeset
1905
kono
parents:
diff changeset
1906 return ret;
kono
parents:
diff changeset
1907 }
kono
parents:
diff changeset
1908
kono
parents:
diff changeset
1909 /* Return code to destroy DECL. */
kono
parents:
diff changeset
1910
kono
parents:
diff changeset
1911 tree
kono
parents:
diff changeset
1912 cxx_omp_clause_dtor (tree clause, tree decl)
kono
parents:
diff changeset
1913 {
kono
parents:
diff changeset
1914 tree info = CP_OMP_CLAUSE_INFO (clause);
kono
parents:
diff changeset
1915 tree ret = NULL;
kono
parents:
diff changeset
1916
kono
parents:
diff changeset
1917 if (info)
kono
parents:
diff changeset
1918 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
kono
parents:
diff changeset
1919
kono
parents:
diff changeset
1920 return ret;
kono
parents:
diff changeset
1921 }
kono
parents:
diff changeset
1922
kono
parents:
diff changeset
1923 /* True if OpenMP should privatize what this DECL points to rather
kono
parents:
diff changeset
1924 than the DECL itself. */
kono
parents:
diff changeset
1925
kono
parents:
diff changeset
1926 bool
kono
parents:
diff changeset
1927 cxx_omp_privatize_by_reference (const_tree decl)
kono
parents:
diff changeset
1928 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1929 return (TYPE_REF_P (TREE_TYPE (decl))
111
kono
parents:
diff changeset
1930 || is_invisiref_parm (decl));
kono
parents:
diff changeset
1931 }
kono
parents:
diff changeset
1932
kono
parents:
diff changeset
1933 /* Return true if DECL is const qualified var having no mutable member. */
kono
parents:
diff changeset
1934 bool
kono
parents:
diff changeset
1935 cxx_omp_const_qual_no_mutable (tree decl)
kono
parents:
diff changeset
1936 {
kono
parents:
diff changeset
1937 tree type = TREE_TYPE (decl);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1938 if (TYPE_REF_P (type))
111
kono
parents:
diff changeset
1939 {
kono
parents:
diff changeset
1940 if (!is_invisiref_parm (decl))
kono
parents:
diff changeset
1941 return false;
kono
parents:
diff changeset
1942 type = TREE_TYPE (type);
kono
parents:
diff changeset
1943
kono
parents:
diff changeset
1944 if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
kono
parents:
diff changeset
1945 {
kono
parents:
diff changeset
1946 /* NVR doesn't preserve const qualification of the
kono
parents:
diff changeset
1947 variable's type. */
kono
parents:
diff changeset
1948 tree outer = outer_curly_brace_block (current_function_decl);
kono
parents:
diff changeset
1949 tree var;
kono
parents:
diff changeset
1950
kono
parents:
diff changeset
1951 if (outer)
kono
parents:
diff changeset
1952 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
kono
parents:
diff changeset
1953 if (VAR_P (var)
kono
parents:
diff changeset
1954 && DECL_NAME (decl) == DECL_NAME (var)
kono
parents:
diff changeset
1955 && (TYPE_MAIN_VARIANT (type)
kono
parents:
diff changeset
1956 == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
kono
parents:
diff changeset
1957 {
kono
parents:
diff changeset
1958 if (TYPE_READONLY (TREE_TYPE (var)))
kono
parents:
diff changeset
1959 type = TREE_TYPE (var);
kono
parents:
diff changeset
1960 break;
kono
parents:
diff changeset
1961 }
kono
parents:
diff changeset
1962 }
kono
parents:
diff changeset
1963 }
kono
parents:
diff changeset
1964
kono
parents:
diff changeset
1965 if (type == error_mark_node)
kono
parents:
diff changeset
1966 return false;
kono
parents:
diff changeset
1967
kono
parents:
diff changeset
1968 /* Variables with const-qualified type having no mutable member
kono
parents:
diff changeset
1969 are predetermined shared. */
kono
parents:
diff changeset
1970 if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
kono
parents:
diff changeset
1971 return true;
kono
parents:
diff changeset
1972
kono
parents:
diff changeset
1973 return false;
kono
parents:
diff changeset
1974 }
kono
parents:
diff changeset
1975
kono
parents:
diff changeset
1976 /* True if OpenMP sharing attribute of DECL is predetermined. */
kono
parents:
diff changeset
1977
kono
parents:
diff changeset
1978 enum omp_clause_default_kind
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1979 cxx_omp_predetermined_sharing_1 (tree decl)
111
kono
parents:
diff changeset
1980 {
kono
parents:
diff changeset
1981 /* Static data members are predetermined shared. */
kono
parents:
diff changeset
1982 if (TREE_STATIC (decl))
kono
parents:
diff changeset
1983 {
kono
parents:
diff changeset
1984 tree ctx = CP_DECL_CONTEXT (decl);
kono
parents:
diff changeset
1985 if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
kono
parents:
diff changeset
1986 return OMP_CLAUSE_DEFAULT_SHARED;
kono
parents:
diff changeset
1987 }
kono
parents:
diff changeset
1988
kono
parents:
diff changeset
1989 /* Const qualified vars having no mutable member are predetermined
kono
parents:
diff changeset
1990 shared. */
kono
parents:
diff changeset
1991 if (cxx_omp_const_qual_no_mutable (decl))
kono
parents:
diff changeset
1992 return OMP_CLAUSE_DEFAULT_SHARED;
kono
parents:
diff changeset
1993
kono
parents:
diff changeset
1994 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
kono
parents:
diff changeset
1995 }
kono
parents:
diff changeset
1996
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1997 /* Likewise, but also include the artificial vars. We don't want to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1998 disallow the artificial vars being mentioned in explicit clauses,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1999 as we use artificial vars e.g. for loop constructs with random
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2000 access iterators other than pointers, but during gimplification
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2001 we want to treat them as predetermined. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2002
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2003 enum omp_clause_default_kind
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2004 cxx_omp_predetermined_sharing (tree decl)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2005 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2006 enum omp_clause_default_kind ret = cxx_omp_predetermined_sharing_1 (decl);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2007 if (ret != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2008 return ret;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2009
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2010 /* Predetermine artificial variables holding integral values, those
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2011 are usually result of gimplify_one_sizepos or SAVE_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2012 gimplification. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2013 if (VAR_P (decl)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2014 && DECL_ARTIFICIAL (decl)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2015 && INTEGRAL_TYPE_P (TREE_TYPE (decl))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2016 && !(DECL_LANG_SPECIFIC (decl)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2017 && DECL_OMP_PRIVATIZED_MEMBER (decl)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2018 return OMP_CLAUSE_DEFAULT_SHARED;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2019
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2020 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2021 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2022
111
kono
parents:
diff changeset
2023 /* Finalize an implicitly determined clause. */
kono
parents:
diff changeset
2024
kono
parents:
diff changeset
2025 void
kono
parents:
diff changeset
2026 cxx_omp_finish_clause (tree c, gimple_seq *)
kono
parents:
diff changeset
2027 {
kono
parents:
diff changeset
2028 tree decl, inner_type;
kono
parents:
diff changeset
2029 bool make_shared = false;
kono
parents:
diff changeset
2030
kono
parents:
diff changeset
2031 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
kono
parents:
diff changeset
2032 return;
kono
parents:
diff changeset
2033
kono
parents:
diff changeset
2034 decl = OMP_CLAUSE_DECL (c);
kono
parents:
diff changeset
2035 decl = require_complete_type (decl);
kono
parents:
diff changeset
2036 inner_type = TREE_TYPE (decl);
kono
parents:
diff changeset
2037 if (decl == error_mark_node)
kono
parents:
diff changeset
2038 make_shared = true;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2039 else if (TYPE_REF_P (TREE_TYPE (decl)))
111
kono
parents:
diff changeset
2040 inner_type = TREE_TYPE (inner_type);
kono
parents:
diff changeset
2041
kono
parents:
diff changeset
2042 /* We're interested in the base element, not arrays. */
kono
parents:
diff changeset
2043 while (TREE_CODE (inner_type) == ARRAY_TYPE)
kono
parents:
diff changeset
2044 inner_type = TREE_TYPE (inner_type);
kono
parents:
diff changeset
2045
kono
parents:
diff changeset
2046 /* Check for special function availability by building a call to one.
kono
parents:
diff changeset
2047 Save the results, because later we won't be in the right context
kono
parents:
diff changeset
2048 for making these queries. */
kono
parents:
diff changeset
2049 if (!make_shared
kono
parents:
diff changeset
2050 && CLASS_TYPE_P (inner_type)
kono
parents:
diff changeset
2051 && cxx_omp_create_clause_info (c, inner_type, false, true, false, true))
kono
parents:
diff changeset
2052 make_shared = true;
kono
parents:
diff changeset
2053
kono
parents:
diff changeset
2054 if (make_shared)
kono
parents:
diff changeset
2055 {
kono
parents:
diff changeset
2056 OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
kono
parents:
diff changeset
2057 OMP_CLAUSE_SHARED_FIRSTPRIVATE (c) = 0;
kono
parents:
diff changeset
2058 OMP_CLAUSE_SHARED_READONLY (c) = 0;
kono
parents:
diff changeset
2059 }
kono
parents:
diff changeset
2060 }
kono
parents:
diff changeset
2061
kono
parents:
diff changeset
2062 /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
kono
parents:
diff changeset
2063 disregarded in OpenMP construct, because it is going to be
kono
parents:
diff changeset
2064 remapped during OpenMP lowering. SHARED is true if DECL
kono
parents:
diff changeset
2065 is going to be shared, false if it is going to be privatized. */
kono
parents:
diff changeset
2066
kono
parents:
diff changeset
2067 bool
kono
parents:
diff changeset
2068 cxx_omp_disregard_value_expr (tree decl, bool shared)
kono
parents:
diff changeset
2069 {
kono
parents:
diff changeset
2070 return !shared
kono
parents:
diff changeset
2071 && VAR_P (decl)
kono
parents:
diff changeset
2072 && DECL_HAS_VALUE_EXPR_P (decl)
kono
parents:
diff changeset
2073 && DECL_ARTIFICIAL (decl)
kono
parents:
diff changeset
2074 && DECL_LANG_SPECIFIC (decl)
kono
parents:
diff changeset
2075 && DECL_OMP_PRIVATIZED_MEMBER (decl);
kono
parents:
diff changeset
2076 }
kono
parents:
diff changeset
2077
kono
parents:
diff changeset
2078 /* Fold expression X which is used as an rvalue if RVAL is true. */
kono
parents:
diff changeset
2079
kono
parents:
diff changeset
2080 static tree
kono
parents:
diff changeset
2081 cp_fold_maybe_rvalue (tree x, bool rval)
kono
parents:
diff changeset
2082 {
kono
parents:
diff changeset
2083 while (true)
kono
parents:
diff changeset
2084 {
kono
parents:
diff changeset
2085 x = cp_fold (x);
kono
parents:
diff changeset
2086 if (rval && DECL_P (x)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2087 && !TYPE_REF_P (TREE_TYPE (x)))
111
kono
parents:
diff changeset
2088 {
kono
parents:
diff changeset
2089 tree v = decl_constant_value (x);
kono
parents:
diff changeset
2090 if (v != x && v != error_mark_node)
kono
parents:
diff changeset
2091 {
kono
parents:
diff changeset
2092 x = v;
kono
parents:
diff changeset
2093 continue;
kono
parents:
diff changeset
2094 }
kono
parents:
diff changeset
2095 }
kono
parents:
diff changeset
2096 break;
kono
parents:
diff changeset
2097 }
kono
parents:
diff changeset
2098 return x;
kono
parents:
diff changeset
2099 }
kono
parents:
diff changeset
2100
kono
parents:
diff changeset
2101 /* Fold expression X which is used as an rvalue. */
kono
parents:
diff changeset
2102
kono
parents:
diff changeset
2103 static tree
kono
parents:
diff changeset
2104 cp_fold_rvalue (tree x)
kono
parents:
diff changeset
2105 {
kono
parents:
diff changeset
2106 return cp_fold_maybe_rvalue (x, true);
kono
parents:
diff changeset
2107 }
kono
parents:
diff changeset
2108
kono
parents:
diff changeset
2109 /* Perform folding on expression X. */
kono
parents:
diff changeset
2110
kono
parents:
diff changeset
2111 tree
kono
parents:
diff changeset
2112 cp_fully_fold (tree x)
kono
parents:
diff changeset
2113 {
kono
parents:
diff changeset
2114 if (processing_template_decl)
kono
parents:
diff changeset
2115 return x;
kono
parents:
diff changeset
2116 /* FIXME cp_fold ought to be a superset of maybe_constant_value so we don't
kono
parents:
diff changeset
2117 have to call both. */
kono
parents:
diff changeset
2118 if (cxx_dialect >= cxx11)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2119 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2120 x = maybe_constant_value (x);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2121 /* Sometimes we are given a CONSTRUCTOR but the call above wraps it into
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2122 a TARGET_EXPR; undo that here. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2123 if (TREE_CODE (x) == TARGET_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2124 x = TARGET_EXPR_INITIAL (x);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2125 else if (TREE_CODE (x) == VIEW_CONVERT_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2126 && TREE_CODE (TREE_OPERAND (x, 0)) == CONSTRUCTOR
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2127 && TREE_TYPE (TREE_OPERAND (x, 0)) == TREE_TYPE (x))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2128 x = TREE_OPERAND (x, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2129 }
111
kono
parents:
diff changeset
2130 return cp_fold_rvalue (x);
kono
parents:
diff changeset
2131 }
kono
parents:
diff changeset
2132
kono
parents:
diff changeset
2133 /* c-common interface to cp_fold. If IN_INIT, this is in a static initializer
kono
parents:
diff changeset
2134 and certain changes are made to the folding done. Or should be (FIXME). We
kono
parents:
diff changeset
2135 never touch maybe_const, as it is only used for the C front-end
kono
parents:
diff changeset
2136 C_MAYBE_CONST_EXPR. */
kono
parents:
diff changeset
2137
kono
parents:
diff changeset
2138 tree
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2139 c_fully_fold (tree x, bool /*in_init*/, bool */*maybe_const*/, bool lval)
111
kono
parents:
diff changeset
2140 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2141 return cp_fold_maybe_rvalue (x, !lval);
111
kono
parents:
diff changeset
2142 }
kono
parents:
diff changeset
2143
kono
parents:
diff changeset
2144 static GTY((deletable)) hash_map<tree, tree> *fold_cache;
kono
parents:
diff changeset
2145
kono
parents:
diff changeset
2146 /* Dispose of the whole FOLD_CACHE. */
kono
parents:
diff changeset
2147
kono
parents:
diff changeset
2148 void
kono
parents:
diff changeset
2149 clear_fold_cache (void)
kono
parents:
diff changeset
2150 {
kono
parents:
diff changeset
2151 if (fold_cache != NULL)
kono
parents:
diff changeset
2152 fold_cache->empty ();
kono
parents:
diff changeset
2153 }
kono
parents:
diff changeset
2154
kono
parents:
diff changeset
2155 /* This function tries to fold an expression X.
kono
parents:
diff changeset
2156 To avoid combinatorial explosion, folding results are kept in fold_cache.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2157 If X is invalid, we don't fold at all.
111
kono
parents:
diff changeset
2158 For performance reasons we don't cache expressions representing a
kono
parents:
diff changeset
2159 declaration or constant.
kono
parents:
diff changeset
2160 Function returns X or its folded variant. */
kono
parents:
diff changeset
2161
kono
parents:
diff changeset
2162 static tree
kono
parents:
diff changeset
2163 cp_fold (tree x)
kono
parents:
diff changeset
2164 {
kono
parents:
diff changeset
2165 tree op0, op1, op2, op3;
kono
parents:
diff changeset
2166 tree org_x = x, r = NULL_TREE;
kono
parents:
diff changeset
2167 enum tree_code code;
kono
parents:
diff changeset
2168 location_t loc;
kono
parents:
diff changeset
2169 bool rval_ops = true;
kono
parents:
diff changeset
2170
kono
parents:
diff changeset
2171 if (!x || x == error_mark_node)
kono
parents:
diff changeset
2172 return x;
kono
parents:
diff changeset
2173
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2174 if (EXPR_P (x) && (!TREE_TYPE (x) || TREE_TYPE (x) == error_mark_node))
111
kono
parents:
diff changeset
2175 return x;
kono
parents:
diff changeset
2176
kono
parents:
diff changeset
2177 /* Don't bother to cache DECLs or constants. */
kono
parents:
diff changeset
2178 if (DECL_P (x) || CONSTANT_CLASS_P (x))
kono
parents:
diff changeset
2179 return x;
kono
parents:
diff changeset
2180
kono
parents:
diff changeset
2181 if (fold_cache == NULL)
kono
parents:
diff changeset
2182 fold_cache = hash_map<tree, tree>::create_ggc (101);
kono
parents:
diff changeset
2183
kono
parents:
diff changeset
2184 if (tree *cached = fold_cache->get (x))
kono
parents:
diff changeset
2185 return *cached;
kono
parents:
diff changeset
2186
kono
parents:
diff changeset
2187 code = TREE_CODE (x);
kono
parents:
diff changeset
2188 switch (code)
kono
parents:
diff changeset
2189 {
kono
parents:
diff changeset
2190 case CLEANUP_POINT_EXPR:
kono
parents:
diff changeset
2191 /* Strip CLEANUP_POINT_EXPR if the expression doesn't have side
kono
parents:
diff changeset
2192 effects. */
kono
parents:
diff changeset
2193 r = cp_fold_rvalue (TREE_OPERAND (x, 0));
kono
parents:
diff changeset
2194 if (!TREE_SIDE_EFFECTS (r))
kono
parents:
diff changeset
2195 x = r;
kono
parents:
diff changeset
2196 break;
kono
parents:
diff changeset
2197
kono
parents:
diff changeset
2198 case SIZEOF_EXPR:
kono
parents:
diff changeset
2199 x = fold_sizeof_expr (x);
kono
parents:
diff changeset
2200 break;
kono
parents:
diff changeset
2201
kono
parents:
diff changeset
2202 case VIEW_CONVERT_EXPR:
kono
parents:
diff changeset
2203 rval_ops = false;
kono
parents:
diff changeset
2204 /* FALLTHRU */
kono
parents:
diff changeset
2205 case CONVERT_EXPR:
kono
parents:
diff changeset
2206 case NOP_EXPR:
kono
parents:
diff changeset
2207 case NON_LVALUE_EXPR:
kono
parents:
diff changeset
2208
kono
parents:
diff changeset
2209 if (VOID_TYPE_P (TREE_TYPE (x)))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2210 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2211 /* This is just to make sure we don't end up with casts to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2212 void from error_mark_node. If we just return x, then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2213 cp_fold_r might fold the operand into error_mark_node and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2214 leave the conversion in the IR. STRIP_USELESS_TYPE_CONVERSION
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2215 during gimplification doesn't like such casts.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2216 Don't create a new tree if op0 != TREE_OPERAND (x, 0), the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2217 folding of the operand should be in the caches and if in cp_fold_r
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2218 it will modify it in place. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2219 op0 = cp_fold (TREE_OPERAND (x, 0));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2220 if (op0 == error_mark_node)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2221 x = error_mark_node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2222 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2223 }
111
kono
parents:
diff changeset
2224
kono
parents:
diff changeset
2225 loc = EXPR_LOCATION (x);
kono
parents:
diff changeset
2226 op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops);
kono
parents:
diff changeset
2227
kono
parents:
diff changeset
2228 if (code == CONVERT_EXPR
kono
parents:
diff changeset
2229 && SCALAR_TYPE_P (TREE_TYPE (x))
kono
parents:
diff changeset
2230 && op0 != void_node)
kono
parents:
diff changeset
2231 /* During parsing we used convert_to_*_nofold; re-convert now using the
kono
parents:
diff changeset
2232 folding variants, since fold() doesn't do those transformations. */
kono
parents:
diff changeset
2233 x = fold (convert (TREE_TYPE (x), op0));
kono
parents:
diff changeset
2234 else if (op0 != TREE_OPERAND (x, 0))
kono
parents:
diff changeset
2235 {
kono
parents:
diff changeset
2236 if (op0 == error_mark_node)
kono
parents:
diff changeset
2237 x = error_mark_node;
kono
parents:
diff changeset
2238 else
kono
parents:
diff changeset
2239 x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
kono
parents:
diff changeset
2240 }
kono
parents:
diff changeset
2241 else
kono
parents:
diff changeset
2242 x = fold (x);
kono
parents:
diff changeset
2243
kono
parents:
diff changeset
2244 /* Conversion of an out-of-range value has implementation-defined
kono
parents:
diff changeset
2245 behavior; the language considers it different from arithmetic
kono
parents:
diff changeset
2246 overflow, which is undefined. */
kono
parents:
diff changeset
2247 if (TREE_CODE (op0) == INTEGER_CST
kono
parents:
diff changeset
2248 && TREE_OVERFLOW_P (x) && !TREE_OVERFLOW_P (op0))
kono
parents:
diff changeset
2249 TREE_OVERFLOW (x) = false;
kono
parents:
diff changeset
2250
kono
parents:
diff changeset
2251 break;
kono
parents:
diff changeset
2252
kono
parents:
diff changeset
2253 case INDIRECT_REF:
kono
parents:
diff changeset
2254 /* We don't need the decltype(auto) obfuscation anymore. */
kono
parents:
diff changeset
2255 if (REF_PARENTHESIZED_P (x))
kono
parents:
diff changeset
2256 {
kono
parents:
diff changeset
2257 tree p = maybe_undo_parenthesized_ref (x);
kono
parents:
diff changeset
2258 return cp_fold (p);
kono
parents:
diff changeset
2259 }
kono
parents:
diff changeset
2260 goto unary;
kono
parents:
diff changeset
2261
kono
parents:
diff changeset
2262 case ADDR_EXPR:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2263 loc = EXPR_LOCATION (x);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2264 op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), false);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2265
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2266 /* Cope with user tricks that amount to offsetof. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2267 if (op0 != error_mark_node
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2268 && TREE_CODE (TREE_TYPE (op0)) != FUNCTION_TYPE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2269 && TREE_CODE (TREE_TYPE (op0)) != METHOD_TYPE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2270 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2271 tree val = get_base_address (op0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2272 if (val
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2273 && INDIRECT_REF_P (val)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2274 && COMPLETE_TYPE_P (TREE_TYPE (val))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2275 && TREE_CONSTANT (TREE_OPERAND (val, 0)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2276 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2277 val = TREE_OPERAND (val, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2278 STRIP_NOPS (val);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2279 if (TREE_CODE (val) == INTEGER_CST)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2280 return fold_offsetof (op0, TREE_TYPE (x));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2281 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2282 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2283 goto finish_unary;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2284
111
kono
parents:
diff changeset
2285 case REALPART_EXPR:
kono
parents:
diff changeset
2286 case IMAGPART_EXPR:
kono
parents:
diff changeset
2287 rval_ops = false;
kono
parents:
diff changeset
2288 /* FALLTHRU */
kono
parents:
diff changeset
2289 case CONJ_EXPR:
kono
parents:
diff changeset
2290 case FIX_TRUNC_EXPR:
kono
parents:
diff changeset
2291 case FLOAT_EXPR:
kono
parents:
diff changeset
2292 case NEGATE_EXPR:
kono
parents:
diff changeset
2293 case ABS_EXPR:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2294 case ABSU_EXPR:
111
kono
parents:
diff changeset
2295 case BIT_NOT_EXPR:
kono
parents:
diff changeset
2296 case TRUTH_NOT_EXPR:
kono
parents:
diff changeset
2297 case FIXED_CONVERT_EXPR:
kono
parents:
diff changeset
2298 unary:
kono
parents:
diff changeset
2299
kono
parents:
diff changeset
2300 loc = EXPR_LOCATION (x);
kono
parents:
diff changeset
2301 op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops);
kono
parents:
diff changeset
2302
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2303 finish_unary:
111
kono
parents:
diff changeset
2304 if (op0 != TREE_OPERAND (x, 0))
kono
parents:
diff changeset
2305 {
kono
parents:
diff changeset
2306 if (op0 == error_mark_node)
kono
parents:
diff changeset
2307 x = error_mark_node;
kono
parents:
diff changeset
2308 else
kono
parents:
diff changeset
2309 {
kono
parents:
diff changeset
2310 x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
kono
parents:
diff changeset
2311 if (code == INDIRECT_REF
kono
parents:
diff changeset
2312 && (INDIRECT_REF_P (x) || TREE_CODE (x) == MEM_REF))
kono
parents:
diff changeset
2313 {
kono
parents:
diff changeset
2314 TREE_READONLY (x) = TREE_READONLY (org_x);
kono
parents:
diff changeset
2315 TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
kono
parents:
diff changeset
2316 TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
kono
parents:
diff changeset
2317 }
kono
parents:
diff changeset
2318 }
kono
parents:
diff changeset
2319 }
kono
parents:
diff changeset
2320 else
kono
parents:
diff changeset
2321 x = fold (x);
kono
parents:
diff changeset
2322
kono
parents:
diff changeset
2323 gcc_assert (TREE_CODE (x) != COND_EXPR
kono
parents:
diff changeset
2324 || !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))));
kono
parents:
diff changeset
2325 break;
kono
parents:
diff changeset
2326
kono
parents:
diff changeset
2327 case UNARY_PLUS_EXPR:
kono
parents:
diff changeset
2328 op0 = cp_fold_rvalue (TREE_OPERAND (x, 0));
kono
parents:
diff changeset
2329 if (op0 == error_mark_node)
kono
parents:
diff changeset
2330 x = error_mark_node;
kono
parents:
diff changeset
2331 else
kono
parents:
diff changeset
2332 x = fold_convert (TREE_TYPE (x), op0);
kono
parents:
diff changeset
2333 break;
kono
parents:
diff changeset
2334
kono
parents:
diff changeset
2335 case POSTDECREMENT_EXPR:
kono
parents:
diff changeset
2336 case POSTINCREMENT_EXPR:
kono
parents:
diff changeset
2337 case INIT_EXPR:
kono
parents:
diff changeset
2338 case PREDECREMENT_EXPR:
kono
parents:
diff changeset
2339 case PREINCREMENT_EXPR:
kono
parents:
diff changeset
2340 case COMPOUND_EXPR:
kono
parents:
diff changeset
2341 case MODIFY_EXPR:
kono
parents:
diff changeset
2342 rval_ops = false;
kono
parents:
diff changeset
2343 /* FALLTHRU */
kono
parents:
diff changeset
2344 case POINTER_PLUS_EXPR:
kono
parents:
diff changeset
2345 case PLUS_EXPR:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2346 case POINTER_DIFF_EXPR:
111
kono
parents:
diff changeset
2347 case MINUS_EXPR:
kono
parents:
diff changeset
2348 case MULT_EXPR:
kono
parents:
diff changeset
2349 case TRUNC_DIV_EXPR:
kono
parents:
diff changeset
2350 case CEIL_DIV_EXPR:
kono
parents:
diff changeset
2351 case FLOOR_DIV_EXPR:
kono
parents:
diff changeset
2352 case ROUND_DIV_EXPR:
kono
parents:
diff changeset
2353 case TRUNC_MOD_EXPR:
kono
parents:
diff changeset
2354 case CEIL_MOD_EXPR:
kono
parents:
diff changeset
2355 case ROUND_MOD_EXPR:
kono
parents:
diff changeset
2356 case RDIV_EXPR:
kono
parents:
diff changeset
2357 case EXACT_DIV_EXPR:
kono
parents:
diff changeset
2358 case MIN_EXPR:
kono
parents:
diff changeset
2359 case MAX_EXPR:
kono
parents:
diff changeset
2360 case LSHIFT_EXPR:
kono
parents:
diff changeset
2361 case RSHIFT_EXPR:
kono
parents:
diff changeset
2362 case LROTATE_EXPR:
kono
parents:
diff changeset
2363 case RROTATE_EXPR:
kono
parents:
diff changeset
2364 case BIT_AND_EXPR:
kono
parents:
diff changeset
2365 case BIT_IOR_EXPR:
kono
parents:
diff changeset
2366 case BIT_XOR_EXPR:
kono
parents:
diff changeset
2367 case TRUTH_AND_EXPR:
kono
parents:
diff changeset
2368 case TRUTH_ANDIF_EXPR:
kono
parents:
diff changeset
2369 case TRUTH_OR_EXPR:
kono
parents:
diff changeset
2370 case TRUTH_ORIF_EXPR:
kono
parents:
diff changeset
2371 case TRUTH_XOR_EXPR:
kono
parents:
diff changeset
2372 case LT_EXPR: case LE_EXPR:
kono
parents:
diff changeset
2373 case GT_EXPR: case GE_EXPR:
kono
parents:
diff changeset
2374 case EQ_EXPR: case NE_EXPR:
kono
parents:
diff changeset
2375 case UNORDERED_EXPR: case ORDERED_EXPR:
kono
parents:
diff changeset
2376 case UNLT_EXPR: case UNLE_EXPR:
kono
parents:
diff changeset
2377 case UNGT_EXPR: case UNGE_EXPR:
kono
parents:
diff changeset
2378 case UNEQ_EXPR: case LTGT_EXPR:
kono
parents:
diff changeset
2379 case RANGE_EXPR: case COMPLEX_EXPR:
kono
parents:
diff changeset
2380
kono
parents:
diff changeset
2381 loc = EXPR_LOCATION (x);
kono
parents:
diff changeset
2382 op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops);
kono
parents:
diff changeset
2383 op1 = cp_fold_rvalue (TREE_OPERAND (x, 1));
kono
parents:
diff changeset
2384
kono
parents:
diff changeset
2385 if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
kono
parents:
diff changeset
2386 {
kono
parents:
diff changeset
2387 if (op0 == error_mark_node || op1 == error_mark_node)
kono
parents:
diff changeset
2388 x = error_mark_node;
kono
parents:
diff changeset
2389 else
kono
parents:
diff changeset
2390 x = fold_build2_loc (loc, code, TREE_TYPE (x), op0, op1);
kono
parents:
diff changeset
2391 }
kono
parents:
diff changeset
2392 else
kono
parents:
diff changeset
2393 x = fold (x);
kono
parents:
diff changeset
2394
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2395 /* This is only needed for -Wnonnull-compare and only if
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2396 TREE_NO_WARNING (org_x), but to avoid that option affecting code
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2397 generation, we do it always. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2398 if (COMPARISON_CLASS_P (org_x))
111
kono
parents:
diff changeset
2399 {
kono
parents:
diff changeset
2400 if (x == error_mark_node || TREE_CODE (x) == INTEGER_CST)
kono
parents:
diff changeset
2401 ;
kono
parents:
diff changeset
2402 else if (COMPARISON_CLASS_P (x))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2403 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2404 if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2405 TREE_NO_WARNING (x) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2406 }
111
kono
parents:
diff changeset
2407 /* Otherwise give up on optimizing these, let GIMPLE folders
kono
parents:
diff changeset
2408 optimize those later on. */
kono
parents:
diff changeset
2409 else if (op0 != TREE_OPERAND (org_x, 0)
kono
parents:
diff changeset
2410 || op1 != TREE_OPERAND (org_x, 1))
kono
parents:
diff changeset
2411 {
kono
parents:
diff changeset
2412 x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2413 if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2414 TREE_NO_WARNING (x) = 1;
111
kono
parents:
diff changeset
2415 }
kono
parents:
diff changeset
2416 else
kono
parents:
diff changeset
2417 x = org_x;
kono
parents:
diff changeset
2418 }
kono
parents:
diff changeset
2419 break;
kono
parents:
diff changeset
2420
kono
parents:
diff changeset
2421 case VEC_COND_EXPR:
kono
parents:
diff changeset
2422 case COND_EXPR:
kono
parents:
diff changeset
2423 loc = EXPR_LOCATION (x);
kono
parents:
diff changeset
2424 op0 = cp_fold_rvalue (TREE_OPERAND (x, 0));
kono
parents:
diff changeset
2425 op1 = cp_fold (TREE_OPERAND (x, 1));
kono
parents:
diff changeset
2426 op2 = cp_fold (TREE_OPERAND (x, 2));
kono
parents:
diff changeset
2427
kono
parents:
diff changeset
2428 if (TREE_CODE (TREE_TYPE (x)) == BOOLEAN_TYPE)
kono
parents:
diff changeset
2429 {
kono
parents:
diff changeset
2430 warning_sentinel s (warn_int_in_bool_context);
kono
parents:
diff changeset
2431 if (!VOID_TYPE_P (TREE_TYPE (op1)))
kono
parents:
diff changeset
2432 op1 = cp_truthvalue_conversion (op1);
kono
parents:
diff changeset
2433 if (!VOID_TYPE_P (TREE_TYPE (op2)))
kono
parents:
diff changeset
2434 op2 = cp_truthvalue_conversion (op2);
kono
parents:
diff changeset
2435 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2436 else if (VOID_TYPE_P (TREE_TYPE (x)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2437 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2438 if (TREE_CODE (op0) == INTEGER_CST)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2439 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2440 /* If the condition is constant, fold can fold away
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2441 the COND_EXPR. If some statement-level uses of COND_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2442 have one of the branches NULL, avoid folding crash. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2443 if (!op1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2444 op1 = build_empty_stmt (loc);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2445 if (!op2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2446 op2 = build_empty_stmt (loc);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2447 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2448 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2449 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2450 /* Otherwise, don't bother folding a void condition, since
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2451 it can't produce a constant value. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2452 if (op0 != TREE_OPERAND (x, 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2453 || op1 != TREE_OPERAND (x, 1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2454 || op2 != TREE_OPERAND (x, 2))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2455 x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2456 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2457 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2458 }
111
kono
parents:
diff changeset
2459
kono
parents:
diff changeset
2460 if (op0 != TREE_OPERAND (x, 0)
kono
parents:
diff changeset
2461 || op1 != TREE_OPERAND (x, 1)
kono
parents:
diff changeset
2462 || op2 != TREE_OPERAND (x, 2))
kono
parents:
diff changeset
2463 {
kono
parents:
diff changeset
2464 if (op0 == error_mark_node
kono
parents:
diff changeset
2465 || op1 == error_mark_node
kono
parents:
diff changeset
2466 || op2 == error_mark_node)
kono
parents:
diff changeset
2467 x = error_mark_node;
kono
parents:
diff changeset
2468 else
kono
parents:
diff changeset
2469 x = fold_build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
kono
parents:
diff changeset
2470 }
kono
parents:
diff changeset
2471 else
kono
parents:
diff changeset
2472 x = fold (x);
kono
parents:
diff changeset
2473
kono
parents:
diff changeset
2474 /* A COND_EXPR might have incompatible types in branches if one or both
kono
parents:
diff changeset
2475 arms are bitfields. If folding exposed such a branch, fix it up. */
kono
parents:
diff changeset
2476 if (TREE_CODE (x) != code
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2477 && x != error_mark_node
111
kono
parents:
diff changeset
2478 && !useless_type_conversion_p (TREE_TYPE (org_x), TREE_TYPE (x)))
kono
parents:
diff changeset
2479 x = fold_convert (TREE_TYPE (org_x), x);
kono
parents:
diff changeset
2480
kono
parents:
diff changeset
2481 break;
kono
parents:
diff changeset
2482
kono
parents:
diff changeset
2483 case CALL_EXPR:
kono
parents:
diff changeset
2484 {
kono
parents:
diff changeset
2485 int i, m, sv = optimize, nw = sv, changed = 0;
kono
parents:
diff changeset
2486 tree callee = get_callee_fndecl (x);
kono
parents:
diff changeset
2487
kono
parents:
diff changeset
2488 /* Some built-in function calls will be evaluated at compile-time in
kono
parents:
diff changeset
2489 fold (). Set optimize to 1 when folding __builtin_constant_p inside
kono
parents:
diff changeset
2490 a constexpr function so that fold_builtin_1 doesn't fold it to 0. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2491 if (callee && fndecl_built_in_p (callee) && !optimize
111
kono
parents:
diff changeset
2492 && DECL_IS_BUILTIN_CONSTANT_P (callee)
kono
parents:
diff changeset
2493 && current_function_decl
kono
parents:
diff changeset
2494 && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
kono
parents:
diff changeset
2495 nw = 1;
kono
parents:
diff changeset
2496
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2497 /* Defer folding __builtin_is_constant_evaluated. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2498 if (callee
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2499 && fndecl_built_in_p (callee, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2500 BUILT_IN_FRONTEND))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2501 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2502
111
kono
parents:
diff changeset
2503 x = copy_node (x);
kono
parents:
diff changeset
2504
kono
parents:
diff changeset
2505 m = call_expr_nargs (x);
kono
parents:
diff changeset
2506 for (i = 0; i < m; i++)
kono
parents:
diff changeset
2507 {
kono
parents:
diff changeset
2508 r = cp_fold (CALL_EXPR_ARG (x, i));
kono
parents:
diff changeset
2509 if (r != CALL_EXPR_ARG (x, i))
kono
parents:
diff changeset
2510 {
kono
parents:
diff changeset
2511 if (r == error_mark_node)
kono
parents:
diff changeset
2512 {
kono
parents:
diff changeset
2513 x = error_mark_node;
kono
parents:
diff changeset
2514 break;
kono
parents:
diff changeset
2515 }
kono
parents:
diff changeset
2516 changed = 1;
kono
parents:
diff changeset
2517 }
kono
parents:
diff changeset
2518 CALL_EXPR_ARG (x, i) = r;
kono
parents:
diff changeset
2519 }
kono
parents:
diff changeset
2520 if (x == error_mark_node)
kono
parents:
diff changeset
2521 break;
kono
parents:
diff changeset
2522
kono
parents:
diff changeset
2523 optimize = nw;
kono
parents:
diff changeset
2524 r = fold (x);
kono
parents:
diff changeset
2525 optimize = sv;
kono
parents:
diff changeset
2526
kono
parents:
diff changeset
2527 if (TREE_CODE (r) != CALL_EXPR)
kono
parents:
diff changeset
2528 {
kono
parents:
diff changeset
2529 x = cp_fold (r);
kono
parents:
diff changeset
2530 break;
kono
parents:
diff changeset
2531 }
kono
parents:
diff changeset
2532
kono
parents:
diff changeset
2533 optimize = nw;
kono
parents:
diff changeset
2534
kono
parents:
diff changeset
2535 /* Invoke maybe_constant_value for functions declared
kono
parents:
diff changeset
2536 constexpr and not called with AGGR_INIT_EXPRs.
kono
parents:
diff changeset
2537 TODO:
kono
parents:
diff changeset
2538 Do constexpr expansion of expressions where the call itself is not
kono
parents:
diff changeset
2539 constant, but the call followed by an INDIRECT_REF is. */
kono
parents:
diff changeset
2540 if (callee && DECL_DECLARED_CONSTEXPR_P (callee)
kono
parents:
diff changeset
2541 && !flag_no_inline)
kono
parents:
diff changeset
2542 r = maybe_constant_value (x);
kono
parents:
diff changeset
2543 optimize = sv;
kono
parents:
diff changeset
2544
kono
parents:
diff changeset
2545 if (TREE_CODE (r) != CALL_EXPR)
kono
parents:
diff changeset
2546 {
kono
parents:
diff changeset
2547 if (DECL_CONSTRUCTOR_P (callee))
kono
parents:
diff changeset
2548 {
kono
parents:
diff changeset
2549 loc = EXPR_LOCATION (x);
kono
parents:
diff changeset
2550 tree s = build_fold_indirect_ref_loc (loc,
kono
parents:
diff changeset
2551 CALL_EXPR_ARG (x, 0));
kono
parents:
diff changeset
2552 r = build2_loc (loc, INIT_EXPR, TREE_TYPE (s), s, r);
kono
parents:
diff changeset
2553 }
kono
parents:
diff changeset
2554 x = r;
kono
parents:
diff changeset
2555 break;
kono
parents:
diff changeset
2556 }
kono
parents:
diff changeset
2557
kono
parents:
diff changeset
2558 if (!changed)
kono
parents:
diff changeset
2559 x = org_x;
kono
parents:
diff changeset
2560 break;
kono
parents:
diff changeset
2561 }
kono
parents:
diff changeset
2562
kono
parents:
diff changeset
2563 case CONSTRUCTOR:
kono
parents:
diff changeset
2564 {
kono
parents:
diff changeset
2565 unsigned i;
kono
parents:
diff changeset
2566 constructor_elt *p;
kono
parents:
diff changeset
2567 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (x);
kono
parents:
diff changeset
2568 vec<constructor_elt, va_gc> *nelts = NULL;
kono
parents:
diff changeset
2569 FOR_EACH_VEC_SAFE_ELT (elts, i, p)
kono
parents:
diff changeset
2570 {
kono
parents:
diff changeset
2571 tree op = cp_fold (p->value);
kono
parents:
diff changeset
2572 if (op != p->value)
kono
parents:
diff changeset
2573 {
kono
parents:
diff changeset
2574 if (op == error_mark_node)
kono
parents:
diff changeset
2575 {
kono
parents:
diff changeset
2576 x = error_mark_node;
kono
parents:
diff changeset
2577 vec_free (nelts);
kono
parents:
diff changeset
2578 break;
kono
parents:
diff changeset
2579 }
kono
parents:
diff changeset
2580 if (nelts == NULL)
kono
parents:
diff changeset
2581 nelts = elts->copy ();
kono
parents:
diff changeset
2582 (*nelts)[i].value = op;
kono
parents:
diff changeset
2583 }
kono
parents:
diff changeset
2584 }
kono
parents:
diff changeset
2585 if (nelts)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2586 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2587 x = build_constructor (TREE_TYPE (x), nelts);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2588 CONSTRUCTOR_PLACEHOLDER_BOUNDARY (x)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2589 = CONSTRUCTOR_PLACEHOLDER_BOUNDARY (org_x);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2590 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2591 if (VECTOR_TYPE_P (TREE_TYPE (x)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2592 x = fold (x);
111
kono
parents:
diff changeset
2593 break;
kono
parents:
diff changeset
2594 }
kono
parents:
diff changeset
2595 case TREE_VEC:
kono
parents:
diff changeset
2596 {
kono
parents:
diff changeset
2597 bool changed = false;
kono
parents:
diff changeset
2598 vec<tree, va_gc> *vec = make_tree_vector ();
kono
parents:
diff changeset
2599 int i, n = TREE_VEC_LENGTH (x);
kono
parents:
diff changeset
2600 vec_safe_reserve (vec, n);
kono
parents:
diff changeset
2601
kono
parents:
diff changeset
2602 for (i = 0; i < n; i++)
kono
parents:
diff changeset
2603 {
kono
parents:
diff changeset
2604 tree op = cp_fold (TREE_VEC_ELT (x, i));
kono
parents:
diff changeset
2605 vec->quick_push (op);
kono
parents:
diff changeset
2606 if (op != TREE_VEC_ELT (x, i))
kono
parents:
diff changeset
2607 changed = true;
kono
parents:
diff changeset
2608 }
kono
parents:
diff changeset
2609
kono
parents:
diff changeset
2610 if (changed)
kono
parents:
diff changeset
2611 {
kono
parents:
diff changeset
2612 r = copy_node (x);
kono
parents:
diff changeset
2613 for (i = 0; i < n; i++)
kono
parents:
diff changeset
2614 TREE_VEC_ELT (r, i) = (*vec)[i];
kono
parents:
diff changeset
2615 x = r;
kono
parents:
diff changeset
2616 }
kono
parents:
diff changeset
2617
kono
parents:
diff changeset
2618 release_tree_vector (vec);
kono
parents:
diff changeset
2619 }
kono
parents:
diff changeset
2620
kono
parents:
diff changeset
2621 break;
kono
parents:
diff changeset
2622
kono
parents:
diff changeset
2623 case ARRAY_REF:
kono
parents:
diff changeset
2624 case ARRAY_RANGE_REF:
kono
parents:
diff changeset
2625
kono
parents:
diff changeset
2626 loc = EXPR_LOCATION (x);
kono
parents:
diff changeset
2627 op0 = cp_fold (TREE_OPERAND (x, 0));
kono
parents:
diff changeset
2628 op1 = cp_fold (TREE_OPERAND (x, 1));
kono
parents:
diff changeset
2629 op2 = cp_fold (TREE_OPERAND (x, 2));
kono
parents:
diff changeset
2630 op3 = cp_fold (TREE_OPERAND (x, 3));
kono
parents:
diff changeset
2631
kono
parents:
diff changeset
2632 if (op0 != TREE_OPERAND (x, 0)
kono
parents:
diff changeset
2633 || op1 != TREE_OPERAND (x, 1)
kono
parents:
diff changeset
2634 || op2 != TREE_OPERAND (x, 2)
kono
parents:
diff changeset
2635 || op3 != TREE_OPERAND (x, 3))
kono
parents:
diff changeset
2636 {
kono
parents:
diff changeset
2637 if (op0 == error_mark_node
kono
parents:
diff changeset
2638 || op1 == error_mark_node
kono
parents:
diff changeset
2639 || op2 == error_mark_node
kono
parents:
diff changeset
2640 || op3 == error_mark_node)
kono
parents:
diff changeset
2641 x = error_mark_node;
kono
parents:
diff changeset
2642 else
kono
parents:
diff changeset
2643 {
kono
parents:
diff changeset
2644 x = build4_loc (loc, code, TREE_TYPE (x), op0, op1, op2, op3);
kono
parents:
diff changeset
2645 TREE_READONLY (x) = TREE_READONLY (org_x);
kono
parents:
diff changeset
2646 TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
kono
parents:
diff changeset
2647 TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
kono
parents:
diff changeset
2648 }
kono
parents:
diff changeset
2649 }
kono
parents:
diff changeset
2650
kono
parents:
diff changeset
2651 x = fold (x);
kono
parents:
diff changeset
2652 break;
kono
parents:
diff changeset
2653
kono
parents:
diff changeset
2654 case SAVE_EXPR:
kono
parents:
diff changeset
2655 /* A SAVE_EXPR might contain e.g. (0 * i) + (0 * j), which, after
kono
parents:
diff changeset
2656 folding, evaluates to an invariant. In that case no need to wrap
kono
parents:
diff changeset
2657 this folded tree with a SAVE_EXPR. */
kono
parents:
diff changeset
2658 r = cp_fold (TREE_OPERAND (x, 0));
kono
parents:
diff changeset
2659 if (tree_invariant_p (r))
kono
parents:
diff changeset
2660 x = r;
kono
parents:
diff changeset
2661 break;
kono
parents:
diff changeset
2662
kono
parents:
diff changeset
2663 default:
kono
parents:
diff changeset
2664 return org_x;
kono
parents:
diff changeset
2665 }
kono
parents:
diff changeset
2666
kono
parents:
diff changeset
2667 fold_cache->put (org_x, x);
kono
parents:
diff changeset
2668 /* Prevent that we try to fold an already folded result again. */
kono
parents:
diff changeset
2669 if (x != org_x)
kono
parents:
diff changeset
2670 fold_cache->put (x, x);
kono
parents:
diff changeset
2671
kono
parents:
diff changeset
2672 return x;
kono
parents:
diff changeset
2673 }
kono
parents:
diff changeset
2674
kono
parents:
diff changeset
2675 #include "gt-cp-cp-gimplify.h"