File: | build/gcc/gimplify.cc |
Warning: | line 14011, column 7 Value stored to 'orig_decl' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Tree lowering pass. This pass converts the GENERIC functions-as-trees |
2 | tree representation into the GIMPLE form. |
3 | Copyright (C) 2002-2023 Free Software Foundation, Inc. |
4 | Major work done by Sebastian Pop <s.pop@laposte.net>, |
5 | Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>. |
6 | |
7 | This file is part of GCC. |
8 | |
9 | GCC is free software; you can redistribute it and/or modify it under |
10 | the terms of the GNU General Public License as published by the Free |
11 | Software Foundation; either version 3, or (at your option) any later |
12 | version. |
13 | |
14 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
15 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
17 | for more details. |
18 | |
19 | You should have received a copy of the GNU General Public License |
20 | along with GCC; see the file COPYING3. If not see |
21 | <http://www.gnu.org/licenses/>. */ |
22 | |
23 | #include "config.h" |
24 | #include "system.h" |
25 | #include "coretypes.h" |
26 | #include "backend.h" |
27 | #include "target.h" |
28 | #include "rtl.h" |
29 | #include "tree.h" |
30 | #include "memmodel.h" |
31 | #include "tm_p.h" |
32 | #include "gimple.h" |
33 | #include "gimple-predict.h" |
34 | #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */ |
35 | #include "ssa.h" |
36 | #include "cgraph.h" |
37 | #include "tree-pretty-print.h" |
38 | #include "diagnostic-core.h" |
39 | #include "alias.h" |
40 | #include "fold-const.h" |
41 | #include "calls.h" |
42 | #include "varasm.h" |
43 | #include "stmt.h" |
44 | #include "expr.h" |
45 | #include "gimple-iterator.h" |
46 | #include "gimple-fold.h" |
47 | #include "tree-eh.h" |
48 | #include "gimplify.h" |
49 | #include "stor-layout.h" |
50 | #include "print-tree.h" |
51 | #include "tree-iterator.h" |
52 | #include "tree-inline.h" |
53 | #include "langhooks.h" |
54 | #include "tree-cfg.h" |
55 | #include "tree-ssa.h" |
56 | #include "tree-hash-traits.h" |
57 | #include "omp-general.h" |
58 | #include "omp-low.h" |
59 | #include "gimple-low.h" |
60 | #include "gomp-constants.h" |
61 | #include "splay-tree.h" |
62 | #include "gimple-walk.h" |
63 | #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */ |
64 | #include "builtins.h" |
65 | #include "stringpool.h" |
66 | #include "attribs.h" |
67 | #include "asan.h" |
68 | #include "dbgcnt.h" |
69 | #include "omp-offload.h" |
70 | #include "context.h" |
71 | #include "tree-nested.h" |
72 | |
73 | /* Hash set of poisoned variables in a bind expr. */ |
74 | static hash_set<tree> *asan_poisoned_variables = NULLnullptr; |
75 | |
76 | enum gimplify_omp_var_data |
77 | { |
78 | GOVD_SEEN = 0x000001, |
79 | GOVD_EXPLICIT = 0x000002, |
80 | GOVD_SHARED = 0x000004, |
81 | GOVD_PRIVATE = 0x000008, |
82 | GOVD_FIRSTPRIVATE = 0x000010, |
83 | GOVD_LASTPRIVATE = 0x000020, |
84 | GOVD_REDUCTION = 0x000040, |
85 | GOVD_LOCAL = 0x00080, |
86 | GOVD_MAP = 0x000100, |
87 | GOVD_DEBUG_PRIVATE = 0x000200, |
88 | GOVD_PRIVATE_OUTER_REF = 0x000400, |
89 | GOVD_LINEAR = 0x000800, |
90 | GOVD_ALIGNED = 0x001000, |
91 | |
92 | /* Flag for GOVD_MAP: don't copy back. */ |
93 | GOVD_MAP_TO_ONLY = 0x002000, |
94 | |
95 | /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */ |
96 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000, |
97 | |
98 | GOVD_MAP_0LEN_ARRAY = 0x008000, |
99 | |
100 | /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */ |
101 | GOVD_MAP_ALWAYS_TO = 0x010000, |
102 | |
103 | /* Flag for shared vars that are or might be stored to in the region. */ |
104 | GOVD_WRITTEN = 0x020000, |
105 | |
106 | /* Flag for GOVD_MAP, if it is a forced mapping. */ |
107 | GOVD_MAP_FORCE = 0x040000, |
108 | |
109 | /* Flag for GOVD_MAP: must be present already. */ |
110 | GOVD_MAP_FORCE_PRESENT = 0x080000, |
111 | |
112 | /* Flag for GOVD_MAP: only allocate. */ |
113 | GOVD_MAP_ALLOC_ONLY = 0x100000, |
114 | |
115 | /* Flag for GOVD_MAP: only copy back. */ |
116 | GOVD_MAP_FROM_ONLY = 0x200000, |
117 | |
118 | GOVD_NONTEMPORAL = 0x400000, |
119 | |
120 | /* Flag for GOVD_LASTPRIVATE: conditional modifier. */ |
121 | GOVD_LASTPRIVATE_CONDITIONAL = 0x800000, |
122 | |
123 | GOVD_CONDTEMP = 0x1000000, |
124 | |
125 | /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */ |
126 | GOVD_REDUCTION_INSCAN = 0x2000000, |
127 | |
128 | /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT. */ |
129 | GOVD_FIRSTPRIVATE_IMPLICIT = 0x4000000, |
130 | |
131 | GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE |
132 | | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR |
133 | | GOVD_LOCAL) |
134 | }; |
135 | |
136 | |
137 | enum omp_region_type |
138 | { |
139 | ORT_WORKSHARE = 0x00, |
140 | ORT_TASKGROUP = 0x01, |
141 | ORT_SIMD = 0x04, |
142 | |
143 | ORT_PARALLEL = 0x08, |
144 | ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1, |
145 | |
146 | ORT_TASK = 0x10, |
147 | ORT_UNTIED_TASK = ORT_TASK | 1, |
148 | ORT_TASKLOOP = ORT_TASK | 2, |
149 | ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2, |
150 | |
151 | ORT_TEAMS = 0x20, |
152 | ORT_COMBINED_TEAMS = ORT_TEAMS | 1, |
153 | ORT_HOST_TEAMS = ORT_TEAMS | 2, |
154 | ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2, |
155 | |
156 | /* Data region. */ |
157 | ORT_TARGET_DATA = 0x40, |
158 | |
159 | /* Data region with offloading. */ |
160 | ORT_TARGET = 0x80, |
161 | ORT_COMBINED_TARGET = ORT_TARGET | 1, |
162 | ORT_IMPLICIT_TARGET = ORT_TARGET | 2, |
163 | |
164 | /* OpenACC variants. */ |
165 | ORT_ACC = 0x100, /* A generic OpenACC region. */ |
166 | ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */ |
167 | ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */ |
168 | ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */ |
169 | ORT_ACC_SERIAL = ORT_ACC | ORT_TARGET | 4, /* Serial construct. */ |
170 | ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */ |
171 | |
172 | /* Dummy OpenMP region, used to disable expansion of |
173 | DECL_VALUE_EXPRs in taskloop pre body. */ |
174 | ORT_NONE = 0x200 |
175 | }; |
176 | |
177 | /* Gimplify hashtable helper. */ |
178 | |
179 | struct gimplify_hasher : free_ptr_hash <elt_t> |
180 | { |
181 | static inline hashval_t hash (const elt_t *); |
182 | static inline bool equal (const elt_t *, const elt_t *); |
183 | }; |
184 | |
185 | struct gimplify_ctx |
186 | { |
187 | struct gimplify_ctx *prev_context; |
188 | |
189 | vec<gbind *> bind_expr_stack; |
190 | tree temps; |
191 | gimple_seq conditional_cleanups; |
192 | tree exit_label; |
193 | tree return_temp; |
194 | |
195 | vec<tree> case_labels; |
196 | hash_set<tree> *live_switch_vars; |
197 | /* The formal temporary table. Should this be persistent? */ |
198 | hash_table<gimplify_hasher> *temp_htab; |
199 | |
200 | int conditions; |
201 | unsigned into_ssa : 1; |
202 | unsigned allow_rhs_cond_expr : 1; |
203 | unsigned in_cleanup_point_expr : 1; |
204 | unsigned keep_stack : 1; |
205 | unsigned save_stack : 1; |
206 | unsigned in_switch_expr : 1; |
207 | }; |
208 | |
209 | enum gimplify_defaultmap_kind |
210 | { |
211 | GDMK_SCALAR, |
212 | GDMK_SCALAR_TARGET, /* w/ Fortran's target attr, implicit mapping, only. */ |
213 | GDMK_AGGREGATE, |
214 | GDMK_ALLOCATABLE, |
215 | GDMK_POINTER |
216 | }; |
217 | |
218 | struct gimplify_omp_ctx |
219 | { |
220 | struct gimplify_omp_ctx *outer_context; |
221 | splay_tree variables; |
222 | hash_set<tree> *privatized_types; |
223 | tree clauses; |
224 | /* Iteration variables in an OMP_FOR. */ |
225 | vec<tree> loop_iter_var; |
226 | location_t location; |
227 | enum omp_clause_default_kind default_kind; |
228 | enum omp_region_type region_type; |
229 | enum tree_code code; |
230 | bool combined_loop; |
231 | bool distribute; |
232 | bool target_firstprivatize_array_bases; |
233 | bool add_safelen1; |
234 | bool order_concurrent; |
235 | bool has_depend; |
236 | bool in_for_exprs; |
237 | int defaultmap[5]; |
238 | }; |
239 | |
240 | static struct gimplify_ctx *gimplify_ctxp; |
241 | static struct gimplify_omp_ctx *gimplify_omp_ctxp; |
242 | static bool in_omp_construct; |
243 | |
244 | /* Forward declaration. */ |
245 | static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool); |
246 | static hash_map<tree, tree> *oacc_declare_returns; |
247 | static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *, |
248 | bool (*) (tree), fallback_t, bool); |
249 | static void prepare_gimple_addressable (tree *, gimple_seq *); |
250 | |
251 | /* Shorter alias name for the above function for use in gimplify.cc |
252 | only. */ |
253 | |
254 | static inline void |
255 | gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs) |
256 | { |
257 | gimple_seq_add_stmt_without_update (seq_p, gs); |
258 | } |
259 | |
260 | /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is |
261 | NULL, a new sequence is allocated. This function is |
262 | similar to gimple_seq_add_seq, but does not scan the operands. |
263 | During gimplification, we need to manipulate statement sequences |
264 | before the def/use vectors have been constructed. */ |
265 | |
266 | static void |
267 | gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src) |
268 | { |
269 | gimple_stmt_iterator si; |
270 | |
271 | if (src == NULLnullptr) |
272 | return; |
273 | |
274 | si = gsi_last (*dst_p); |
275 | gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT); |
276 | } |
277 | |
278 | |
279 | /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing |
280 | and popping gimplify contexts. */ |
281 | |
282 | static struct gimplify_ctx *ctx_pool = NULLnullptr; |
283 | |
284 | /* Return a gimplify context struct from the pool. */ |
285 | |
286 | static inline struct gimplify_ctx * |
287 | ctx_alloc (void) |
288 | { |
289 | struct gimplify_ctx * c = ctx_pool; |
290 | |
291 | if (c) |
292 | ctx_pool = c->prev_context; |
293 | else |
294 | c = XNEW (struct gimplify_ctx)((struct gimplify_ctx *) xmalloc (sizeof (struct gimplify_ctx ))); |
295 | |
296 | memset (c, '\0', sizeof (*c)); |
297 | return c; |
298 | } |
299 | |
300 | /* Put gimplify context C back into the pool. */ |
301 | |
302 | static inline void |
303 | ctx_free (struct gimplify_ctx *c) |
304 | { |
305 | c->prev_context = ctx_pool; |
306 | ctx_pool = c; |
307 | } |
308 | |
309 | /* Free allocated ctx stack memory. */ |
310 | |
311 | void |
312 | free_gimplify_stack (void) |
313 | { |
314 | struct gimplify_ctx *c; |
315 | |
316 | while ((c = ctx_pool)) |
317 | { |
318 | ctx_pool = c->prev_context; |
319 | free (c); |
320 | } |
321 | } |
322 | |
323 | |
324 | /* Set up a context for the gimplifier. */ |
325 | |
326 | void |
327 | push_gimplify_context (bool in_ssa, bool rhs_cond_ok) |
328 | { |
329 | struct gimplify_ctx *c = ctx_alloc (); |
330 | |
331 | c->prev_context = gimplify_ctxp; |
332 | gimplify_ctxp = c; |
333 | gimplify_ctxp->into_ssa = in_ssa; |
334 | gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok; |
335 | } |
336 | |
337 | /* Tear down a context for the gimplifier. If BODY is non-null, then |
338 | put the temporaries into the outer BIND_EXPR. Otherwise, put them |
339 | in the local_decls. |
340 | |
341 | BODY is not a sequence, but the first tuple in a sequence. */ |
342 | |
343 | void |
344 | pop_gimplify_context (gimple *body) |
345 | { |
346 | struct gimplify_ctx *c = gimplify_ctxp; |
347 | |
348 | gcc_assert (c((void)(!(c && (!c->bind_expr_stack.exists () || c ->bind_expr_stack.is_empty ())) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 350, __FUNCTION__), 0 : 0)) |
349 | && (!c->bind_expr_stack.exists ()((void)(!(c && (!c->bind_expr_stack.exists () || c ->bind_expr_stack.is_empty ())) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 350, __FUNCTION__), 0 : 0)) |
350 | || c->bind_expr_stack.is_empty ()))((void)(!(c && (!c->bind_expr_stack.exists () || c ->bind_expr_stack.is_empty ())) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 350, __FUNCTION__), 0 : 0)); |
351 | c->bind_expr_stack.release (); |
352 | gimplify_ctxp = c->prev_context; |
353 | |
354 | if (body) |
355 | declare_vars (c->temps, body, false); |
356 | else |
357 | record_vars (c->temps); |
358 | |
359 | delete c->temp_htab; |
360 | c->temp_htab = NULLnullptr; |
361 | ctx_free (c); |
362 | } |
363 | |
364 | /* Push a GIMPLE_BIND tuple onto the stack of bindings. */ |
365 | |
366 | static void |
367 | gimple_push_bind_expr (gbind *bind_stmt) |
368 | { |
369 | gimplify_ctxp->bind_expr_stack.reserve (8); |
370 | gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt); |
371 | } |
372 | |
373 | /* Pop the first element off the stack of bindings. */ |
374 | |
375 | static void |
376 | gimple_pop_bind_expr (void) |
377 | { |
378 | gimplify_ctxp->bind_expr_stack.pop (); |
379 | } |
380 | |
381 | /* Return the first element of the stack of bindings. */ |
382 | |
383 | gbind * |
384 | gimple_current_bind_expr (void) |
385 | { |
386 | return gimplify_ctxp->bind_expr_stack.last (); |
387 | } |
388 | |
389 | /* Return the stack of bindings created during gimplification. */ |
390 | |
391 | vec<gbind *> |
392 | gimple_bind_expr_stack (void) |
393 | { |
394 | return gimplify_ctxp->bind_expr_stack; |
395 | } |
396 | |
397 | /* Return true iff there is a COND_EXPR between us and the innermost |
398 | CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */ |
399 | |
400 | static bool |
401 | gimple_conditional_context (void) |
402 | { |
403 | return gimplify_ctxp->conditions > 0; |
404 | } |
405 | |
406 | /* Note that we've entered a COND_EXPR. */ |
407 | |
408 | static void |
409 | gimple_push_condition (void) |
410 | { |
411 | #ifdef ENABLE_GIMPLE_CHECKING1 |
412 | if (gimplify_ctxp->conditions == 0) |
413 | gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups))((void)(!(gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups )) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 413, __FUNCTION__), 0 : 0)); |
414 | #endif |
415 | ++(gimplify_ctxp->conditions); |
416 | } |
417 | |
418 | /* Note that we've left a COND_EXPR. If we're back at unconditional scope |
419 | now, add any conditional cleanups we've seen to the prequeue. */ |
420 | |
421 | static void |
422 | gimple_pop_condition (gimple_seq *pre_p) |
423 | { |
424 | int conds = --(gimplify_ctxp->conditions); |
425 | |
426 | gcc_assert (conds >= 0)((void)(!(conds >= 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 426, __FUNCTION__), 0 : 0)); |
427 | if (conds == 0) |
428 | { |
429 | gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups); |
430 | gimplify_ctxp->conditional_cleanups = NULLnullptr; |
431 | } |
432 | } |
433 | |
434 | /* A stable comparison routine for use with splay trees and DECLs. */ |
435 | |
436 | static int |
437 | splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb) |
438 | { |
439 | tree a = (tree) xa; |
440 | tree b = (tree) xb; |
441 | |
442 | return DECL_UID (a)((contains_struct_check ((a), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 442, __FUNCTION__))->decl_minimal.uid) - DECL_UID (b)((contains_struct_check ((b), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 442, __FUNCTION__))->decl_minimal.uid); |
443 | } |
444 | |
445 | /* Create a new omp construct that deals with variable remapping. */ |
446 | |
447 | static struct gimplify_omp_ctx * |
448 | new_omp_context (enum omp_region_type region_type) |
449 | { |
450 | struct gimplify_omp_ctx *c; |
451 | |
452 | c = XCNEW (struct gimplify_omp_ctx)((struct gimplify_omp_ctx *) xcalloc (1, sizeof (struct gimplify_omp_ctx ))); |
453 | c->outer_context = gimplify_omp_ctxp; |
454 | c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0); |
455 | c->privatized_types = new hash_set<tree>; |
456 | c->location = input_location; |
457 | c->region_type = region_type; |
458 | if ((region_type & ORT_TASK) == 0) |
459 | c->default_kind = OMP_CLAUSE_DEFAULT_SHARED; |
460 | else |
461 | c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED; |
462 | c->defaultmap[GDMK_SCALAR] = GOVD_MAP; |
463 | c->defaultmap[GDMK_SCALAR_TARGET] = GOVD_MAP; |
464 | c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP; |
465 | c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP; |
466 | c->defaultmap[GDMK_POINTER] = GOVD_MAP; |
467 | |
468 | return c; |
469 | } |
470 | |
471 | /* Destroy an omp construct that deals with variable remapping. */ |
472 | |
473 | static void |
474 | delete_omp_context (struct gimplify_omp_ctx *c) |
475 | { |
476 | splay_tree_delete (c->variables); |
477 | delete c->privatized_types; |
478 | c->loop_iter_var.release (); |
479 | XDELETE (c)free ((void*) (c)); |
480 | } |
481 | |
482 | static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int); |
483 | static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool); |
484 | |
485 | /* Both gimplify the statement T and append it to *SEQ_P. This function |
486 | behaves exactly as gimplify_stmt, but you don't have to pass T as a |
487 | reference. */ |
488 | |
489 | void |
490 | gimplify_and_add (tree t, gimple_seq *seq_p) |
491 | { |
492 | gimplify_stmt (&t, seq_p); |
493 | } |
494 | |
495 | /* Gimplify statement T into sequence *SEQ_P, and return the first |
496 | tuple in the sequence of generated tuples for this statement. |
497 | Return NULL if gimplifying T produced no tuples. */ |
498 | |
499 | static gimple * |
500 | gimplify_and_return_first (tree t, gimple_seq *seq_p) |
501 | { |
502 | gimple_stmt_iterator last = gsi_last (*seq_p); |
503 | |
504 | gimplify_and_add (t, seq_p); |
505 | |
506 | if (!gsi_end_p (last)) |
507 | { |
508 | gsi_next (&last); |
509 | return gsi_stmt (last); |
510 | } |
511 | else |
512 | return gimple_seq_first_stmt (*seq_p); |
513 | } |
514 | |
515 | /* Returns true iff T is a valid RHS for an assignment to an un-renamed |
516 | LHS, or for a call argument. */ |
517 | |
518 | static bool |
519 | is_gimple_mem_rhs (tree t) |
520 | { |
521 | /* If we're dealing with a renamable type, either source or dest must be |
522 | a renamed variable. */ |
523 | if (is_gimple_reg_type (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 523, __FUNCTION__))->typed.type))) |
524 | return is_gimple_val (t); |
525 | else |
526 | return is_gimple_val (t) || is_gimple_lvalue (t); |
527 | } |
528 | |
529 | /* Return true if T is a CALL_EXPR or an expression that can be |
530 | assigned to a temporary. Note that this predicate should only be |
531 | used during gimplification. See the rationale for this in |
532 | gimplify_modify_expr. */ |
533 | |
534 | static bool |
535 | is_gimple_reg_rhs_or_call (tree t) |
536 | { |
537 | return (get_gimple_rhs_class (TREE_CODE (t)((enum tree_code) (t)->base.code)) != GIMPLE_INVALID_RHS |
538 | || TREE_CODE (t)((enum tree_code) (t)->base.code) == CALL_EXPR); |
539 | } |
540 | |
541 | /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that |
542 | this predicate should only be used during gimplification. See the |
543 | rationale for this in gimplify_modify_expr. */ |
544 | |
545 | static bool |
546 | is_gimple_mem_rhs_or_call (tree t) |
547 | { |
548 | /* If we're dealing with a renamable type, either source or dest must be |
549 | a renamed variable. */ |
550 | if (is_gimple_reg_type (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 550, __FUNCTION__))->typed.type))) |
551 | return is_gimple_val (t); |
552 | else |
553 | return (is_gimple_val (t) |
554 | || is_gimple_lvalue (t) |
555 | || TREE_CLOBBER_P (t)(((enum tree_code) (t)->base.code) == CONSTRUCTOR && ((t)->base.volatile_flag)) |
556 | || TREE_CODE (t)((enum tree_code) (t)->base.code) == CALL_EXPR); |
557 | } |
558 | |
559 | /* Create a temporary with a name derived from VAL. Subroutine of |
560 | lookup_tmp_var; nobody else should call this function. */ |
561 | |
562 | static inline tree |
563 | create_tmp_from_val (tree val) |
564 | { |
565 | /* Drop all qualifiers and address-space information from the value type. */ |
566 | tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val))((tree_class_check ((((contains_struct_check ((val), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 566, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 566, __FUNCTION__))->type_common.main_variant); |
567 | tree var = create_tmp_var (type, get_name (val)); |
568 | return var; |
569 | } |
570 | |
571 | /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse |
572 | an existing expression temporary. If NOT_GIMPLE_REG, mark it as such. */ |
573 | |
574 | static tree |
575 | lookup_tmp_var (tree val, bool is_formal, bool not_gimple_reg) |
576 | { |
577 | tree ret; |
578 | |
579 | /* We cannot mark a formal temporary with DECL_NOT_GIMPLE_REG_P. */ |
580 | gcc_assert (!is_formal || !not_gimple_reg)((void)(!(!is_formal || !not_gimple_reg) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 580, __FUNCTION__), 0 : 0)); |
581 | |
582 | /* If not optimizing, never really reuse a temporary. local-alloc |
583 | won't allocate any variable that is used in more than one basic |
584 | block, which means it will go into memory, causing much extra |
585 | work in reload and final and poorer code generation, outweighing |
586 | the extra memory allocation here. */ |
587 | if (!optimizeglobal_options.x_optimize || !is_formal || TREE_SIDE_EFFECTS (val)((non_type_check ((val), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 587, __FUNCTION__))->base.side_effects_flag)) |
588 | { |
589 | ret = create_tmp_from_val (val); |
590 | DECL_NOT_GIMPLE_REG_P (ret)(contains_struct_check ((ret), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 590, __FUNCTION__))->decl_common.not_gimple_reg_flag = not_gimple_reg; |
591 | } |
592 | else |
593 | { |
594 | elt_t elt, *elt_p; |
595 | elt_t **slot; |
596 | |
597 | elt.val = val; |
598 | if (!gimplify_ctxp->temp_htab) |
599 | gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000); |
600 | slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT); |
601 | if (*slot == NULLnullptr) |
602 | { |
603 | elt_p = XNEW (elt_t)((elt_t *) xmalloc (sizeof (elt_t))); |
604 | elt_p->val = val; |
605 | elt_p->temp = ret = create_tmp_from_val (val); |
606 | *slot = elt_p; |
607 | } |
608 | else |
609 | { |
610 | elt_p = *slot; |
611 | ret = elt_p->temp; |
612 | } |
613 | } |
614 | |
615 | return ret; |
616 | } |
617 | |
618 | /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */ |
619 | |
620 | static tree |
621 | internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p, |
622 | bool is_formal, bool allow_ssa, bool not_gimple_reg) |
623 | { |
624 | tree t, mod; |
625 | |
626 | /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we |
627 | can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */ |
628 | gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call, |
629 | fb_rvalue); |
630 | |
631 | if (allow_ssa |
632 | && gimplify_ctxp->into_ssa |
633 | && is_gimple_reg_type (TREE_TYPE (val)((contains_struct_check ((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 633, __FUNCTION__))->typed.type))) |
634 | { |
635 | t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val))((tree_class_check ((((contains_struct_check ((val), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 635, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 635, __FUNCTION__))->type_common.main_variant)); |
636 | if (! gimple_in_ssa_p (cfun(cfun + 0))) |
637 | { |
638 | const char *name = get_name (val); |
639 | if (name) |
640 | SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name))do { tree var_ = (create_tmp_var_name (name)); (tree_check (( t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 640, __FUNCTION__, (SSA_NAME)))->ssa_name.var = var_; (tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 640, __FUNCTION__, (SSA_NAME)))->base.public_flag = (var_ && ((enum tree_code) (var_)->base.code) == VAR_DECL && ((tree_check ((var_), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 640, __FUNCTION__, (VAR_DECL)))->base.u.bits.saturating_flag )); } while (0); |
641 | } |
642 | } |
643 | else |
644 | t = lookup_tmp_var (val, is_formal, not_gimple_reg); |
645 | |
646 | mod = build2 (INIT_EXPR, TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 646, __FUNCTION__))->typed.type), t, unshare_expr (val)); |
647 | |
648 | SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location))(expr_check (((mod)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 648, __FUNCTION__))->exp.locus = (((((IS_ADHOC_LOC ((((( val)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((val))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((val))->base.code))]) <= tcc_expression )) ? (val)->exp.locus : ((location_t) 0)))) ? get_location_from_adhoc_loc (line_table, ((((val)) && ((tree_code_type_tmpl < 0>::tree_code_type[(int) (((enum tree_code) ((val))->base .code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((val))-> base.code))]) <= tcc_expression)) ? (val)->exp.locus : ( (location_t) 0))) : (((((val)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((val))-> base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((val))-> base.code))]) <= tcc_expression)) ? (val)->exp.locus : ( (location_t) 0)))) != ((location_t) 0)) ? (val)->exp.locus : (input_location))); |
649 | |
650 | /* gimplify_modify_expr might want to reduce this further. */ |
651 | gimplify_and_add (mod, pre_p); |
652 | ggc_free (mod); |
653 | |
654 | return t; |
655 | } |
656 | |
657 | /* Return a formal temporary variable initialized with VAL. PRE_P is as |
658 | in gimplify_expr. Only use this function if: |
659 | |
660 | 1) The value of the unfactored expression represented by VAL will not |
661 | change between the initialization and use of the temporary, and |
662 | 2) The temporary will not be otherwise modified. |
663 | |
664 | For instance, #1 means that this is inappropriate for SAVE_EXPR temps, |
665 | and #2 means it is inappropriate for && temps. |
666 | |
667 | For other cases, use get_initialized_tmp_var instead. */ |
668 | |
669 | tree |
670 | get_formal_tmp_var (tree val, gimple_seq *pre_p) |
671 | { |
672 | return internal_get_tmp_var (val, pre_p, NULLnullptr, true, true, false); |
673 | } |
674 | |
675 | /* Return a temporary variable initialized with VAL. PRE_P and POST_P |
676 | are as in gimplify_expr. */ |
677 | |
678 | tree |
679 | get_initialized_tmp_var (tree val, gimple_seq *pre_p, |
680 | gimple_seq *post_p /* = NULL */, |
681 | bool allow_ssa /* = true */) |
682 | { |
683 | return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa, false); |
684 | } |
685 | |
686 | /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true, |
687 | generate debug info for them; otherwise don't. */ |
688 | |
689 | void |
690 | declare_vars (tree vars, gimple *gs, bool debug_info) |
691 | { |
692 | tree last = vars; |
693 | if (last) |
694 | { |
695 | tree temps, block; |
696 | |
697 | gbind *scope = as_a <gbind *> (gs); |
698 | |
699 | temps = nreverse (last); |
700 | |
701 | block = gimple_bind_block (scope); |
702 | gcc_assert (!block || TREE_CODE (block) == BLOCK)((void)(!(!block || ((enum tree_code) (block)->base.code) == BLOCK) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 702, __FUNCTION__), 0 : 0)); |
703 | if (!block || !debug_info) |
704 | { |
705 | DECL_CHAIN (last)(((contains_struct_check (((contains_struct_check ((last), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 705, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 705, __FUNCTION__))->common.chain)) = gimple_bind_vars (scope); |
706 | gimple_bind_set_vars (scope, temps); |
707 | } |
708 | else |
709 | { |
710 | /* We need to attach the nodes both to the BIND_EXPR and to its |
711 | associated BLOCK for debugging purposes. The key point here |
712 | is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR |
713 | is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */ |
714 | if (BLOCK_VARS (block)((tree_check ((block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 714, __FUNCTION__, (BLOCK)))->block.vars)) |
715 | BLOCK_VARS (block)((tree_check ((block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 715, __FUNCTION__, (BLOCK)))->block.vars) = chainon (BLOCK_VARS (block)((tree_check ((block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 715, __FUNCTION__, (BLOCK)))->block.vars), temps); |
716 | else |
717 | { |
718 | gimple_bind_set_vars (scope, |
719 | chainon (gimple_bind_vars (scope), temps)); |
720 | BLOCK_VARS (block)((tree_check ((block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 720, __FUNCTION__, (BLOCK)))->block.vars) = temps; |
721 | } |
722 | } |
723 | } |
724 | } |
725 | |
726 | /* For VAR a VAR_DECL of variable size, try to find a constant upper bound |
727 | for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if |
728 | no such upper bound can be obtained. */ |
729 | |
730 | static void |
731 | force_constant_size (tree var) |
732 | { |
733 | /* The only attempt we make is by querying the maximum size of objects |
734 | of the variable's type. */ |
735 | |
736 | HOST_WIDE_INTlong max_size; |
737 | |
738 | gcc_assert (VAR_P (var))((void)(!((((enum tree_code) (var)->base.code) == VAR_DECL )) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 738, __FUNCTION__), 0 : 0)); |
739 | |
740 | max_size = max_int_size_in_bytes (TREE_TYPE (var)((contains_struct_check ((var), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 740, __FUNCTION__))->typed.type)); |
741 | |
742 | gcc_assert (max_size >= 0)((void)(!(max_size >= 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 742, __FUNCTION__), 0 : 0)); |
743 | |
744 | DECL_SIZE_UNIT (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 744, __FUNCTION__))->decl_common.size_unit) |
745 | = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var))((contains_struct_check ((((contains_struct_check ((var), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 745, __FUNCTION__))->decl_common.size_unit)), (TS_TYPED) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 745, __FUNCTION__))->typed.type), max_size); |
746 | DECL_SIZE (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 746, __FUNCTION__))->decl_common.size) |
747 | = build_int_cst (TREE_TYPE (DECL_SIZE (var))((contains_struct_check ((((contains_struct_check ((var), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 747, __FUNCTION__))->decl_common.size)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 747, __FUNCTION__))->typed.type), max_size * BITS_PER_UNIT(8)); |
748 | } |
749 | |
750 | /* Push the temporary variable TMP into the current binding. */ |
751 | |
752 | void |
753 | gimple_add_tmp_var_fn (struct function *fn, tree tmp) |
754 | { |
755 | gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp))((void)(!(!(((contains_struct_check (((contains_struct_check ( (tmp), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 755, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 755, __FUNCTION__))->common.chain)) && !((contains_struct_check ((tmp), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 755, __FUNCTION__))->decl_with_vis.seen_in_bind_expr)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 755, __FUNCTION__), 0 : 0)); |
756 | |
757 | /* Later processing assumes that the object size is constant, which might |
758 | not be true at this point. Force the use of a constant upper bound in |
759 | this case. */ |
760 | if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)((contains_struct_check ((tmp), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 760, __FUNCTION__))->decl_common.size_unit))) |
761 | force_constant_size (tmp); |
762 | |
763 | DECL_CONTEXT (tmp)((contains_struct_check ((tmp), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 763, __FUNCTION__))->decl_minimal.context) = fn->decl; |
764 | DECL_SEEN_IN_BIND_EXPR_P (tmp)((contains_struct_check ((tmp), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 764, __FUNCTION__))->decl_with_vis.seen_in_bind_expr) = 1; |
765 | |
766 | record_vars_into (tmp, fn->decl); |
767 | } |
768 | |
769 | /* Push the temporary variable TMP into the current binding. */ |
770 | |
771 | void |
772 | gimple_add_tmp_var (tree tmp) |
773 | { |
774 | gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp))((void)(!(!(((contains_struct_check (((contains_struct_check ( (tmp), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 774, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 774, __FUNCTION__))->common.chain)) && !((contains_struct_check ((tmp), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 774, __FUNCTION__))->decl_with_vis.seen_in_bind_expr)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 774, __FUNCTION__), 0 : 0)); |
775 | |
776 | /* Later processing assumes that the object size is constant, which might |
777 | not be true at this point. Force the use of a constant upper bound in |
778 | this case. */ |
779 | if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)((contains_struct_check ((tmp), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 779, __FUNCTION__))->decl_common.size_unit))) |
780 | force_constant_size (tmp); |
781 | |
782 | DECL_CONTEXT (tmp)((contains_struct_check ((tmp), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 782, __FUNCTION__))->decl_minimal.context) = current_function_decl; |
783 | DECL_SEEN_IN_BIND_EXPR_P (tmp)((contains_struct_check ((tmp), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 783, __FUNCTION__))->decl_with_vis.seen_in_bind_expr) = 1; |
784 | |
785 | if (gimplify_ctxp) |
786 | { |
787 | DECL_CHAIN (tmp)(((contains_struct_check (((contains_struct_check ((tmp), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 787, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 787, __FUNCTION__))->common.chain)) = gimplify_ctxp->temps; |
788 | gimplify_ctxp->temps = tmp; |
789 | |
790 | /* Mark temporaries local within the nearest enclosing parallel. */ |
791 | if (gimplify_omp_ctxp) |
792 | { |
793 | struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; |
794 | int flag = GOVD_LOCAL | GOVD_SEEN; |
795 | while (ctx |
796 | && (ctx->region_type == ORT_WORKSHARE |
797 | || ctx->region_type == ORT_TASKGROUP |
798 | || ctx->region_type == ORT_SIMD |
799 | || ctx->region_type == ORT_ACC)) |
800 | { |
801 | if (ctx->region_type == ORT_SIMD |
802 | && TREE_ADDRESSABLE (tmp)((tmp)->base.addressable_flag) |
803 | && !TREE_STATIC (tmp)((tmp)->base.static_flag)) |
804 | { |
805 | if (TREE_CODE (DECL_SIZE_UNIT (tmp))((enum tree_code) (((contains_struct_check ((tmp), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 805, __FUNCTION__))->decl_common.size_unit))->base.code ) != INTEGER_CST) |
806 | ctx->add_safelen1 = true; |
807 | else if (ctx->in_for_exprs) |
808 | flag = GOVD_PRIVATE; |
809 | else |
810 | flag = GOVD_PRIVATE | GOVD_SEEN; |
811 | break; |
812 | } |
813 | ctx = ctx->outer_context; |
814 | } |
815 | if (ctx) |
816 | omp_add_variable (ctx, tmp, flag); |
817 | } |
818 | } |
819 | else if (cfun(cfun + 0)) |
820 | record_vars (tmp); |
821 | else |
822 | { |
823 | gimple_seq body_seq; |
824 | |
825 | /* This case is for nested functions. We need to expose the locals |
826 | they create. */ |
827 | body_seq = gimple_body (current_function_decl); |
828 | declare_vars (tmp, gimple_seq_first_stmt (body_seq), false); |
829 | } |
830 | } |
831 | |
832 | |
833 | |
834 | /* This page contains routines to unshare tree nodes, i.e. to duplicate tree |
835 | nodes that are referenced more than once in GENERIC functions. This is |
836 | necessary because gimplification (translation into GIMPLE) is performed |
837 | by modifying tree nodes in-place, so gimplication of a shared node in a |
838 | first context could generate an invalid GIMPLE form in a second context. |
839 | |
840 | This is achieved with a simple mark/copy/unmark algorithm that walks the |
841 | GENERIC representation top-down, marks nodes with TREE_VISITED the first |
842 | time it encounters them, duplicates them if they already have TREE_VISITED |
843 | set, and finally removes the TREE_VISITED marks it has set. |
844 | |
845 | The algorithm works only at the function level, i.e. it generates a GENERIC |
846 | representation of a function with no nodes shared within the function when |
847 | passed a GENERIC function (except for nodes that are allowed to be shared). |
848 | |
849 | At the global level, it is also necessary to unshare tree nodes that are |
850 | referenced in more than one function, for the same aforementioned reason. |
851 | This requires some cooperation from the front-end. There are 2 strategies: |
852 | |
853 | 1. Manual unsharing. The front-end needs to call unshare_expr on every |
854 | expression that might end up being shared across functions. |
855 | |
856 | 2. Deep unsharing. This is an extension of regular unsharing. Instead |
857 | of calling unshare_expr on expressions that might be shared across |
858 | functions, the front-end pre-marks them with TREE_VISITED. This will |
859 | ensure that they are unshared on the first reference within functions |
860 | when the regular unsharing algorithm runs. The counterpart is that |
861 | this algorithm must look deeper than for manual unsharing, which is |
862 | specified by LANG_HOOKS_DEEP_UNSHARING. |
863 | |
864 | If there are only few specific cases of node sharing across functions, it is |
865 | probably easier for a front-end to unshare the expressions manually. On the |
866 | contrary, if the expressions generated at the global level are as widespread |
867 | as expressions generated within functions, deep unsharing is very likely the |
868 | way to go. */ |
869 | |
870 | /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes. |
871 | These nodes model computations that must be done once. If we were to |
872 | unshare something like SAVE_EXPR(i++), the gimplification process would |
873 | create wrong code. However, if DATA is non-null, it must hold a pointer |
874 | set that is used to unshare the subtrees of these nodes. */ |
875 | |
876 | static tree |
877 | mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data) |
878 | { |
879 | tree t = *tp; |
880 | enum tree_code code = TREE_CODE (t)((enum tree_code) (t)->base.code); |
881 | |
882 | /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but |
883 | copy their subtrees if we can make sure to do it only once. */ |
884 | if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR) |
885 | { |
886 | if (data && !((hash_set<tree> *)data)->add (t)) |
887 | ; |
888 | else |
889 | *walk_subtrees = 0; |
890 | } |
891 | |
892 | /* Stop at types, decls, constants like copy_tree_r. */ |
893 | else if (TREE_CODE_CLASS (code)tree_code_type_tmpl <0>::tree_code_type[(int) (code)] == tcc_type |
894 | || TREE_CODE_CLASS (code)tree_code_type_tmpl <0>::tree_code_type[(int) (code)] == tcc_declaration |
895 | || TREE_CODE_CLASS (code)tree_code_type_tmpl <0>::tree_code_type[(int) (code)] == tcc_constant) |
896 | *walk_subtrees = 0; |
897 | |
898 | /* Cope with the statement expression extension. */ |
899 | else if (code == STATEMENT_LIST) |
900 | ; |
901 | |
902 | /* Leave the bulk of the work to copy_tree_r itself. */ |
903 | else |
904 | copy_tree_r (tp, walk_subtrees, NULLnullptr); |
905 | |
906 | return NULL_TREE(tree) nullptr; |
907 | } |
908 | |
909 | /* Callback for walk_tree to unshare most of the shared trees rooted at *TP. |
910 | If *TP has been visited already, then *TP is deeply copied by calling |
911 | mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */ |
912 | |
913 | static tree |
914 | copy_if_shared_r (tree *tp, int *walk_subtrees, void *data) |
915 | { |
916 | tree t = *tp; |
917 | enum tree_code code = TREE_CODE (t)((enum tree_code) (t)->base.code); |
918 | |
919 | /* Skip types, decls, and constants. But we do want to look at their |
920 | types and the bounds of types. Mark them as visited so we properly |
921 | unmark their subtrees on the unmark pass. If we've already seen them, |
922 | don't look down further. */ |
923 | if (TREE_CODE_CLASS (code)tree_code_type_tmpl <0>::tree_code_type[(int) (code)] == tcc_type |
924 | || TREE_CODE_CLASS (code)tree_code_type_tmpl <0>::tree_code_type[(int) (code)] == tcc_declaration |
925 | || TREE_CODE_CLASS (code)tree_code_type_tmpl <0>::tree_code_type[(int) (code)] == tcc_constant) |
926 | { |
927 | if (TREE_VISITED (t)((t)->base.visited)) |
928 | *walk_subtrees = 0; |
929 | else |
930 | TREE_VISITED (t)((t)->base.visited) = 1; |
931 | } |
932 | |
933 | /* If this node has been visited already, unshare it and don't look |
934 | any deeper. */ |
935 | else if (TREE_VISITED (t)((t)->base.visited)) |
936 | { |
937 | walk_tree (tp, mostly_copy_tree_r, data, NULL)walk_tree_1 (tp, mostly_copy_tree_r, data, nullptr, nullptr); |
938 | *walk_subtrees = 0; |
939 | } |
940 | |
941 | /* Otherwise, mark the node as visited and keep looking. */ |
942 | else |
943 | TREE_VISITED (t)((t)->base.visited) = 1; |
944 | |
945 | return NULL_TREE(tree) nullptr; |
946 | } |
947 | |
948 | /* Unshare most of the shared trees rooted at *TP. DATA is passed to the |
949 | copy_if_shared_r callback unmodified. */ |
950 | |
951 | void |
952 | copy_if_shared (tree *tp, void *data) |
953 | { |
954 | walk_tree (tp, copy_if_shared_r, data, NULL)walk_tree_1 (tp, copy_if_shared_r, data, nullptr, nullptr); |
955 | } |
956 | |
957 | /* Unshare all the trees in the body of FNDECL, as well as in the bodies of |
958 | any nested functions. */ |
959 | |
960 | static void |
961 | unshare_body (tree fndecl) |
962 | { |
963 | struct cgraph_node *cgn = cgraph_node::get (fndecl); |
964 | /* If the language requires deep unsharing, we need a pointer set to make |
965 | sure we don't repeatedly unshare subtrees of unshareable nodes. */ |
966 | hash_set<tree> *visited |
967 | = lang_hooks.deep_unsharing ? new hash_set<tree> : NULLnullptr; |
968 | |
969 | copy_if_shared (&DECL_SAVED_TREE (fndecl)((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 969, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree ), visited); |
970 | copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl))((contains_struct_check ((((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 970, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result )), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 970, __FUNCTION__))->decl_common.size), visited); |
971 | copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl))((contains_struct_check ((((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 971, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result )), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 971, __FUNCTION__))->decl_common.size_unit), visited); |
972 | |
973 | delete visited; |
974 | |
975 | if (cgn) |
976 | for (cgn = first_nested_function (cgn); cgn; |
977 | cgn = next_nested_function (cgn)) |
978 | unshare_body (cgn->decl); |
979 | } |
980 | |
981 | /* Callback for walk_tree to unmark the visited trees rooted at *TP. |
982 | Subtrees are walked until the first unvisited node is encountered. */ |
983 | |
984 | static tree |
985 | unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED__attribute__ ((__unused__))) |
986 | { |
987 | tree t = *tp; |
988 | |
989 | /* If this node has been visited, unmark it and keep looking. */ |
990 | if (TREE_VISITED (t)((t)->base.visited)) |
991 | TREE_VISITED (t)((t)->base.visited) = 0; |
992 | |
993 | /* Otherwise, don't look any deeper. */ |
994 | else |
995 | *walk_subtrees = 0; |
996 | |
997 | return NULL_TREE(tree) nullptr; |
998 | } |
999 | |
1000 | /* Unmark the visited trees rooted at *TP. */ |
1001 | |
1002 | static inline void |
1003 | unmark_visited (tree *tp) |
1004 | { |
1005 | walk_tree (tp, unmark_visited_r, NULL, NULL)walk_tree_1 (tp, unmark_visited_r, nullptr, nullptr, nullptr); |
1006 | } |
1007 | |
1008 | /* Likewise, but mark all trees as not visited. */ |
1009 | |
1010 | static void |
1011 | unvisit_body (tree fndecl) |
1012 | { |
1013 | struct cgraph_node *cgn = cgraph_node::get (fndecl); |
1014 | |
1015 | unmark_visited (&DECL_SAVED_TREE (fndecl)((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1015, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree )); |
1016 | unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl))((contains_struct_check ((((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1016, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result )), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1016, __FUNCTION__))->decl_common.size)); |
1017 | unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl))((contains_struct_check ((((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1017, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result )), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1017, __FUNCTION__))->decl_common.size_unit)); |
1018 | |
1019 | if (cgn) |
1020 | for (cgn = first_nested_function (cgn); |
1021 | cgn; cgn = next_nested_function (cgn)) |
1022 | unvisit_body (cgn->decl); |
1023 | } |
1024 | |
1025 | /* Unconditionally make an unshared copy of EXPR. This is used when using |
1026 | stored expressions which span multiple functions, such as BINFO_VTABLE, |
1027 | as the normal unsharing process can't tell that they're shared. */ |
1028 | |
1029 | tree |
1030 | unshare_expr (tree expr) |
1031 | { |
1032 | walk_tree (&expr, mostly_copy_tree_r, NULL, NULL)walk_tree_1 (&expr, mostly_copy_tree_r, nullptr, nullptr, nullptr); |
1033 | return expr; |
1034 | } |
1035 | |
1036 | /* Worker for unshare_expr_without_location. */ |
1037 | |
1038 | static tree |
1039 | prune_expr_location (tree *tp, int *walk_subtrees, void *) |
1040 | { |
1041 | if (EXPR_P (*tp)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (*tp)->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (*tp)->base.code))]) <= tcc_expression)) |
1042 | SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION)(expr_check (((*tp)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1042, __FUNCTION__))->exp.locus = (((location_t) 0)); |
1043 | else |
1044 | *walk_subtrees = 0; |
1045 | return NULL_TREE(tree) nullptr; |
1046 | } |
1047 | |
1048 | /* Similar to unshare_expr but also prune all expression locations |
1049 | from EXPR. */ |
1050 | |
1051 | tree |
1052 | unshare_expr_without_location (tree expr) |
1053 | { |
1054 | walk_tree (&expr, mostly_copy_tree_r, NULL, NULL)walk_tree_1 (&expr, mostly_copy_tree_r, nullptr, nullptr, nullptr); |
1055 | if (EXPR_P (expr)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (expr)->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (expr)->base.code))]) <= tcc_expression)) |
1056 | walk_tree (&expr, prune_expr_location, NULL, NULL)walk_tree_1 (&expr, prune_expr_location, nullptr, nullptr , nullptr); |
1057 | return expr; |
1058 | } |
1059 | |
1060 | /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has |
1061 | one, OR_ELSE otherwise. The location of a STATEMENT_LISTs |
1062 | comprising at least one DEBUG_BEGIN_STMT followed by exactly one |
1063 | EXPR is the location of the EXPR. */ |
1064 | |
1065 | static location_t |
1066 | rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION((location_t) 0)) |
1067 | { |
1068 | if (!expr) |
1069 | return or_else; |
1070 | |
1071 | if (EXPR_HAS_LOCATION (expr)(((IS_ADHOC_LOC (((((expr)) && ((tree_code_type_tmpl < 0>::tree_code_type[(int) (((enum tree_code) ((expr))->base .code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))-> base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) ? get_location_from_adhoc_loc (line_table , ((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression )) ? (expr)->exp.locus : ((location_t) 0))) : (((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) != ((location_t ) 0))) |
1072 | return EXPR_LOCATION (expr)((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression )) ? (expr)->exp.locus : ((location_t) 0)); |
1073 | |
1074 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) != STATEMENT_LIST) |
1075 | return or_else; |
1076 | |
1077 | tree_stmt_iterator i = tsi_start (expr); |
1078 | |
1079 | bool found = false; |
1080 | while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i))((enum tree_code) (tsi_stmt (i))->base.code) == DEBUG_BEGIN_STMT) |
1081 | { |
1082 | found = true; |
1083 | tsi_next (&i); |
1084 | } |
1085 | |
1086 | if (!found || !tsi_one_before_end_p (i)) |
1087 | return or_else; |
1088 | |
1089 | return rexpr_location (tsi_stmt (i), or_else); |
1090 | } |
1091 | |
1092 | /* Return TRUE iff EXPR (maybe recursively) has a location; see |
1093 | rexpr_location for the potential recursion. */ |
1094 | |
1095 | static inline bool |
1096 | rexpr_has_location (tree expr) |
1097 | { |
1098 | return rexpr_location (expr) != UNKNOWN_LOCATION((location_t) 0); |
1099 | } |
1100 | |
1101 | |
1102 | /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both |
1103 | contain statements and have a value. Assign its value to a temporary |
1104 | and give it void_type_node. Return the temporary, or NULL_TREE if |
1105 | WRAPPER was already void. */ |
1106 | |
1107 | tree |
1108 | voidify_wrapper_expr (tree wrapper, tree temp) |
1109 | { |
1110 | tree type = TREE_TYPE (wrapper)((contains_struct_check ((wrapper), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1110, __FUNCTION__))->typed.type); |
1111 | if (type && !VOID_TYPE_P (type)(((enum tree_code) (type)->base.code) == VOID_TYPE)) |
1112 | { |
1113 | tree *p; |
1114 | |
1115 | /* Set p to point to the body of the wrapper. Loop until we find |
1116 | something that isn't a wrapper. */ |
1117 | for (p = &wrapper; p && *p; ) |
1118 | { |
1119 | switch (TREE_CODE (*p)((enum tree_code) (*p)->base.code)) |
1120 | { |
1121 | case BIND_EXPR: |
1122 | TREE_SIDE_EFFECTS (*p)((non_type_check ((*p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1122, __FUNCTION__))->base.side_effects_flag) = 1; |
1123 | TREE_TYPE (*p)((contains_struct_check ((*p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1123, __FUNCTION__))->typed.type) = void_type_nodeglobal_trees[TI_VOID_TYPE]; |
1124 | /* For a BIND_EXPR, the body is operand 1. */ |
1125 | p = &BIND_EXPR_BODY (*p)((*((const_cast<tree*> (tree_operand_check (((tree_check ((*p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1125, __FUNCTION__, (BIND_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1125, __FUNCTION__)))))); |
1126 | break; |
1127 | |
1128 | case CLEANUP_POINT_EXPR: |
1129 | case TRY_FINALLY_EXPR: |
1130 | case TRY_CATCH_EXPR: |
1131 | TREE_SIDE_EFFECTS (*p)((non_type_check ((*p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1131, __FUNCTION__))->base.side_effects_flag) = 1; |
1132 | TREE_TYPE (*p)((contains_struct_check ((*p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1132, __FUNCTION__))->typed.type) = void_type_nodeglobal_trees[TI_VOID_TYPE]; |
1133 | p = &TREE_OPERAND (*p, 0)(*((const_cast<tree*> (tree_operand_check ((*p), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1133, __FUNCTION__))))); |
1134 | break; |
1135 | |
1136 | case STATEMENT_LIST: |
1137 | { |
1138 | tree_stmt_iterator i = tsi_last (*p); |
1139 | TREE_SIDE_EFFECTS (*p)((non_type_check ((*p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1139, __FUNCTION__))->base.side_effects_flag) = 1; |
1140 | TREE_TYPE (*p)((contains_struct_check ((*p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1140, __FUNCTION__))->typed.type) = void_type_nodeglobal_trees[TI_VOID_TYPE]; |
1141 | p = tsi_end_p (i) ? NULLnullptr : tsi_stmt_ptr (i); |
1142 | } |
1143 | break; |
1144 | |
1145 | case COMPOUND_EXPR: |
1146 | /* Advance to the last statement. Set all container types to |
1147 | void. */ |
1148 | for (; TREE_CODE (*p)((enum tree_code) (*p)->base.code) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1)(*((const_cast<tree*> (tree_operand_check ((*p), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1148, __FUNCTION__)))))) |
1149 | { |
1150 | TREE_SIDE_EFFECTS (*p)((non_type_check ((*p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1150, __FUNCTION__))->base.side_effects_flag) = 1; |
1151 | TREE_TYPE (*p)((contains_struct_check ((*p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1151, __FUNCTION__))->typed.type) = void_type_nodeglobal_trees[TI_VOID_TYPE]; |
1152 | } |
1153 | break; |
1154 | |
1155 | case TRANSACTION_EXPR: |
1156 | TREE_SIDE_EFFECTS (*p)((non_type_check ((*p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1156, __FUNCTION__))->base.side_effects_flag) = 1; |
1157 | TREE_TYPE (*p)((contains_struct_check ((*p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1157, __FUNCTION__))->typed.type) = void_type_nodeglobal_trees[TI_VOID_TYPE]; |
1158 | p = &TRANSACTION_EXPR_BODY (*p)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1158, __FUNCTION__, (TRANSACTION_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1158, __FUNCTION__))))); |
1159 | break; |
1160 | |
1161 | default: |
1162 | /* Assume that any tree upon which voidify_wrapper_expr is |
1163 | directly called is a wrapper, and that its body is op0. */ |
1164 | if (p == &wrapper) |
1165 | { |
1166 | TREE_SIDE_EFFECTS (*p)((non_type_check ((*p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1166, __FUNCTION__))->base.side_effects_flag) = 1; |
1167 | TREE_TYPE (*p)((contains_struct_check ((*p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1167, __FUNCTION__))->typed.type) = void_type_nodeglobal_trees[TI_VOID_TYPE]; |
1168 | p = &TREE_OPERAND (*p, 0)(*((const_cast<tree*> (tree_operand_check ((*p), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1168, __FUNCTION__))))); |
1169 | break; |
1170 | } |
1171 | goto out; |
1172 | } |
1173 | } |
1174 | |
1175 | out: |
1176 | if (p == NULLnullptr || IS_EMPTY_STMT (*p)(((enum tree_code) (*p)->base.code) == NOP_EXPR && (((enum tree_code) (((contains_struct_check ((*p), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1176, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE ) && integer_zerop ((*((const_cast<tree*> (tree_operand_check ((*p), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1176, __FUNCTION__)))))))) |
1177 | temp = NULL_TREE(tree) nullptr; |
1178 | else if (temp) |
1179 | { |
1180 | /* The wrapper is on the RHS of an assignment that we're pushing |
1181 | down. */ |
1182 | gcc_assert (TREE_CODE (temp) == INIT_EXPR((void)(!(((enum tree_code) (temp)->base.code) == INIT_EXPR || ((enum tree_code) (temp)->base.code) == MODIFY_EXPR) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1183, __FUNCTION__), 0 : 0)) |
1183 | || TREE_CODE (temp) == MODIFY_EXPR)((void)(!(((enum tree_code) (temp)->base.code) == INIT_EXPR || ((enum tree_code) (temp)->base.code) == MODIFY_EXPR) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1183, __FUNCTION__), 0 : 0)); |
1184 | TREE_OPERAND (temp, 1)(*((const_cast<tree*> (tree_operand_check ((temp), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1184, __FUNCTION__))))) = *p; |
1185 | *p = temp; |
1186 | } |
1187 | else |
1188 | { |
1189 | temp = create_tmp_var (type, "retval"); |
1190 | *p = build2 (INIT_EXPR, type, temp, *p); |
1191 | } |
1192 | |
1193 | return temp; |
1194 | } |
1195 | |
1196 | return NULL_TREE(tree) nullptr; |
1197 | } |
1198 | |
1199 | /* Prepare calls to builtins to SAVE and RESTORE the stack as well as |
1200 | a temporary through which they communicate. */ |
1201 | |
1202 | static void |
1203 | build_stack_save_restore (gcall **save, gcall **restore) |
1204 | { |
1205 | tree tmp_var; |
1206 | |
1207 | *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0); |
1208 | tmp_var = create_tmp_var (ptr_type_nodeglobal_trees[TI_PTR_TYPE], "saved_stack"); |
1209 | gimple_call_set_lhs (*save, tmp_var); |
1210 | |
1211 | *restore |
1212 | = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE), |
1213 | 1, tmp_var); |
1214 | } |
1215 | |
1216 | /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */ |
1217 | |
1218 | static tree |
1219 | build_asan_poison_call_expr (tree decl) |
1220 | { |
1221 | /* Do not poison variables that have size equal to zero. */ |
1222 | tree unit_size = DECL_SIZE_UNIT (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1222, __FUNCTION__))->decl_common.size_unit); |
1223 | if (zerop (unit_size)) |
1224 | return NULL_TREE(tree) nullptr; |
1225 | |
1226 | tree base = build_fold_addr_expr (decl)build_fold_addr_expr_loc (((location_t) 0), (decl)); |
1227 | |
1228 | return build_call_expr_internal_loc (UNKNOWN_LOCATION((location_t) 0), IFN_ASAN_MARK, |
1229 | void_type_nodeglobal_trees[TI_VOID_TYPE], 3, |
1230 | build_int_cst (integer_type_nodeinteger_types[itk_int], |
1231 | ASAN_MARK_POISON), |
1232 | base, unit_size); |
1233 | } |
1234 | |
1235 | /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending |
1236 | on POISON flag, shadow memory of a DECL variable. The call will be |
1237 | put on location identified by IT iterator, where BEFORE flag drives |
1238 | position where the stmt will be put. */ |
1239 | |
1240 | static void |
1241 | asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it, |
1242 | bool before) |
1243 | { |
1244 | tree unit_size = DECL_SIZE_UNIT (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1244, __FUNCTION__))->decl_common.size_unit); |
1245 | tree base = build_fold_addr_expr (decl)build_fold_addr_expr_loc (((location_t) 0), (decl)); |
1246 | |
1247 | /* Do not poison variables that have size equal to zero. */ |
1248 | if (zerop (unit_size)) |
1249 | return; |
1250 | |
1251 | /* It's necessary to have all stack variables aligned to ASAN granularity |
1252 | bytes. */ |
1253 | gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ())((void)(!(!hwasan_sanitize_p () || hwasan_sanitize_stack_p () ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1253, __FUNCTION__), 0 : 0)); |
1254 | unsigned shadow_granularity |
1255 | = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZEtargetm.memtag.granule_size () : ASAN_SHADOW_GRANULARITY(1UL << 3); |
1256 | if (DECL_ALIGN_UNIT (decl)((((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1256, __FUNCTION__))->decl_common.align) ? ((unsigned)1) << (((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1256, __FUNCTION__))->decl_common.align) - 1) : 0) / (8) ) <= shadow_granularity) |
1257 | SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity)(((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1257, __FUNCTION__))->decl_common.align) = ffs_hwi ((8) * shadow_granularity)); |
1258 | |
1259 | HOST_WIDE_INTlong flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON; |
1260 | |
1261 | gimple *g |
1262 | = gimple_build_call_internal (IFN_ASAN_MARK, 3, |
1263 | build_int_cst (integer_type_nodeinteger_types[itk_int], flags), |
1264 | base, unit_size); |
1265 | |
1266 | if (before) |
1267 | gsi_insert_before (it, g, GSI_NEW_STMT); |
1268 | else |
1269 | gsi_insert_after (it, g, GSI_NEW_STMT); |
1270 | } |
1271 | |
1272 | /* Generate IFN_ASAN_MARK internal call that depending on POISON flag |
1273 | either poisons or unpoisons a DECL. Created statement is appended |
1274 | to SEQ_P gimple sequence. */ |
1275 | |
1276 | static void |
1277 | asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p) |
1278 | { |
1279 | gimple_stmt_iterator it = gsi_last (*seq_p); |
1280 | bool before = false; |
1281 | |
1282 | if (gsi_end_p (it)) |
1283 | before = true; |
1284 | |
1285 | asan_poison_variable (decl, poison, &it, before); |
1286 | } |
1287 | |
1288 | /* Sort pair of VAR_DECLs A and B by DECL_UID. */ |
1289 | |
1290 | static int |
1291 | sort_by_decl_uid (const void *a, const void *b) |
1292 | { |
1293 | const tree *t1 = (const tree *)a; |
1294 | const tree *t2 = (const tree *)b; |
1295 | |
1296 | int uid1 = DECL_UID (*t1)((contains_struct_check ((*t1), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1296, __FUNCTION__))->decl_minimal.uid); |
1297 | int uid2 = DECL_UID (*t2)((contains_struct_check ((*t2), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1297, __FUNCTION__))->decl_minimal.uid); |
1298 | |
1299 | if (uid1 < uid2) |
1300 | return -1; |
1301 | else if (uid1 > uid2) |
1302 | return 1; |
1303 | else |
1304 | return 0; |
1305 | } |
1306 | |
1307 | /* Generate IFN_ASAN_MARK internal call for all VARIABLES |
1308 | depending on POISON flag. Created statement is appended |
1309 | to SEQ_P gimple sequence. */ |
1310 | |
1311 | static void |
1312 | asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p) |
1313 | { |
1314 | unsigned c = variables->elements (); |
1315 | if (c == 0) |
1316 | return; |
1317 | |
1318 | auto_vec<tree> sorted_variables (c); |
1319 | |
1320 | for (hash_set<tree>::iterator it = variables->begin (); |
1321 | it != variables->end (); ++it) |
1322 | sorted_variables.safe_push (*it); |
1323 | |
1324 | sorted_variables.qsort (sort_by_decl_uid)qsort (sort_by_decl_uid); |
1325 | |
1326 | unsigned i; |
1327 | tree var; |
1328 | FOR_EACH_VEC_ELT (sorted_variables, i, var)for (i = 0; (sorted_variables).iterate ((i), &(var)); ++( i)) |
1329 | { |
1330 | asan_poison_variable (var, poison, seq_p); |
1331 | |
1332 | /* Add use_after_scope_memory attribute for the variable in order |
1333 | to prevent re-written into SSA. */ |
1334 | if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE"use after scope memory", |
1335 | DECL_ATTRIBUTES (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1335, __FUNCTION__))->decl_common.attributes))) |
1336 | DECL_ATTRIBUTES (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1336, __FUNCTION__))->decl_common.attributes) |
1337 | = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE)(__builtin_constant_p ("use after scope memory") ? get_identifier_with_length (("use after scope memory"), strlen ("use after scope memory" )) : get_identifier ("use after scope memory")), |
1338 | integer_one_nodeglobal_trees[TI_INTEGER_ONE], |
1339 | DECL_ATTRIBUTES (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1339, __FUNCTION__))->decl_common.attributes)); |
1340 | } |
1341 | } |
1342 | |
1343 | /* Gimplify a BIND_EXPR. Just voidify and recurse. */ |
1344 | |
1345 | static enum gimplify_status |
1346 | gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) |
1347 | { |
1348 | tree bind_expr = *expr_p; |
1349 | bool old_keep_stack = gimplify_ctxp->keep_stack; |
1350 | bool old_save_stack = gimplify_ctxp->save_stack; |
1351 | tree t; |
1352 | gbind *bind_stmt; |
1353 | gimple_seq body, cleanup; |
1354 | gcall *stack_save; |
1355 | location_t start_locus = 0, end_locus = 0; |
1356 | tree ret_clauses = NULLnullptr; |
1357 | |
1358 | tree temp = voidify_wrapper_expr (bind_expr, NULLnullptr); |
1359 | |
1360 | /* Mark variables seen in this bind expr. */ |
1361 | for (t = BIND_EXPR_VARS (bind_expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((bind_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1361, __FUNCTION__, (BIND_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1361, __FUNCTION__)))))); t ; t = DECL_CHAIN (t)(((contains_struct_check (((contains_struct_check ((t), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1361, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1361, __FUNCTION__))->common.chain))) |
1362 | { |
1363 | if (VAR_P (t)(((enum tree_code) (t)->base.code) == VAR_DECL)) |
1364 | { |
1365 | struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; |
1366 | |
1367 | /* Mark variable as local. */ |
1368 | if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t)((contains_struct_check ((t), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1368, __FUNCTION__))->decl_common.decl_flag_1)) |
1369 | { |
1370 | if (! DECL_SEEN_IN_BIND_EXPR_P (t)((contains_struct_check ((t), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1370, __FUNCTION__))->decl_with_vis.seen_in_bind_expr) |
1371 | || splay_tree_lookup (ctx->variables, |
1372 | (splay_tree_key) t) == NULLnullptr) |
1373 | { |
1374 | int flag = GOVD_LOCAL; |
1375 | if (ctx->region_type == ORT_SIMD |
1376 | && TREE_ADDRESSABLE (t)((t)->base.addressable_flag) |
1377 | && !TREE_STATIC (t)((t)->base.static_flag)) |
1378 | { |
1379 | if (TREE_CODE (DECL_SIZE_UNIT (t))((enum tree_code) (((contains_struct_check ((t), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1379, __FUNCTION__))->decl_common.size_unit))->base.code ) != INTEGER_CST) |
1380 | ctx->add_safelen1 = true; |
1381 | else |
1382 | flag = GOVD_PRIVATE; |
1383 | } |
1384 | omp_add_variable (ctx, t, flag | GOVD_SEEN); |
1385 | } |
1386 | /* Static locals inside of target construct or offloaded |
1387 | routines need to be "omp declare target". */ |
1388 | if (TREE_STATIC (t)((t)->base.static_flag)) |
1389 | for (; ctx; ctx = ctx->outer_context) |
1390 | if ((ctx->region_type & ORT_TARGET) != 0) |
1391 | { |
1392 | if (!lookup_attribute ("omp declare target", |
1393 | DECL_ATTRIBUTES (t)((contains_struct_check ((t), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1393, __FUNCTION__))->decl_common.attributes))) |
1394 | { |
1395 | tree id = get_identifier ("omp declare target")(__builtin_constant_p ("omp declare target") ? get_identifier_with_length (("omp declare target"), strlen ("omp declare target")) : get_identifier ("omp declare target")); |
1396 | DECL_ATTRIBUTES (t)((contains_struct_check ((t), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1396, __FUNCTION__))->decl_common.attributes) |
1397 | = tree_cons (id, NULL_TREE(tree) nullptr, DECL_ATTRIBUTES (t)((contains_struct_check ((t), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1397, __FUNCTION__))->decl_common.attributes)); |
1398 | varpool_node *node = varpool_node::get (t); |
1399 | if (node) |
1400 | { |
1401 | node->offloadable = 1; |
1402 | if (ENABLE_OFFLOADING0 && !DECL_EXTERNAL (t)((contains_struct_check ((t), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1402, __FUNCTION__))->decl_common.decl_flag_1)) |
1403 | { |
1404 | g->have_offload = true; |
1405 | if (!in_lto_pglobal_options.x_in_lto_p) |
1406 | vec_safe_push (offload_vars, t); |
1407 | } |
1408 | } |
1409 | } |
1410 | break; |
1411 | } |
1412 | } |
1413 | |
1414 | DECL_SEEN_IN_BIND_EXPR_P (t)((contains_struct_check ((t), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1414, __FUNCTION__))->decl_with_vis.seen_in_bind_expr) = 1; |
1415 | |
1416 | if (DECL_HARD_REGISTER (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1416, __FUNCTION__, (VAR_DECL)))->decl_with_vis.hard_register ) && !is_global_var (t) && cfun(cfun + 0)) |
1417 | cfun(cfun + 0)->has_local_explicit_reg_vars = true; |
1418 | } |
1419 | } |
1420 | |
1421 | bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((bind_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1421, __FUNCTION__, (BIND_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1421, __FUNCTION__)))))), NULLnullptr, |
1422 | BIND_EXPR_BLOCK (bind_expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((bind_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1422, __FUNCTION__, (BIND_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1422, __FUNCTION__))))))); |
1423 | gimple_push_bind_expr (bind_stmt); |
1424 | |
1425 | gimplify_ctxp->keep_stack = false; |
1426 | gimplify_ctxp->save_stack = false; |
1427 | |
1428 | /* Gimplify the body into the GIMPLE_BIND tuple's body. */ |
1429 | body = NULLnullptr; |
1430 | gimplify_stmt (&BIND_EXPR_BODY (bind_expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((bind_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1430, __FUNCTION__, (BIND_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1430, __FUNCTION__)))))), &body); |
1431 | gimple_bind_set_body (bind_stmt, body); |
1432 | |
1433 | /* Source location wise, the cleanup code (stack_restore and clobbers) |
1434 | belongs to the end of the block, so propagate what we have. The |
1435 | stack_save operation belongs to the beginning of block, which we can |
1436 | infer from the bind_expr directly if the block has no explicit |
1437 | assignment. */ |
1438 | if (BIND_EXPR_BLOCK (bind_expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((bind_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1438, __FUNCTION__, (BIND_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1438, __FUNCTION__))))))) |
1439 | { |
1440 | end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr))((tree_check ((((*((const_cast<tree*> (tree_operand_check (((tree_check ((bind_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1440, __FUNCTION__, (BIND_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1440, __FUNCTION__))))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1440, __FUNCTION__, (BLOCK)))->block.end_locus); |
1441 | start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr))((tree_check ((((*((const_cast<tree*> (tree_operand_check (((tree_check ((bind_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1441, __FUNCTION__, (BIND_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1441, __FUNCTION__))))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1441, __FUNCTION__, (BLOCK)))->block.locus); |
1442 | } |
1443 | if (start_locus == 0) |
1444 | start_locus = EXPR_LOCATION (bind_expr)((((bind_expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((bind_expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((bind_expr))->base.code))]) <= tcc_expression)) ? (bind_expr)->exp.locus : ((location_t) 0)); |
1445 | |
1446 | cleanup = NULLnullptr; |
1447 | stack_save = NULLnullptr; |
1448 | |
1449 | /* If the code both contains VLAs and calls alloca, then we cannot reclaim |
1450 | the stack space allocated to the VLAs. */ |
1451 | if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack) |
1452 | { |
1453 | gcall *stack_restore; |
1454 | |
1455 | /* Save stack on entry and restore it on exit. Add a try_finally |
1456 | block to achieve this. */ |
1457 | build_stack_save_restore (&stack_save, &stack_restore); |
1458 | |
1459 | gimple_set_location (stack_save, start_locus); |
1460 | gimple_set_location (stack_restore, end_locus); |
1461 | |
1462 | gimplify_seq_add_stmt (&cleanup, stack_restore); |
1463 | } |
1464 | |
1465 | /* Add clobbers for all variables that go out of scope. */ |
1466 | for (t = BIND_EXPR_VARS (bind_expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((bind_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1466, __FUNCTION__, (BIND_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1466, __FUNCTION__)))))); t ; t = DECL_CHAIN (t)(((contains_struct_check (((contains_struct_check ((t), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1466, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1466, __FUNCTION__))->common.chain))) |
1467 | { |
1468 | if (VAR_P (t)(((enum tree_code) (t)->base.code) == VAR_DECL) |
1469 | && !is_global_var (t) |
1470 | && DECL_CONTEXT (t)((contains_struct_check ((t), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1470, __FUNCTION__))->decl_minimal.context) == current_function_decl) |
1471 | { |
1472 | if (!DECL_HARD_REGISTER (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1472, __FUNCTION__, (VAR_DECL)))->decl_with_vis.hard_register ) |
1473 | && !TREE_THIS_VOLATILE (t)((t)->base.volatile_flag) |
1474 | && !DECL_HAS_VALUE_EXPR_P (t)((tree_check3 ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1474, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL)) ) ->decl_common.decl_flag_2) |
1475 | /* Only care for variables that have to be in memory. Others |
1476 | will be rewritten into SSA names, hence moved to the |
1477 | top-level. */ |
1478 | && !is_gimple_reg (t) |
1479 | && flag_stack_reuseglobal_options.x_flag_stack_reuse != SR_NONE) |
1480 | { |
1481 | tree clobber = build_clobber (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1481, __FUNCTION__))->typed.type), CLOBBER_EOL); |
1482 | gimple *clobber_stmt; |
1483 | clobber_stmt = gimple_build_assign (t, clobber); |
1484 | gimple_set_location (clobber_stmt, end_locus); |
1485 | gimplify_seq_add_stmt (&cleanup, clobber_stmt); |
1486 | } |
1487 | |
1488 | if (flag_openaccglobal_options.x_flag_openacc && oacc_declare_returns != NULLnullptr) |
1489 | { |
1490 | tree key = t; |
1491 | if (DECL_HAS_VALUE_EXPR_P (key)((tree_check3 ((key), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1491, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL)) ) ->decl_common.decl_flag_2)) |
1492 | { |
1493 | key = DECL_VALUE_EXPR (key)(decl_value_expr_lookup ((contains_struct_check ((key), (TS_DECL_WRTL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1493, __FUNCTION__)))); |
1494 | if (TREE_CODE (key)((enum tree_code) (key)->base.code) == INDIRECT_REF) |
1495 | key = TREE_OPERAND (key, 0)(*((const_cast<tree*> (tree_operand_check ((key), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1495, __FUNCTION__))))); |
1496 | } |
1497 | tree *c = oacc_declare_returns->get (key); |
1498 | if (c != NULLnullptr) |
1499 | { |
1500 | if (ret_clauses) |
1501 | OMP_CLAUSE_CHAIN (*c)((contains_struct_check (((tree_check ((*c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1501, __FUNCTION__, (OMP_CLAUSE)))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1501, __FUNCTION__))->common.chain) = ret_clauses; |
1502 | |
1503 | ret_clauses = unshare_expr (*c); |
1504 | |
1505 | oacc_declare_returns->remove (key); |
1506 | |
1507 | if (oacc_declare_returns->is_empty ()) |
1508 | { |
1509 | delete oacc_declare_returns; |
1510 | oacc_declare_returns = NULLnullptr; |
1511 | } |
1512 | } |
1513 | } |
1514 | } |
1515 | |
1516 | if (asan_poisoned_variables != NULLnullptr |
1517 | && asan_poisoned_variables->contains (t)) |
1518 | { |
1519 | asan_poisoned_variables->remove (t); |
1520 | asan_poison_variable (t, true, &cleanup); |
1521 | } |
1522 | |
1523 | if (gimplify_ctxp->live_switch_vars != NULLnullptr |
1524 | && gimplify_ctxp->live_switch_vars->contains (t)) |
1525 | gimplify_ctxp->live_switch_vars->remove (t); |
1526 | } |
1527 | |
1528 | if (ret_clauses) |
1529 | { |
1530 | gomp_target *stmt; |
1531 | gimple_stmt_iterator si = gsi_start (cleanup); |
1532 | |
1533 | stmt = gimple_build_omp_target (NULLnullptr, GF_OMP_TARGET_KIND_OACC_DECLARE, |
1534 | ret_clauses); |
1535 | gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT); |
1536 | } |
1537 | |
1538 | if (cleanup) |
1539 | { |
1540 | gtry *gs; |
1541 | gimple_seq new_body; |
1542 | |
1543 | new_body = NULLnullptr; |
1544 | gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup, |
1545 | GIMPLE_TRY_FINALLY); |
1546 | |
1547 | if (stack_save) |
1548 | gimplify_seq_add_stmt (&new_body, stack_save); |
1549 | gimplify_seq_add_stmt (&new_body, gs); |
1550 | gimple_bind_set_body (bind_stmt, new_body); |
1551 | } |
1552 | |
1553 | /* keep_stack propagates all the way up to the outermost BIND_EXPR. */ |
1554 | if (!gimplify_ctxp->keep_stack) |
1555 | gimplify_ctxp->keep_stack = old_keep_stack; |
1556 | gimplify_ctxp->save_stack = old_save_stack; |
1557 | |
1558 | gimple_pop_bind_expr (); |
1559 | |
1560 | gimplify_seq_add_stmt (pre_p, bind_stmt); |
1561 | |
1562 | if (temp) |
1563 | { |
1564 | *expr_p = temp; |
1565 | return GS_OK; |
1566 | } |
1567 | |
1568 | *expr_p = NULL_TREE(tree) nullptr; |
1569 | return GS_ALL_DONE; |
1570 | } |
1571 | |
1572 | /* Maybe add early return predict statement to PRE_P sequence. */ |
1573 | |
1574 | static void |
1575 | maybe_add_early_return_predict_stmt (gimple_seq *pre_p) |
1576 | { |
1577 | /* If we are not in a conditional context, add PREDICT statement. */ |
1578 | if (gimple_conditional_context ()) |
1579 | { |
1580 | gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN, |
1581 | NOT_TAKEN); |
1582 | gimplify_seq_add_stmt (pre_p, predict); |
1583 | } |
1584 | } |
1585 | |
1586 | /* Gimplify a RETURN_EXPR. If the expression to be returned is not a |
1587 | GIMPLE value, it is assigned to a new temporary and the statement is |
1588 | re-written to return the temporary. |
1589 | |
1590 | PRE_P points to the sequence where side effects that must happen before |
1591 | STMT should be stored. */ |
1592 | |
1593 | static enum gimplify_status |
1594 | gimplify_return_expr (tree stmt, gimple_seq *pre_p) |
1595 | { |
1596 | greturn *ret; |
1597 | tree ret_expr = TREE_OPERAND (stmt, 0)(*((const_cast<tree*> (tree_operand_check ((stmt), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1597, __FUNCTION__))))); |
1598 | tree result_decl, result; |
1599 | |
1600 | if (ret_expr == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
1601 | return GS_ERROR; |
1602 | |
1603 | if (!ret_expr |
1604 | || TREE_CODE (ret_expr)((enum tree_code) (ret_expr)->base.code) == RESULT_DECL) |
1605 | { |
1606 | maybe_add_early_return_predict_stmt (pre_p); |
1607 | greturn *ret = gimple_build_return (ret_expr); |
1608 | copy_warning (ret, stmt); |
1609 | gimplify_seq_add_stmt (pre_p, ret); |
1610 | return GS_ALL_DONE; |
1611 | } |
1612 | |
1613 | if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))(((enum tree_code) (((contains_struct_check ((((contains_struct_check ((current_function_decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1613, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1613, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE )) |
1614 | result_decl = NULL_TREE(tree) nullptr; |
1615 | else if (TREE_CODE (ret_expr)((enum tree_code) (ret_expr)->base.code) == COMPOUND_EXPR) |
1616 | { |
1617 | /* Used in C++ for handling EH cleanup of the return value if a local |
1618 | cleanup throws. Assume the front-end knows what it's doing. */ |
1619 | result_decl = DECL_RESULT (current_function_decl)((tree_check ((current_function_decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1619, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result ); |
1620 | /* But crash if we end up trying to modify ret_expr below. */ |
1621 | ret_expr = NULL_TREE(tree) nullptr; |
1622 | } |
1623 | else |
1624 | { |
1625 | result_decl = TREE_OPERAND (ret_expr, 0)(*((const_cast<tree*> (tree_operand_check ((ret_expr), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1625, __FUNCTION__))))); |
1626 | |
1627 | /* See through a return by reference. */ |
1628 | if (TREE_CODE (result_decl)((enum tree_code) (result_decl)->base.code) == INDIRECT_REF) |
1629 | result_decl = TREE_OPERAND (result_decl, 0)(*((const_cast<tree*> (tree_operand_check ((result_decl ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1629, __FUNCTION__))))); |
1630 | |
1631 | gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR((void)(!((((enum tree_code) (ret_expr)->base.code) == MODIFY_EXPR || ((enum tree_code) (ret_expr)->base.code) == INIT_EXPR) && ((enum tree_code) (result_decl)->base.code) == RESULT_DECL) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1633, __FUNCTION__), 0 : 0)) |
1632 | || TREE_CODE (ret_expr) == INIT_EXPR)((void)(!((((enum tree_code) (ret_expr)->base.code) == MODIFY_EXPR || ((enum tree_code) (ret_expr)->base.code) == INIT_EXPR) && ((enum tree_code) (result_decl)->base.code) == RESULT_DECL) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1633, __FUNCTION__), 0 : 0)) |
1633 | && TREE_CODE (result_decl) == RESULT_DECL)((void)(!((((enum tree_code) (ret_expr)->base.code) == MODIFY_EXPR || ((enum tree_code) (ret_expr)->base.code) == INIT_EXPR) && ((enum tree_code) (result_decl)->base.code) == RESULT_DECL) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1633, __FUNCTION__), 0 : 0)); |
1634 | } |
1635 | |
1636 | /* If aggregate_value_p is true, then we can return the bare RESULT_DECL. |
1637 | Recall that aggregate_value_p is FALSE for any aggregate type that is |
1638 | returned in registers. If we're returning values in registers, then |
1639 | we don't want to extend the lifetime of the RESULT_DECL, particularly |
1640 | across another call. In addition, for those aggregates for which |
1641 | hard_function_value generates a PARALLEL, we'll die during normal |
1642 | expansion of structure assignments; there's special code in expand_return |
1643 | to handle this case that does not exist in expand_expr. */ |
1644 | if (!result_decl) |
1645 | result = NULL_TREE(tree) nullptr; |
1646 | else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)((contains_struct_check ((current_function_decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1646, __FUNCTION__))->typed.type))) |
1647 | { |
1648 | if (!poly_int_tree_p (DECL_SIZE (result_decl)((contains_struct_check ((result_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1648, __FUNCTION__))->decl_common.size))) |
1649 | { |
1650 | if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl))((tree_class_check ((((contains_struct_check ((result_decl), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1650, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1650, __FUNCTION__))->base.constant_flag)) |
1651 | gimplify_type_sizes (TREE_TYPE (result_decl)((contains_struct_check ((result_decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1651, __FUNCTION__))->typed.type), pre_p); |
1652 | /* Note that we don't use gimplify_vla_decl because the RESULT_DECL |
1653 | should be effectively allocated by the caller, i.e. all calls to |
1654 | this function must be subject to the Return Slot Optimization. */ |
1655 | gimplify_one_sizepos (&DECL_SIZE (result_decl)((contains_struct_check ((result_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1655, __FUNCTION__))->decl_common.size), pre_p); |
1656 | gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl)((contains_struct_check ((result_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1656, __FUNCTION__))->decl_common.size_unit), pre_p); |
1657 | } |
1658 | result = result_decl; |
1659 | } |
1660 | else if (gimplify_ctxp->return_temp) |
1661 | result = gimplify_ctxp->return_temp; |
1662 | else |
1663 | { |
1664 | result = create_tmp_reg (TREE_TYPE (result_decl)((contains_struct_check ((result_decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1664, __FUNCTION__))->typed.type)); |
1665 | |
1666 | /* ??? With complex control flow (usually involving abnormal edges), |
1667 | we can wind up warning about an uninitialized value for this. Due |
1668 | to how this variable is constructed and initialized, this is never |
1669 | true. Give up and never warn. */ |
1670 | suppress_warning (result, OPT_Wuninitialized); |
1671 | |
1672 | gimplify_ctxp->return_temp = result; |
1673 | } |
1674 | |
1675 | /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use. |
1676 | Then gimplify the whole thing. */ |
1677 | if (result != result_decl) |
1678 | TREE_OPERAND (ret_expr, 0)(*((const_cast<tree*> (tree_operand_check ((ret_expr), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1678, __FUNCTION__))))) = result; |
1679 | |
1680 | gimplify_and_add (TREE_OPERAND (stmt, 0)(*((const_cast<tree*> (tree_operand_check ((stmt), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1680, __FUNCTION__))))), pre_p); |
1681 | |
1682 | maybe_add_early_return_predict_stmt (pre_p); |
1683 | ret = gimple_build_return (result); |
1684 | copy_warning (ret, stmt); |
1685 | gimplify_seq_add_stmt (pre_p, ret); |
1686 | |
1687 | return GS_ALL_DONE; |
1688 | } |
1689 | |
1690 | /* Gimplify a variable-length array DECL. */ |
1691 | |
1692 | static void |
1693 | gimplify_vla_decl (tree decl, gimple_seq *seq_p) |
1694 | { |
1695 | /* This is a variable-sized decl. Simplify its size and mark it |
1696 | for deferred expansion. */ |
1697 | tree t, addr, ptr_type; |
1698 | |
1699 | gimplify_one_sizepos (&DECL_SIZE (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1699, __FUNCTION__))->decl_common.size), seq_p); |
1700 | gimplify_one_sizepos (&DECL_SIZE_UNIT (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1700, __FUNCTION__))->decl_common.size_unit), seq_p); |
1701 | |
1702 | /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */ |
1703 | if (DECL_HAS_VALUE_EXPR_P (decl)((tree_check3 ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1703, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL)) ) ->decl_common.decl_flag_2)) |
1704 | return; |
1705 | |
1706 | /* All occurrences of this decl in final gimplified code will be |
1707 | replaced by indirection. Setting DECL_VALUE_EXPR does two |
1708 | things: First, it lets the rest of the gimplifier know what |
1709 | replacement to use. Second, it lets the debug info know |
1710 | where to find the value. */ |
1711 | ptr_type = build_pointer_type (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1711, __FUNCTION__))->typed.type)); |
1712 | addr = create_tmp_var (ptr_type, get_name (decl)); |
1713 | DECL_IGNORED_P (addr)((contains_struct_check ((addr), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1713, __FUNCTION__))->decl_common.ignored_flag) = 0; |
1714 | t = build_fold_indirect_ref (addr)build_fold_indirect_ref_loc (((location_t) 0), addr); |
1715 | TREE_THIS_NOTRAP (t)((tree_check5 ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1715, __FUNCTION__, (INDIRECT_REF), (MEM_REF), (TARGET_MEM_REF ), (ARRAY_REF), (ARRAY_RANGE_REF)))->base.nothrow_flag) = 1; |
1716 | SET_DECL_VALUE_EXPR (decl, t)(decl_value_expr_insert ((contains_struct_check ((decl), (TS_DECL_WRTL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1716, __FUNCTION__)), t)); |
1717 | DECL_HAS_VALUE_EXPR_P (decl)((tree_check3 ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1717, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL)) ) ->decl_common.decl_flag_2) = 1; |
1718 | |
1719 | t = build_alloca_call_expr (DECL_SIZE_UNIT (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1719, __FUNCTION__))->decl_common.size_unit), DECL_ALIGN (decl)(((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1719, __FUNCTION__))->decl_common.align) ? ((unsigned)1) << (((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1719, __FUNCTION__))->decl_common.align) - 1) : 0), |
1720 | max_int_size_in_bytes (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1720, __FUNCTION__))->typed.type))); |
1721 | /* The call has been built for a variable-sized object. */ |
1722 | CALL_ALLOCA_FOR_VAR_P (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1722, __FUNCTION__, (CALL_EXPR)))->base.protected_flag) = 1; |
1723 | t = fold_convert (ptr_type, t)fold_convert_loc (((location_t) 0), ptr_type, t); |
1724 | t = build2 (MODIFY_EXPR, TREE_TYPE (addr)((contains_struct_check ((addr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1724, __FUNCTION__))->typed.type), addr, t); |
1725 | |
1726 | gimplify_and_add (t, seq_p); |
1727 | |
1728 | /* Record the dynamic allocation associated with DECL if requested. */ |
1729 | if (flag_callgraph_infoglobal_options.x_flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC) |
1730 | record_dynamic_alloc (decl); |
1731 | } |
1732 | |
1733 | /* A helper function to be called via walk_tree. Mark all labels under *TP |
1734 | as being forced. To be called for DECL_INITIAL of static variables. */ |
1735 | |
1736 | static tree |
1737 | force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED__attribute__ ((__unused__))) |
1738 | { |
1739 | if (TYPE_P (*tp)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*tp)->base.code))] == tcc_type)) |
1740 | *walk_subtrees = 0; |
1741 | if (TREE_CODE (*tp)((enum tree_code) (*tp)->base.code) == LABEL_DECL) |
1742 | { |
1743 | FORCED_LABEL (*tp)((tree_check ((*tp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1743, __FUNCTION__, (LABEL_DECL)))->base.side_effects_flag ) = 1; |
1744 | cfun(cfun + 0)->has_forced_label_in_static = 1; |
1745 | } |
1746 | |
1747 | return NULL_TREE(tree) nullptr; |
1748 | } |
1749 | |
1750 | /* Generate an initialization to automatic variable DECL based on INIT_TYPE. |
1751 | Build a call to internal const function DEFERRED_INIT: |
1752 | 1st argument: SIZE of the DECL; |
1753 | 2nd argument: INIT_TYPE; |
1754 | 3rd argument: NAME of the DECL; |
1755 | |
1756 | as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL). */ |
1757 | |
1758 | static void |
1759 | gimple_add_init_for_auto_var (tree decl, |
1760 | enum auto_init_type init_type, |
1761 | gimple_seq *seq_p) |
1762 | { |
1763 | gcc_assert (auto_var_p (decl))((void)(!(auto_var_p (decl)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1763, __FUNCTION__), 0 : 0)); |
1764 | gcc_assert (init_type > AUTO_INIT_UNINITIALIZED)((void)(!(init_type > AUTO_INIT_UNINITIALIZED) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1764, __FUNCTION__), 0 : 0)); |
1765 | location_t loc = EXPR_LOCATION (decl)((((decl)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((decl))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((decl))->base.code))]) <= tcc_expression )) ? (decl)->exp.locus : ((location_t) 0)); |
1766 | tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl))((tree_class_check ((((contains_struct_check ((decl), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1766, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1766, __FUNCTION__))->type_common.size_unit); |
1767 | |
1768 | tree init_type_node |
1769 | = build_int_cst (integer_type_nodeinteger_types[itk_int], (int) init_type); |
1770 | |
1771 | tree decl_name = NULL_TREE(tree) nullptr; |
1772 | if (DECL_NAME (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1772, __FUNCTION__))->decl_minimal.name)) |
1773 | |
1774 | decl_name = build_string_literal (DECL_NAME (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1774, __FUNCTION__))->decl_minimal.name)); |
1775 | |
1776 | else |
1777 | { |
1778 | char decl_name_anonymous[3 + (HOST_BITS_PER_INT(8 * 4) + 2) / 3]; |
1779 | sprintf (decl_name_anonymous, "D.%u", DECL_UID (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1779, __FUNCTION__))->decl_minimal.uid)); |
1780 | decl_name = build_string_literal (decl_name_anonymous); |
1781 | } |
1782 | |
1783 | tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT, |
1784 | TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1784, __FUNCTION__))->typed.type), 3, |
1785 | decl_size, init_type_node, |
1786 | decl_name); |
1787 | |
1788 | gimplify_assign (decl, call, seq_p); |
1789 | } |
1790 | |
1791 | /* Generate padding initialization for automatic vairable DECL. |
1792 | C guarantees that brace-init with fewer initializers than members |
1793 | aggregate will initialize the rest of the aggregate as-if it were |
1794 | static initialization. In turn static initialization guarantees |
1795 | that padding is initialized to zero. So, we always initialize paddings |
1796 | to zeroes regardless INIT_TYPE. |
1797 | To do the padding initialization, we insert a call to |
1798 | __builtin_clear_padding (&decl, 0, for_auto_init = true). |
1799 | Note, we add an additional dummy argument for __builtin_clear_padding, |
1800 | 'for_auto_init' to distinguish whether this call is for automatic |
1801 | variable initialization or not. |
1802 | */ |
1803 | static void |
1804 | gimple_add_padding_init_for_auto_var (tree decl, bool is_vla, |
1805 | gimple_seq *seq_p) |
1806 | { |
1807 | tree addr_of_decl = NULL_TREE(tree) nullptr; |
1808 | tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING); |
1809 | |
1810 | if (is_vla) |
1811 | { |
1812 | /* The temporary address variable for this vla should be |
1813 | created in gimplify_vla_decl. */ |
1814 | gcc_assert (DECL_HAS_VALUE_EXPR_P (decl))((void)(!(((tree_check3 ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1814, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL)) ) ->decl_common.decl_flag_2)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1814, __FUNCTION__), 0 : 0)); |
1815 | gcc_assert (TREE_CODE (DECL_VALUE_EXPR (decl)) == INDIRECT_REF)((void)(!(((enum tree_code) ((decl_value_expr_lookup ((contains_struct_check ((decl), (TS_DECL_WRTL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1815, __FUNCTION__)))))->base.code) == INDIRECT_REF) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1815, __FUNCTION__), 0 : 0)); |
1816 | addr_of_decl = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0)(*((const_cast<tree*> (tree_operand_check (((decl_value_expr_lookup ((contains_struct_check ((decl), (TS_DECL_WRTL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1816, __FUNCTION__))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1816, __FUNCTION__))))); |
1817 | } |
1818 | else |
1819 | { |
1820 | mark_addressable (decl); |
1821 | addr_of_decl = build_fold_addr_expr (decl)build_fold_addr_expr_loc (((location_t) 0), (decl)); |
1822 | } |
1823 | |
1824 | gimple *call = gimple_build_call (fn, 2, addr_of_decl, |
1825 | build_one_cst (TREE_TYPE (addr_of_decl)((contains_struct_check ((addr_of_decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1825, __FUNCTION__))->typed.type))); |
1826 | gimplify_seq_add_stmt (seq_p, call); |
1827 | } |
1828 | |
1829 | /* Return true if the DECL need to be automaticly initialized by the |
1830 | compiler. */ |
1831 | static bool |
1832 | is_var_need_auto_init (tree decl) |
1833 | { |
1834 | if (auto_var_p (decl) |
1835 | && (TREE_CODE (decl)((enum tree_code) (decl)->base.code) != VAR_DECL |
1836 | || !DECL_HARD_REGISTER (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1836, __FUNCTION__, (VAR_DECL)))->decl_with_vis.hard_register )) |
1837 | && (flag_auto_var_initglobal_options.x_flag_auto_var_init > AUTO_INIT_UNINITIALIZED) |
1838 | && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1838, __FUNCTION__))->decl_common.attributes))) |
1839 | && !OPAQUE_TYPE_P (TREE_TYPE (decl))(((enum tree_code) (((contains_struct_check ((decl), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1839, __FUNCTION__))->typed.type))->base.code) == OPAQUE_TYPE ) |
1840 | && !is_empty_type (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1840, __FUNCTION__))->typed.type))) |
1841 | return true; |
1842 | return false; |
1843 | } |
1844 | |
1845 | /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation |
1846 | and initialization explicit. */ |
1847 | |
1848 | static enum gimplify_status |
1849 | gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p) |
1850 | { |
1851 | tree stmt = *stmt_p; |
1852 | tree decl = DECL_EXPR_DECL (stmt)(*((const_cast<tree*> (tree_operand_check (((tree_check ((stmt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1852, __FUNCTION__, (DECL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1852, __FUNCTION__))))); |
1853 | |
1854 | *stmt_p = NULL_TREE(tree) nullptr; |
1855 | |
1856 | if (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1856, __FUNCTION__))->typed.type) == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
1857 | return GS_ERROR; |
1858 | |
1859 | if ((TREE_CODE (decl)((enum tree_code) (decl)->base.code) == TYPE_DECL |
1860 | || VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL)) |
1861 | && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl))((tree_class_check ((((contains_struct_check ((decl), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1861, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1861, __FUNCTION__))->base.constant_flag)) |
1862 | { |
1863 | gimplify_type_sizes (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1863, __FUNCTION__))->typed.type), seq_p); |
1864 | if (TREE_CODE (TREE_TYPE (decl))((enum tree_code) (((contains_struct_check ((decl), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1864, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE) |
1865 | gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl))((contains_struct_check ((((contains_struct_check ((decl), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1865, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1865, __FUNCTION__))->typed.type), seq_p); |
1866 | } |
1867 | |
1868 | /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified |
1869 | in case its size expressions contain problematic nodes like CALL_EXPR. */ |
1870 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == TYPE_DECL |
1871 | && DECL_ORIGINAL_TYPE (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1871, __FUNCTION__, (TYPE_DECL)))->decl_non_common.result ) |
1872 | && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl))((tree_class_check ((((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1872, __FUNCTION__, (TYPE_DECL)))->decl_non_common.result )), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1872, __FUNCTION__))->base.constant_flag)) |
1873 | { |
1874 | gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1874, __FUNCTION__, (TYPE_DECL)))->decl_non_common.result ), seq_p); |
1875 | if (TREE_CODE (DECL_ORIGINAL_TYPE (decl))((enum tree_code) (((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1875, __FUNCTION__, (TYPE_DECL)))->decl_non_common.result ))->base.code) == REFERENCE_TYPE) |
1876 | gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl))((contains_struct_check ((((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1876, __FUNCTION__, (TYPE_DECL)))->decl_non_common.result )), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1876, __FUNCTION__))->typed.type), seq_p); |
1877 | } |
1878 | |
1879 | if (VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL) && !DECL_EXTERNAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1879, __FUNCTION__))->decl_common.decl_flag_1)) |
1880 | { |
1881 | tree init = DECL_INITIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1881, __FUNCTION__))->decl_common.initial); |
1882 | bool is_vla = false; |
1883 | /* Check whether a decl has FE created VALUE_EXPR here BEFORE |
1884 | gimplify_vla_decl creates VALUE_EXPR for a vla decl. |
1885 | If the decl has VALUE_EXPR that was created by FE (usually |
1886 | C++FE), it's a proxy varaible, and FE already initialized |
1887 | the VALUE_EXPR of it, we should not initialize it anymore. */ |
1888 | bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl)((tree_check3 ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1888, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL)) ) ->decl_common.decl_flag_2); |
1889 | |
1890 | poly_uint64 size; |
1891 | if (!poly_int_tree_p (DECL_SIZE_UNIT (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1891, __FUNCTION__))->decl_common.size_unit), &size) |
1892 | || (!TREE_STATIC (decl)((decl)->base.static_flag) |
1893 | && flag_stack_checkglobal_options.x_flag_stack_check == GENERIC_STACK_CHECK |
1894 | && maybe_gt (size,maybe_lt ((unsigned long) (((1 << 12) - (((global_options .x_ix86_isa_flags & (1UL << 1)) != 0) ? 8 : 4)) / 100 ), size) |
1895 | (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)maybe_lt ((unsigned long) (((1 << 12) - (((global_options .x_ix86_isa_flags & (1UL << 1)) != 0) ? 8 : 4)) / 100 ), size))) |
1896 | { |
1897 | gimplify_vla_decl (decl, seq_p); |
1898 | is_vla = true; |
1899 | } |
1900 | |
1901 | if (asan_poisoned_variables |
1902 | && !is_vla |
1903 | && TREE_ADDRESSABLE (decl)((decl)->base.addressable_flag) |
1904 | && !TREE_STATIC (decl)((decl)->base.static_flag) |
1905 | && !DECL_HAS_VALUE_EXPR_P (decl)((tree_check3 ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1905, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL)) ) ->decl_common.decl_flag_2) |
1906 | && DECL_ALIGN (decl)(((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1906, __FUNCTION__))->decl_common.align) ? ((unsigned)1) << (((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1906, __FUNCTION__))->decl_common.align) - 1) : 0) <= MAX_SUPPORTED_STACK_ALIGNMENT(((unsigned int) 1 << 28) * 8) |
1907 | && dbg_cnt (asan_use_after_scope) |
1908 | && !gimplify_omp_ctxp |
1909 | /* GNAT introduces temporaries to hold return values of calls in |
1910 | initializers of variables defined in other units, so the |
1911 | declaration of the variable is discarded completely. We do not |
1912 | want to issue poison calls for such dropped variables. */ |
1913 | && (DECL_SEEN_IN_BIND_EXPR_P (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1913, __FUNCTION__))->decl_with_vis.seen_in_bind_expr) |
1914 | || (DECL_ARTIFICIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1914, __FUNCTION__))->decl_common.artificial_flag) && DECL_NAME (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1914, __FUNCTION__))->decl_minimal.name) == NULL_TREE(tree) nullptr))) |
1915 | { |
1916 | asan_poisoned_variables->add (decl); |
1917 | asan_poison_variable (decl, false, seq_p); |
1918 | if (!DECL_ARTIFICIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1918, __FUNCTION__))->decl_common.artificial_flag) && gimplify_ctxp->live_switch_vars) |
1919 | gimplify_ctxp->live_switch_vars->add (decl); |
1920 | } |
1921 | |
1922 | /* Some front ends do not explicitly declare all anonymous |
1923 | artificial variables. We compensate here by declaring the |
1924 | variables, though it would be better if the front ends would |
1925 | explicitly declare them. */ |
1926 | if (!DECL_SEEN_IN_BIND_EXPR_P (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1926, __FUNCTION__))->decl_with_vis.seen_in_bind_expr) |
1927 | && DECL_ARTIFICIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1927, __FUNCTION__))->decl_common.artificial_flag) && DECL_NAME (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1927, __FUNCTION__))->decl_minimal.name) == NULL_TREE(tree) nullptr) |
1928 | gimple_add_tmp_var (decl); |
1929 | |
1930 | if (init && init != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
1931 | { |
1932 | if (!TREE_STATIC (decl)((decl)->base.static_flag)) |
1933 | { |
1934 | DECL_INITIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1934, __FUNCTION__))->decl_common.initial) = NULL_TREE(tree) nullptr; |
1935 | init = build2 (INIT_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], decl, init); |
1936 | gimplify_and_add (init, seq_p); |
1937 | ggc_free (init); |
1938 | /* Clear TREE_READONLY if we really have an initialization. */ |
1939 | if (!DECL_INITIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1939, __FUNCTION__))->decl_common.initial) |
1940 | && !omp_privatize_by_reference (decl)) |
1941 | TREE_READONLY (decl)((non_type_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1941, __FUNCTION__))->base.readonly_flag) = 0; |
1942 | } |
1943 | else |
1944 | /* We must still examine initializers for static variables |
1945 | as they may contain a label address. */ |
1946 | walk_tree (&init, force_labels_r, NULL, NULL)walk_tree_1 (&init, force_labels_r, nullptr, nullptr, nullptr ); |
1947 | } |
1948 | /* When there is no explicit initializer, if the user requested, |
1949 | We should insert an artifical initializer for this automatic |
1950 | variable. */ |
1951 | else if (is_var_need_auto_init (decl) |
1952 | && !decl_had_value_expr_p) |
1953 | { |
1954 | gimple_add_init_for_auto_var (decl, |
1955 | flag_auto_var_initglobal_options.x_flag_auto_var_init, |
1956 | seq_p); |
1957 | /* The expanding of a call to the above .DEFERRED_INIT will apply |
1958 | block initialization to the whole space covered by this variable. |
1959 | As a result, all the paddings will be initialized to zeroes |
1960 | for zero initialization and 0xFE byte-repeatable patterns for |
1961 | pattern initialization. |
1962 | In order to make the paddings as zeroes for pattern init, We |
1963 | should add a call to __builtin_clear_padding to clear the |
1964 | paddings to zero in compatiple with CLANG. |
1965 | We cannot insert this call if the variable is a gimple register |
1966 | since __builtin_clear_padding will take the address of the |
1967 | variable. As a result, if a long double/_Complex long double |
1968 | variable will spilled into stack later, its padding is 0XFE. */ |
1969 | if (flag_auto_var_initglobal_options.x_flag_auto_var_init == AUTO_INIT_PATTERN |
1970 | && !is_gimple_reg (decl) |
1971 | && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1971, __FUNCTION__))->typed.type))) |
1972 | gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p); |
1973 | } |
1974 | } |
1975 | |
1976 | return GS_ALL_DONE; |
1977 | } |
1978 | |
1979 | /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body |
1980 | and replacing the LOOP_EXPR with goto, but if the loop contains an |
1981 | EXIT_EXPR, we need to append a label for it to jump to. */ |
1982 | |
1983 | static enum gimplify_status |
1984 | gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p) |
1985 | { |
1986 | tree saved_label = gimplify_ctxp->exit_label; |
1987 | tree start_label = create_artificial_label (UNKNOWN_LOCATION((location_t) 0)); |
1988 | |
1989 | gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label)); |
1990 | |
1991 | gimplify_ctxp->exit_label = NULL_TREE(tree) nullptr; |
1992 | |
1993 | gimplify_and_add (LOOP_EXPR_BODY (*expr_p)(*(tree_operand_check_code ((*expr_p), (LOOP_EXPR), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 1993, __FUNCTION__))), pre_p); |
1994 | |
1995 | gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label)); |
1996 | |
1997 | if (gimplify_ctxp->exit_label) |
1998 | gimplify_seq_add_stmt (pre_p, |
1999 | gimple_build_label (gimplify_ctxp->exit_label)); |
2000 | |
2001 | gimplify_ctxp->exit_label = saved_label; |
2002 | |
2003 | *expr_p = NULLnullptr; |
2004 | return GS_ALL_DONE; |
2005 | } |
2006 | |
2007 | /* Gimplify a statement list onto a sequence. These may be created either |
2008 | by an enlightened front-end, or by shortcut_cond_expr. */ |
2009 | |
2010 | static enum gimplify_status |
2011 | gimplify_statement_list (tree *expr_p, gimple_seq *pre_p) |
2012 | { |
2013 | tree temp = voidify_wrapper_expr (*expr_p, NULLnullptr); |
2014 | |
2015 | tree_stmt_iterator i = tsi_start (*expr_p); |
2016 | |
2017 | while (!tsi_end_p (i)) |
2018 | { |
2019 | gimplify_stmt (tsi_stmt_ptr (i), pre_p); |
2020 | tsi_delink (&i); |
2021 | } |
2022 | |
2023 | if (temp) |
2024 | { |
2025 | *expr_p = temp; |
2026 | return GS_OK; |
2027 | } |
2028 | |
2029 | return GS_ALL_DONE; |
2030 | } |
2031 | |
2032 | |
2033 | /* Emit warning for the unreachable statment STMT if needed. |
2034 | Return the gimple itself when the warning is emitted, otherwise |
2035 | return NULL. */ |
2036 | static gimple * |
2037 | emit_warn_switch_unreachable (gimple *stmt) |
2038 | { |
2039 | if (gimple_code (stmt) == GIMPLE_GOTO |
2040 | && TREE_CODE (gimple_goto_dest (stmt))((enum tree_code) (gimple_goto_dest (stmt))->base.code) == LABEL_DECL |
2041 | && DECL_ARTIFICIAL (gimple_goto_dest (stmt))((contains_struct_check ((gimple_goto_dest (stmt)), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2041, __FUNCTION__))->decl_common.artificial_flag)) |
2042 | /* Don't warn for compiler-generated gotos. These occur |
2043 | in Duff's devices, for example. */ |
2044 | return NULLnullptr; |
2045 | else if ((flag_auto_var_initglobal_options.x_flag_auto_var_init > AUTO_INIT_UNINITIALIZED) |
2046 | && ((gimple_call_internal_p (stmt, IFN_DEFERRED_INIT)) |
2047 | || (gimple_call_builtin_p (stmt, BUILT_IN_CLEAR_PADDING) |
2048 | && (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1))((unsigned long) (*tree_int_cst_elt_check ((gimple_call_arg ( stmt, 1)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2048, __FUNCTION__)))) |
2049 | || (is_gimple_assign (stmt) |
2050 | && gimple_assign_single_p (stmt) |
2051 | && (TREE_CODE (gimple_assign_rhs1 (stmt))((enum tree_code) (gimple_assign_rhs1 (stmt))->base.code) == SSA_NAME) |
2052 | && gimple_call_internal_p ( |
2053 | SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt))(tree_check ((gimple_assign_rhs1 (stmt)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2053, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt, |
2054 | IFN_DEFERRED_INIT)))) |
2055 | /* Don't warn for compiler-generated initializations for |
2056 | -ftrivial-auto-var-init. |
2057 | There are 3 cases: |
2058 | case 1: a call to .DEFERRED_INIT; |
2059 | case 2: a call to __builtin_clear_padding with the 2nd argument is |
2060 | present and non-zero; |
2061 | case 3: a gimple assign store right after the call to .DEFERRED_INIT |
2062 | that has the LHS of .DEFERRED_INIT as the RHS as following: |
2063 | _1 = .DEFERRED_INIT (4, 2, &"i1"[0]); |
2064 | i1 = _1. */ |
2065 | return NULLnullptr; |
2066 | else |
2067 | warning_at (gimple_location (stmt), OPT_Wswitch_unreachable, |
2068 | "statement will never be executed"); |
2069 | return stmt; |
2070 | } |
2071 | |
2072 | /* Callback for walk_gimple_seq. */ |
2073 | |
2074 | static tree |
2075 | warn_switch_unreachable_and_auto_init_r (gimple_stmt_iterator *gsi_p, |
2076 | bool *handled_ops_p, |
2077 | struct walk_stmt_info *wi) |
2078 | { |
2079 | gimple *stmt = gsi_stmt (*gsi_p); |
2080 | bool unreachable_issued = wi->info != NULLnullptr; |
2081 | |
2082 | *handled_ops_p = true; |
2083 | switch (gimple_code (stmt)) |
2084 | { |
2085 | case GIMPLE_TRY: |
2086 | /* A compiler-generated cleanup or a user-written try block. |
2087 | If it's empty, don't dive into it--that would result in |
2088 | worse location info. */ |
2089 | if (gimple_try_eval (stmt) == NULLnullptr) |
2090 | { |
2091 | if (warn_switch_unreachableglobal_options.x_warn_switch_unreachable && !unreachable_issued) |
2092 | wi->info = emit_warn_switch_unreachable (stmt); |
2093 | |
2094 | /* Stop when auto var init warning is not on. */ |
2095 | if (!warn_trivial_auto_var_initglobal_options.x_warn_trivial_auto_var_init) |
2096 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
2097 | } |
2098 | /* Fall through. */ |
2099 | case GIMPLE_BIND: |
2100 | case GIMPLE_CATCH: |
2101 | case GIMPLE_EH_FILTER: |
2102 | case GIMPLE_TRANSACTION: |
2103 | /* Walk the sub-statements. */ |
2104 | *handled_ops_p = false; |
2105 | break; |
2106 | |
2107 | case GIMPLE_DEBUG: |
2108 | /* Ignore these. We may generate them before declarations that |
2109 | are never executed. If there's something to warn about, |
2110 | there will be non-debug stmts too, and we'll catch those. */ |
2111 | break; |
2112 | |
2113 | case GIMPLE_LABEL: |
2114 | /* Stop till the first Label. */ |
2115 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
2116 | case GIMPLE_CALL: |
2117 | if (gimple_call_internal_p (stmt, IFN_ASAN_MARK)) |
2118 | { |
2119 | *handled_ops_p = false; |
2120 | break; |
2121 | } |
2122 | if (warn_trivial_auto_var_initglobal_options.x_warn_trivial_auto_var_init |
2123 | && flag_auto_var_initglobal_options.x_flag_auto_var_init > AUTO_INIT_UNINITIALIZED |
2124 | && gimple_call_internal_p (stmt, IFN_DEFERRED_INIT)) |
2125 | { |
2126 | /* Get the variable name from the 3rd argument of call. */ |
2127 | tree var_name = gimple_call_arg (stmt, 2); |
2128 | var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0)(*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check ((var_name), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2128, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2128, __FUNCTION__))))); |
2129 | const char *var_name_str = TREE_STRING_POINTER (var_name)((const char *)((tree_check ((var_name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2129, __FUNCTION__, (STRING_CST)))->string.str)); |
2130 | |
2131 | warning_at (gimple_location (stmt), OPT_Wtrivial_auto_var_init, |
2132 | "%qs cannot be initialized with" |
2133 | "%<-ftrivial-auto-var_init%>", |
2134 | var_name_str); |
2135 | break; |
2136 | } |
2137 | |
2138 | /* Fall through. */ |
2139 | default: |
2140 | /* check the first "real" statement (not a decl/lexical scope/...), issue |
2141 | warning if needed. */ |
2142 | if (warn_switch_unreachableglobal_options.x_warn_switch_unreachable && !unreachable_issued) |
2143 | wi->info = emit_warn_switch_unreachable (stmt); |
2144 | /* Stop when auto var init warning is not on. */ |
2145 | if (!warn_trivial_auto_var_initglobal_options.x_warn_trivial_auto_var_init) |
2146 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
2147 | break; |
2148 | } |
2149 | return NULL_TREE(tree) nullptr; |
2150 | } |
2151 | |
2152 | |
2153 | /* Possibly warn about unreachable statements between switch's controlling |
2154 | expression and the first case. Also warn about -ftrivial-auto-var-init |
2155 | cannot initialize the auto variable under such situation. |
2156 | SEQ is the body of a switch expression. */ |
2157 | |
2158 | static void |
2159 | maybe_warn_switch_unreachable_and_auto_init (gimple_seq seq) |
2160 | { |
2161 | if ((!warn_switch_unreachableglobal_options.x_warn_switch_unreachable && !warn_trivial_auto_var_initglobal_options.x_warn_trivial_auto_var_init) |
2162 | /* This warning doesn't play well with Fortran when optimizations |
2163 | are on. */ |
2164 | || lang_GNU_Fortran () |
2165 | || seq == NULLnullptr) |
2166 | return; |
2167 | |
2168 | struct walk_stmt_info wi; |
2169 | |
2170 | memset (&wi, 0, sizeof (wi)); |
2171 | walk_gimple_seq (seq, warn_switch_unreachable_and_auto_init_r, NULLnullptr, &wi); |
2172 | } |
2173 | |
2174 | |
2175 | /* A label entry that pairs label and a location. */ |
2176 | struct label_entry |
2177 | { |
2178 | tree label; |
2179 | location_t loc; |
2180 | }; |
2181 | |
2182 | /* Find LABEL in vector of label entries VEC. */ |
2183 | |
2184 | static struct label_entry * |
2185 | find_label_entry (const auto_vec<struct label_entry> *vec, tree label) |
2186 | { |
2187 | unsigned int i; |
2188 | struct label_entry *l; |
2189 | |
2190 | FOR_EACH_VEC_ELT (*vec, i, l)for (i = 0; (*vec).iterate ((i), &(l)); ++(i)) |
2191 | if (l->label == label) |
2192 | return l; |
2193 | return NULLnullptr; |
2194 | } |
2195 | |
2196 | /* Return true if LABEL, a LABEL_DECL, represents a case label |
2197 | in a vector of labels CASES. */ |
2198 | |
2199 | static bool |
2200 | case_label_p (const vec<tree> *cases, tree label) |
2201 | { |
2202 | unsigned int i; |
2203 | tree l; |
2204 | |
2205 | FOR_EACH_VEC_ELT (*cases, i, l)for (i = 0; (*cases).iterate ((i), &(l)); ++(i)) |
2206 | if (CASE_LABEL (l)(*((const_cast<tree*> (tree_operand_check (((tree_check ((l), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2206, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2206, __FUNCTION__))))) == label) |
2207 | return true; |
2208 | return false; |
2209 | } |
2210 | |
2211 | /* Find the last nondebug statement in a scope STMT. */ |
2212 | |
2213 | static gimple * |
2214 | last_stmt_in_scope (gimple *stmt) |
2215 | { |
2216 | if (!stmt) |
2217 | return NULLnullptr; |
2218 | |
2219 | switch (gimple_code (stmt)) |
2220 | { |
2221 | case GIMPLE_BIND: |
2222 | { |
2223 | gbind *bind = as_a <gbind *> (stmt); |
2224 | stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind)); |
2225 | return last_stmt_in_scope (stmt); |
2226 | } |
2227 | |
2228 | case GIMPLE_TRY: |
2229 | { |
2230 | gtry *try_stmt = as_a <gtry *> (stmt); |
2231 | stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt)); |
2232 | gimple *last_eval = last_stmt_in_scope (stmt); |
2233 | if (gimple_stmt_may_fallthru (last_eval) |
2234 | && (last_eval == NULLnullptr |
2235 | || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH)) |
2236 | && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY) |
2237 | { |
2238 | stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt)); |
2239 | return last_stmt_in_scope (stmt); |
2240 | } |
2241 | else |
2242 | return last_eval; |
2243 | } |
2244 | |
2245 | case GIMPLE_DEBUG: |
2246 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2246, __FUNCTION__)); |
2247 | |
2248 | default: |
2249 | return stmt; |
2250 | } |
2251 | } |
2252 | |
2253 | /* Collect labels that may fall through into LABELS and return the statement |
2254 | preceding another case label, or a user-defined label. Store a location |
2255 | useful to give warnings at *PREVLOC (usually the location of the returned |
2256 | statement or of its surrounding scope). */ |
2257 | |
2258 | static gimple * |
2259 | collect_fallthrough_labels (gimple_stmt_iterator *gsi_p, |
2260 | auto_vec <struct label_entry> *labels, |
2261 | location_t *prevloc) |
2262 | { |
2263 | gimple *prev = NULLnullptr; |
2264 | |
2265 | *prevloc = UNKNOWN_LOCATION((location_t) 0); |
2266 | do |
2267 | { |
2268 | if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND) |
2269 | { |
2270 | /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr, |
2271 | which starts on a GIMPLE_SWITCH and ends with a break label. |
2272 | Handle that as a single statement that can fall through. */ |
2273 | gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p)); |
2274 | gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind)); |
2275 | gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind)); |
2276 | if (last |
2277 | && gimple_code (first) == GIMPLE_SWITCH |
2278 | && gimple_code (last) == GIMPLE_LABEL) |
2279 | { |
2280 | tree label = gimple_label_label (as_a <glabel *> (last)); |
2281 | if (SWITCH_BREAK_LABEL_P (label)((tree_check ((label), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2281, __FUNCTION__, (LABEL_DECL)))->base.protected_flag)) |
2282 | { |
2283 | prev = bind; |
2284 | gsi_next (gsi_p); |
2285 | continue; |
2286 | } |
2287 | } |
2288 | } |
2289 | if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND |
2290 | || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY) |
2291 | { |
2292 | /* Nested scope. Only look at the last statement of |
2293 | the innermost scope. */ |
2294 | location_t bind_loc = gimple_location (gsi_stmt (*gsi_p)); |
2295 | gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p)); |
2296 | if (last) |
2297 | { |
2298 | prev = last; |
2299 | /* It might be a label without a location. Use the |
2300 | location of the scope then. */ |
2301 | if (!gimple_has_location (prev)) |
2302 | *prevloc = bind_loc; |
2303 | } |
2304 | gsi_next (gsi_p); |
2305 | continue; |
2306 | } |
2307 | |
2308 | /* Ifs are tricky. */ |
2309 | if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND) |
2310 | { |
2311 | gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p)); |
2312 | tree false_lab = gimple_cond_false_label (cond_stmt); |
2313 | location_t if_loc = gimple_location (cond_stmt); |
2314 | |
2315 | /* If we have e.g. |
2316 | if (i > 1) goto <D.2259>; else goto D; |
2317 | we can't do much with the else-branch. */ |
2318 | if (!DECL_ARTIFICIAL (false_lab)((contains_struct_check ((false_lab), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2318, __FUNCTION__))->decl_common.artificial_flag)) |
2319 | break; |
2320 | |
2321 | /* Go on until the false label, then one step back. */ |
2322 | for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p)) |
2323 | { |
2324 | gimple *stmt = gsi_stmt (*gsi_p); |
2325 | if (gimple_code (stmt) == GIMPLE_LABEL |
2326 | && gimple_label_label (as_a <glabel *> (stmt)) == false_lab) |
2327 | break; |
2328 | } |
2329 | |
2330 | /* Not found? Oops. */ |
2331 | if (gsi_end_p (*gsi_p)) |
2332 | break; |
2333 | |
2334 | /* A dead label can't fall through. */ |
2335 | if (!UNUSED_LABEL_P (false_lab)((tree_check ((false_lab), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2335, __FUNCTION__, (LABEL_DECL)))->base.default_def_flag )) |
2336 | { |
2337 | struct label_entry l = { false_lab, if_loc }; |
2338 | labels->safe_push (l); |
2339 | } |
2340 | |
2341 | /* Go to the last statement of the then branch. */ |
2342 | gsi_prev (gsi_p); |
2343 | |
2344 | /* if (i != 0) goto <D.1759>; else goto <D.1760>; |
2345 | <D.1759>: |
2346 | <stmt>; |
2347 | goto <D.1761>; |
2348 | <D.1760>: |
2349 | */ |
2350 | if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO |
2351 | && !gimple_has_location (gsi_stmt (*gsi_p))) |
2352 | { |
2353 | /* Look at the statement before, it might be |
2354 | attribute fallthrough, in which case don't warn. */ |
2355 | gsi_prev (gsi_p); |
2356 | bool fallthru_before_dest |
2357 | = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH); |
2358 | gsi_next (gsi_p); |
2359 | tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p)); |
2360 | if (!fallthru_before_dest) |
2361 | { |
2362 | struct label_entry l = { goto_dest, if_loc }; |
2363 | labels->safe_push (l); |
2364 | } |
2365 | } |
2366 | /* This case is about |
2367 | if (1 != 0) goto <D.2022>; else goto <D.2023>; |
2368 | <D.2022>: |
2369 | n = n + 1; // #1 |
2370 | <D.2023>: // #2 |
2371 | <D.1988>: // #3 |
2372 | where #2 is UNUSED_LABEL_P and we want to warn about #1 falling |
2373 | through to #3. So set PREV to #1. */ |
2374 | else if (UNUSED_LABEL_P (false_lab)((tree_check ((false_lab), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2374, __FUNCTION__, (LABEL_DECL)))->base.default_def_flag )) |
2375 | prev = gsi_stmt (*gsi_p); |
2376 | |
2377 | /* And move back. */ |
2378 | gsi_next (gsi_p); |
2379 | } |
2380 | |
2381 | /* Remember the last statement. Skip labels that are of no interest |
2382 | to us. */ |
2383 | if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL) |
2384 | { |
2385 | tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p))); |
2386 | if (find_label_entry (labels, label)) |
2387 | prev = gsi_stmt (*gsi_p); |
2388 | } |
2389 | else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK)) |
2390 | ; |
2391 | else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT) |
2392 | ; |
2393 | else if (!is_gimple_debug (gsi_stmt (*gsi_p))) |
2394 | prev = gsi_stmt (*gsi_p); |
2395 | gsi_next (gsi_p); |
2396 | } |
2397 | while (!gsi_end_p (*gsi_p) |
2398 | /* Stop if we find a case or a user-defined label. */ |
2399 | && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL |
2400 | || !gimple_has_location (gsi_stmt (*gsi_p)))); |
2401 | |
2402 | if (prev && gimple_has_location (prev)) |
2403 | *prevloc = gimple_location (prev); |
2404 | return prev; |
2405 | } |
2406 | |
2407 | /* Return true if the switch fallthough warning should occur. LABEL is |
2408 | the label statement that we're falling through to. */ |
2409 | |
2410 | static bool |
2411 | should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label) |
2412 | { |
2413 | gimple_stmt_iterator gsi = *gsi_p; |
2414 | |
2415 | /* Don't warn if the label is marked with a "falls through" comment. */ |
2416 | if (FALLTHROUGH_LABEL_P (label)((tree_check ((label), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2416, __FUNCTION__, (LABEL_DECL)))->base.private_flag)) |
2417 | return false; |
2418 | |
2419 | /* Don't warn for non-case labels followed by a statement: |
2420 | case 0: |
2421 | foo (); |
2422 | label: |
2423 | bar (); |
2424 | as these are likely intentional. */ |
2425 | if (!case_label_p (&gimplify_ctxp->case_labels, label)) |
2426 | { |
2427 | tree l; |
2428 | while (!gsi_end_p (gsi) |
2429 | && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL |
2430 | && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi)))) |
2431 | && !case_label_p (&gimplify_ctxp->case_labels, l)) |
2432 | gsi_next_nondebug (&gsi); |
2433 | if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL) |
2434 | return false; |
2435 | } |
2436 | |
2437 | /* Don't warn for terminated branches, i.e. when the subsequent case labels |
2438 | immediately breaks. */ |
2439 | gsi = *gsi_p; |
2440 | |
2441 | /* Skip all immediately following labels. */ |
2442 | while (!gsi_end_p (gsi) |
2443 | && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL |
2444 | || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT)) |
2445 | gsi_next_nondebug (&gsi); |
2446 | |
2447 | /* { ... something; default:; } */ |
2448 | if (gsi_end_p (gsi) |
2449 | /* { ... something; default: break; } or |
2450 | { ... something; default: goto L; } */ |
2451 | || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO |
2452 | /* { ... something; default: return; } */ |
2453 | || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN) |
2454 | return false; |
2455 | |
2456 | return true; |
2457 | } |
2458 | |
2459 | /* Callback for walk_gimple_seq. */ |
2460 | |
2461 | static tree |
2462 | warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p, |
2463 | struct walk_stmt_info *) |
2464 | { |
2465 | gimple *stmt = gsi_stmt (*gsi_p); |
2466 | |
2467 | *handled_ops_p = true; |
2468 | switch (gimple_code (stmt)) |
2469 | { |
2470 | case GIMPLE_TRY: |
2471 | case GIMPLE_BIND: |
2472 | case GIMPLE_CATCH: |
2473 | case GIMPLE_EH_FILTER: |
2474 | case GIMPLE_TRANSACTION: |
2475 | /* Walk the sub-statements. */ |
2476 | *handled_ops_p = false; |
2477 | break; |
2478 | |
2479 | /* Find a sequence of form: |
2480 | |
2481 | GIMPLE_LABEL |
2482 | [...] |
2483 | <may fallthru stmt> |
2484 | GIMPLE_LABEL |
2485 | |
2486 | and possibly warn. */ |
2487 | case GIMPLE_LABEL: |
2488 | { |
2489 | /* Found a label. Skip all immediately following labels. */ |
2490 | while (!gsi_end_p (*gsi_p) |
2491 | && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL) |
2492 | gsi_next_nondebug (gsi_p); |
2493 | |
2494 | /* There might be no more statements. */ |
2495 | if (gsi_end_p (*gsi_p)) |
2496 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
2497 | |
2498 | /* Vector of labels that fall through. */ |
2499 | auto_vec <struct label_entry> labels; |
2500 | location_t prevloc; |
2501 | gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc); |
2502 | |
2503 | /* There might be no more statements. */ |
2504 | if (gsi_end_p (*gsi_p)) |
2505 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
2506 | |
2507 | gimple *next = gsi_stmt (*gsi_p); |
2508 | tree label; |
2509 | /* If what follows is a label, then we may have a fallthrough. */ |
2510 | if (gimple_code (next) == GIMPLE_LABEL |
2511 | && gimple_has_location (next) |
2512 | && (label = gimple_label_label (as_a <glabel *> (next))) |
2513 | && prev != NULLnullptr) |
2514 | { |
2515 | struct label_entry *l; |
2516 | bool warned_p = false; |
2517 | auto_diagnostic_group d; |
2518 | if (!should_warn_for_implicit_fallthrough (gsi_p, label)) |
2519 | /* Quiet. */; |
2520 | else if (gimple_code (prev) == GIMPLE_LABEL |
2521 | && (label = gimple_label_label (as_a <glabel *> (prev))) |
2522 | && (l = find_label_entry (&labels, label))) |
2523 | warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_, |
2524 | "this statement may fall through"); |
2525 | else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH) |
2526 | /* Try to be clever and don't warn when the statement |
2527 | can't actually fall through. */ |
2528 | && gimple_stmt_may_fallthru (prev) |
2529 | && prevloc != UNKNOWN_LOCATION((location_t) 0)) |
2530 | warned_p = warning_at (prevloc, |
2531 | OPT_Wimplicit_fallthrough_, |
2532 | "this statement may fall through"); |
2533 | if (warned_p) |
2534 | inform (gimple_location (next), "here"); |
2535 | |
2536 | /* Mark this label as processed so as to prevent multiple |
2537 | warnings in nested switches. */ |
2538 | FALLTHROUGH_LABEL_P (label)((tree_check ((label), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2538, __FUNCTION__, (LABEL_DECL)))->base.private_flag) = true; |
2539 | |
2540 | /* So that next warn_implicit_fallthrough_r will start looking for |
2541 | a new sequence starting with this label. */ |
2542 | gsi_prev (gsi_p); |
2543 | } |
2544 | } |
2545 | break; |
2546 | default: |
2547 | break; |
2548 | } |
2549 | return NULL_TREE(tree) nullptr; |
2550 | } |
2551 | |
2552 | /* Warn when a switch case falls through. */ |
2553 | |
2554 | static void |
2555 | maybe_warn_implicit_fallthrough (gimple_seq seq) |
2556 | { |
2557 | if (!warn_implicit_fallthroughglobal_options.x_warn_implicit_fallthrough) |
2558 | return; |
2559 | |
2560 | /* This warning is meant for C/C++/ObjC/ObjC++ only. */ |
2561 | if (!(lang_GNU_C () |
2562 | || lang_GNU_CXX () |
2563 | || lang_GNU_OBJC ())) |
2564 | return; |
2565 | |
2566 | struct walk_stmt_info wi; |
2567 | memset (&wi, 0, sizeof (wi)); |
2568 | walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULLnullptr, &wi); |
2569 | } |
2570 | |
2571 | /* Callback for walk_gimple_seq. */ |
2572 | |
2573 | static tree |
2574 | expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p, |
2575 | struct walk_stmt_info *wi) |
2576 | { |
2577 | gimple *stmt = gsi_stmt (*gsi_p); |
2578 | |
2579 | *handled_ops_p = true; |
2580 | switch (gimple_code (stmt)) |
2581 | { |
2582 | case GIMPLE_TRY: |
2583 | case GIMPLE_BIND: |
2584 | case GIMPLE_CATCH: |
2585 | case GIMPLE_EH_FILTER: |
2586 | case GIMPLE_TRANSACTION: |
2587 | /* Walk the sub-statements. */ |
2588 | *handled_ops_p = false; |
2589 | break; |
2590 | case GIMPLE_CALL: |
2591 | if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH)) |
2592 | { |
2593 | gsi_remove (gsi_p, true); |
2594 | if (gsi_end_p (*gsi_p)) |
2595 | { |
2596 | *static_cast<location_t *>(wi->info) = gimple_location (stmt); |
2597 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
2598 | } |
2599 | |
2600 | bool found = false; |
2601 | location_t loc = gimple_location (stmt); |
2602 | |
2603 | gimple_stmt_iterator gsi2 = *gsi_p; |
2604 | stmt = gsi_stmt (gsi2); |
2605 | if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt)) |
2606 | { |
2607 | /* Go on until the artificial label. */ |
2608 | tree goto_dest = gimple_goto_dest (stmt); |
2609 | for (; !gsi_end_p (gsi2); gsi_next (&gsi2)) |
2610 | { |
2611 | if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL |
2612 | && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2))) |
2613 | == goto_dest) |
2614 | break; |
2615 | } |
2616 | |
2617 | /* Not found? Stop. */ |
2618 | if (gsi_end_p (gsi2)) |
2619 | break; |
2620 | |
2621 | /* Look one past it. */ |
2622 | gsi_next (&gsi2); |
2623 | } |
2624 | |
2625 | /* We're looking for a case label or default label here. */ |
2626 | while (!gsi_end_p (gsi2)) |
2627 | { |
2628 | stmt = gsi_stmt (gsi2); |
2629 | if (gimple_code (stmt) == GIMPLE_LABEL) |
2630 | { |
2631 | tree label = gimple_label_label (as_a <glabel *> (stmt)); |
2632 | if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label)((contains_struct_check ((label), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2632, __FUNCTION__))->decl_common.artificial_flag)) |
2633 | { |
2634 | found = true; |
2635 | break; |
2636 | } |
2637 | } |
2638 | else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK)) |
2639 | ; |
2640 | else if (!is_gimple_debug (stmt)) |
2641 | /* Anything else is not expected. */ |
2642 | break; |
2643 | gsi_next (&gsi2); |
2644 | } |
2645 | if (!found) |
2646 | pedwarn (loc, 0, "attribute %<fallthrough%> not preceding " |
2647 | "a case label or default label"); |
2648 | } |
2649 | break; |
2650 | default: |
2651 | break; |
2652 | } |
2653 | return NULL_TREE(tree) nullptr; |
2654 | } |
2655 | |
2656 | /* Expand all FALLTHROUGH () calls in SEQ. */ |
2657 | |
2658 | static void |
2659 | expand_FALLTHROUGH (gimple_seq *seq_p) |
2660 | { |
2661 | struct walk_stmt_info wi; |
2662 | location_t loc; |
2663 | memset (&wi, 0, sizeof (wi)); |
2664 | wi.info = (void *) &loc; |
2665 | walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULLnullptr, &wi); |
2666 | if (wi.callback_result == integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]) |
2667 | /* We've found [[fallthrough]]; at the end of a switch, which the C++ |
2668 | standard says is ill-formed; see [dcl.attr.fallthrough]. */ |
2669 | pedwarn (loc, 0, "attribute %<fallthrough%> not preceding " |
2670 | "a case label or default label"); |
2671 | } |
2672 | |
2673 | |
2674 | /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can |
2675 | branch to. */ |
2676 | |
2677 | static enum gimplify_status |
2678 | gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p) |
2679 | { |
2680 | tree switch_expr = *expr_p; |
2681 | gimple_seq switch_body_seq = NULLnullptr; |
2682 | enum gimplify_status ret; |
2683 | tree index_type = TREE_TYPE (switch_expr)((contains_struct_check ((switch_expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2683, __FUNCTION__))->typed.type); |
2684 | if (index_type == NULL_TREE(tree) nullptr) |
2685 | index_type = TREE_TYPE (SWITCH_COND (switch_expr))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check (((tree_check ((switch_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2685, __FUNCTION__, (SWITCH_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2685, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2685, __FUNCTION__))->typed.type); |
2686 | |
2687 | ret = gimplify_expr (&SWITCH_COND (switch_expr)(*((const_cast<tree*> (tree_operand_check (((tree_check ((switch_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2687, __FUNCTION__, (SWITCH_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2687, __FUNCTION__))))), pre_p, NULLnullptr, is_gimple_val, |
2688 | fb_rvalue); |
2689 | if (ret == GS_ERROR || ret == GS_UNHANDLED) |
2690 | return ret; |
2691 | |
2692 | if (SWITCH_BODY (switch_expr)(*((const_cast<tree*> (tree_operand_check (((tree_check ((switch_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2692, __FUNCTION__, (SWITCH_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2692, __FUNCTION__)))))) |
2693 | { |
2694 | vec<tree> labels; |
2695 | vec<tree> saved_labels; |
2696 | hash_set<tree> *saved_live_switch_vars = NULLnullptr; |
2697 | tree default_case = NULL_TREE(tree) nullptr; |
2698 | gswitch *switch_stmt; |
2699 | |
2700 | /* Save old labels, get new ones from body, then restore the old |
2701 | labels. Save all the things from the switch body to append after. */ |
2702 | saved_labels = gimplify_ctxp->case_labels; |
2703 | gimplify_ctxp->case_labels.create (8); |
2704 | |
2705 | /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */ |
2706 | saved_live_switch_vars = gimplify_ctxp->live_switch_vars; |
2707 | tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check (((tree_check ((switch_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2707, __FUNCTION__, (SWITCH_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2707, __FUNCTION__))))))->base.code); |
2708 | if (body_type == BIND_EXPR || body_type == STATEMENT_LIST) |
2709 | gimplify_ctxp->live_switch_vars = new hash_set<tree> (4); |
2710 | else |
2711 | gimplify_ctxp->live_switch_vars = NULLnullptr; |
2712 | |
2713 | bool old_in_switch_expr = gimplify_ctxp->in_switch_expr; |
2714 | gimplify_ctxp->in_switch_expr = true; |
2715 | |
2716 | gimplify_stmt (&SWITCH_BODY (switch_expr)(*((const_cast<tree*> (tree_operand_check (((tree_check ((switch_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2716, __FUNCTION__, (SWITCH_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2716, __FUNCTION__))))), &switch_body_seq); |
2717 | |
2718 | gimplify_ctxp->in_switch_expr = old_in_switch_expr; |
2719 | maybe_warn_switch_unreachable_and_auto_init (switch_body_seq); |
2720 | maybe_warn_implicit_fallthrough (switch_body_seq); |
2721 | /* Only do this for the outermost GIMPLE_SWITCH. */ |
2722 | if (!gimplify_ctxp->in_switch_expr) |
2723 | expand_FALLTHROUGH (&switch_body_seq); |
2724 | |
2725 | labels = gimplify_ctxp->case_labels; |
2726 | gimplify_ctxp->case_labels = saved_labels; |
2727 | |
2728 | if (gimplify_ctxp->live_switch_vars) |
2729 | { |
2730 | gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ())((void)(!(gimplify_ctxp->live_switch_vars->is_empty ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2730, __FUNCTION__), 0 : 0)); |
2731 | delete gimplify_ctxp->live_switch_vars; |
2732 | } |
2733 | gimplify_ctxp->live_switch_vars = saved_live_switch_vars; |
2734 | |
2735 | preprocess_case_label_vec_for_gimple (labels, index_type, |
2736 | &default_case); |
2737 | |
2738 | bool add_bind = false; |
2739 | if (!default_case) |
2740 | { |
2741 | glabel *new_default; |
2742 | |
2743 | default_case |
2744 | = build_case_label (NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr, |
2745 | create_artificial_label (UNKNOWN_LOCATION((location_t) 0))); |
2746 | if (old_in_switch_expr) |
2747 | { |
2748 | SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case))((tree_check (((*((const_cast<tree*> (tree_operand_check (((tree_check ((default_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2748, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2748, __FUNCTION__)))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2748, __FUNCTION__, (LABEL_DECL)))->base.protected_flag) = 1; |
2749 | add_bind = true; |
2750 | } |
2751 | new_default = gimple_build_label (CASE_LABEL (default_case)(*((const_cast<tree*> (tree_operand_check (((tree_check ((default_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2751, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2751, __FUNCTION__)))))); |
2752 | gimplify_seq_add_stmt (&switch_body_seq, new_default); |
2753 | } |
2754 | else if (old_in_switch_expr) |
2755 | { |
2756 | gimple *last = gimple_seq_last_stmt (switch_body_seq); |
2757 | if (last && gimple_code (last) == GIMPLE_LABEL) |
2758 | { |
2759 | tree label = gimple_label_label (as_a <glabel *> (last)); |
2760 | if (SWITCH_BREAK_LABEL_P (label)((tree_check ((label), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2760, __FUNCTION__, (LABEL_DECL)))->base.protected_flag)) |
2761 | add_bind = true; |
2762 | } |
2763 | } |
2764 | |
2765 | switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr)(*((const_cast<tree*> (tree_operand_check (((tree_check ((switch_expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2765, __FUNCTION__, (SWITCH_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2765, __FUNCTION__))))), |
2766 | default_case, labels); |
2767 | /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq |
2768 | ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL, |
2769 | wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND, |
2770 | so that we can easily find the start and end of the switch |
2771 | statement. */ |
2772 | if (add_bind) |
2773 | { |
2774 | gimple_seq bind_body = NULLnullptr; |
2775 | gimplify_seq_add_stmt (&bind_body, switch_stmt); |
2776 | gimple_seq_add_seq (&bind_body, switch_body_seq); |
2777 | gbind *bind = gimple_build_bind (NULL_TREE(tree) nullptr, bind_body, NULL_TREE(tree) nullptr); |
2778 | gimple_set_location (bind, EXPR_LOCATION (switch_expr)((((switch_expr)) && ((tree_code_type_tmpl <0>:: tree_code_type[(int) (((enum tree_code) ((switch_expr))->base .code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((switch_expr ))->base.code))]) <= tcc_expression)) ? (switch_expr)-> exp.locus : ((location_t) 0))); |
2779 | gimplify_seq_add_stmt (pre_p, bind); |
2780 | } |
2781 | else |
2782 | { |
2783 | gimplify_seq_add_stmt (pre_p, switch_stmt); |
2784 | gimplify_seq_add_seq (pre_p, switch_body_seq); |
2785 | } |
2786 | labels.release (); |
2787 | } |
2788 | else |
2789 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2789, __FUNCTION__)); |
2790 | |
2791 | return GS_ALL_DONE; |
2792 | } |
2793 | |
2794 | /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */ |
2795 | |
2796 | static enum gimplify_status |
2797 | gimplify_label_expr (tree *expr_p, gimple_seq *pre_p) |
2798 | { |
2799 | gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))((void)(!(decl_function_context ((*((const_cast<tree*> ( tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2799, __FUNCTION__, (LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2799, __FUNCTION__)))))) == current_function_decl) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2800, __FUNCTION__), 0 : 0)) |
2800 | == current_function_decl)((void)(!(decl_function_context ((*((const_cast<tree*> ( tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2799, __FUNCTION__, (LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2799, __FUNCTION__)))))) == current_function_decl) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2800, __FUNCTION__), 0 : 0)); |
2801 | |
2802 | tree label = LABEL_EXPR_LABEL (*expr_p)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2802, __FUNCTION__, (LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2802, __FUNCTION__))))); |
2803 | glabel *label_stmt = gimple_build_label (label); |
2804 | gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 ))); |
2805 | gimplify_seq_add_stmt (pre_p, label_stmt); |
2806 | |
2807 | if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)((contains_struct_check ((label), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2807, __FUNCTION__))->decl_common.attributes))) |
2808 | gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL, |
2809 | NOT_TAKEN)); |
2810 | else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)((contains_struct_check ((label), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2810, __FUNCTION__))->decl_common.attributes))) |
2811 | gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL, |
2812 | TAKEN)); |
2813 | |
2814 | return GS_ALL_DONE; |
2815 | } |
2816 | |
2817 | /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */ |
2818 | |
2819 | static enum gimplify_status |
2820 | gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p) |
2821 | { |
2822 | struct gimplify_ctx *ctxp; |
2823 | glabel *label_stmt; |
2824 | |
2825 | /* Invalid programs can play Duff's Device type games with, for example, |
2826 | #pragma omp parallel. At least in the C front end, we don't |
2827 | detect such invalid branches until after gimplification, in the |
2828 | diagnose_omp_blocks pass. */ |
2829 | for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context) |
2830 | if (ctxp->case_labels.exists ()) |
2831 | break; |
2832 | |
2833 | tree label = CASE_LABEL (*expr_p)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2833, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2833, __FUNCTION__))))); |
2834 | label_stmt = gimple_build_label (label); |
2835 | gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 ))); |
2836 | ctxp->case_labels.safe_push (*expr_p); |
2837 | gimplify_seq_add_stmt (pre_p, label_stmt); |
2838 | |
2839 | if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)((contains_struct_check ((label), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2839, __FUNCTION__))->decl_common.attributes))) |
2840 | gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL, |
2841 | NOT_TAKEN)); |
2842 | else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)((contains_struct_check ((label), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2842, __FUNCTION__))->decl_common.attributes))) |
2843 | gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL, |
2844 | TAKEN)); |
2845 | |
2846 | return GS_ALL_DONE; |
2847 | } |
2848 | |
2849 | /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first |
2850 | if necessary. */ |
2851 | |
2852 | tree |
2853 | build_and_jump (tree *label_p) |
2854 | { |
2855 | if (label_p == NULLnullptr) |
2856 | /* If there's nowhere to jump, just fall through. */ |
2857 | return NULL_TREE(tree) nullptr; |
2858 | |
2859 | if (*label_p == NULL_TREE(tree) nullptr) |
2860 | { |
2861 | tree label = create_artificial_label (UNKNOWN_LOCATION((location_t) 0)); |
2862 | *label_p = label; |
2863 | } |
2864 | |
2865 | return build1 (GOTO_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], *label_p); |
2866 | } |
2867 | |
2868 | /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR. |
2869 | This also involves building a label to jump to and communicating it to |
2870 | gimplify_loop_expr through gimplify_ctxp->exit_label. */ |
2871 | |
2872 | static enum gimplify_status |
2873 | gimplify_exit_expr (tree *expr_p) |
2874 | { |
2875 | tree cond = TREE_OPERAND (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2875, __FUNCTION__))))); |
2876 | tree expr; |
2877 | |
2878 | expr = build_and_jump (&gimplify_ctxp->exit_label); |
2879 | expr = build3 (COND_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], cond, expr, NULL_TREE(tree) nullptr); |
2880 | *expr_p = expr; |
2881 | |
2882 | return GS_OK; |
2883 | } |
2884 | |
2885 | /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is |
2886 | different from its canonical type, wrap the whole thing inside a |
2887 | NOP_EXPR and force the type of the COMPONENT_REF to be the canonical |
2888 | type. |
2889 | |
2890 | The canonical type of a COMPONENT_REF is the type of the field being |
2891 | referenced--unless the field is a bit-field which can be read directly |
2892 | in a smaller mode, in which case the canonical type is the |
2893 | sign-appropriate type corresponding to that mode. */ |
2894 | |
2895 | static void |
2896 | canonicalize_component_ref (tree *expr_p) |
2897 | { |
2898 | tree expr = *expr_p; |
2899 | tree type; |
2900 | |
2901 | gcc_assert (TREE_CODE (expr) == COMPONENT_REF)((void)(!(((enum tree_code) (expr)->base.code) == COMPONENT_REF ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2901, __FUNCTION__), 0 : 0)); |
2902 | |
2903 | if (INTEGRAL_TYPE_P (TREE_TYPE (expr))(((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2903, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2903, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2903, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE )) |
2904 | type = TREE_TYPE (get_unwidened (expr, NULL_TREE))((contains_struct_check ((get_unwidened (expr, (tree) nullptr )), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2904, __FUNCTION__))->typed.type); |
2905 | else |
2906 | type = TREE_TYPE (TREE_OPERAND (expr, 1))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2906, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2906, __FUNCTION__))->typed.type); |
2907 | |
2908 | /* One could argue that all the stuff below is not necessary for |
2909 | the non-bitfield case and declare it a FE error if type |
2910 | adjustment would be needed. */ |
2911 | if (TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2911, __FUNCTION__))->typed.type) != type) |
2912 | { |
2913 | #ifdef ENABLE_TYPES_CHECKING1 |
2914 | tree old_type = TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2914, __FUNCTION__))->typed.type); |
2915 | #endif |
2916 | int type_quals; |
2917 | |
2918 | /* We need to preserve qualifiers and propagate them from |
2919 | operand 0. */ |
2920 | type_quals = TYPE_QUALS (type)((int) ((((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2920, __FUNCTION__))->base.readonly_flag) * TYPE_QUAL_CONST ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2920, __FUNCTION__))->base.volatile_flag) * TYPE_QUAL_VOLATILE ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2920, __FUNCTION__))->base.u.bits.atomic_flag) * TYPE_QUAL_ATOMIC ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2920, __FUNCTION__))->type_common.restrict_flag) * TYPE_QUAL_RESTRICT ) | (((((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2920, __FUNCTION__))->base.u.bits.address_space) & 0xFF ) << 8)))) |
2921 | | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)))((int) ((((tree_class_check ((((contains_struct_check (((*((const_cast <tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__))->base.readonly_flag) * TYPE_QUAL_CONST ) | (((tree_class_check ((((contains_struct_check (((*((const_cast <tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__))->base.volatile_flag) * TYPE_QUAL_VOLATILE ) | (((tree_class_check ((((contains_struct_check (((*((const_cast <tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__))->base.u.bits.atomic_flag) * TYPE_QUAL_ATOMIC ) | (((tree_class_check ((((contains_struct_check (((*((const_cast <tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__))->type_common.restrict_flag) * TYPE_QUAL_RESTRICT ) | (((((tree_class_check ((((contains_struct_check (((*((const_cast <tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2921, __FUNCTION__))->base.u.bits.address_space) & 0xFF ) << 8)))); |
2922 | if (TYPE_QUALS (type)((int) ((((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2922, __FUNCTION__))->base.readonly_flag) * TYPE_QUAL_CONST ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2922, __FUNCTION__))->base.volatile_flag) * TYPE_QUAL_VOLATILE ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2922, __FUNCTION__))->base.u.bits.atomic_flag) * TYPE_QUAL_ATOMIC ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2922, __FUNCTION__))->type_common.restrict_flag) * TYPE_QUAL_RESTRICT ) | (((((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2922, __FUNCTION__))->base.u.bits.address_space) & 0xFF ) << 8)))) != type_quals) |
2923 | type = build_qualified_type (TYPE_MAIN_VARIANT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2923, __FUNCTION__))->type_common.main_variant), type_quals); |
2924 | |
2925 | /* Set the type of the COMPONENT_REF to the underlying type. */ |
2926 | TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2926, __FUNCTION__))->typed.type) = type; |
2927 | |
2928 | #ifdef ENABLE_TYPES_CHECKING1 |
2929 | /* It is now a FE error, if the conversion from the canonical |
2930 | type to the original expression type is not useless. */ |
2931 | gcc_assert (useless_type_conversion_p (old_type, type))((void)(!(useless_type_conversion_p (old_type, type)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2931, __FUNCTION__), 0 : 0)); |
2932 | #endif |
2933 | } |
2934 | } |
2935 | |
2936 | /* If a NOP conversion is changing a pointer to array of foo to a pointer |
2937 | to foo, embed that change in the ADDR_EXPR by converting |
2938 | T array[U]; |
2939 | (T *)&array |
2940 | ==> |
2941 | &array[L] |
2942 | where L is the lower bound. For simplicity, only do this for constant |
2943 | lower bound. |
2944 | The constraint is that the type of &array[L] is trivially convertible |
2945 | to T *. */ |
2946 | |
2947 | static void |
2948 | canonicalize_addr_expr (tree *expr_p) |
2949 | { |
2950 | tree expr = *expr_p; |
2951 | tree addr_expr = TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2951, __FUNCTION__))))); |
2952 | tree datype, ddatype, pddatype; |
2953 | |
2954 | /* We simplify only conversions from an ADDR_EXPR to a pointer type. */ |
2955 | if (!POINTER_TYPE_P (TREE_TYPE (expr))(((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2955, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2955, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE ) |
2956 | || TREE_CODE (addr_expr)((enum tree_code) (addr_expr)->base.code) != ADDR_EXPR) |
2957 | return; |
2958 | |
2959 | /* The addr_expr type should be a pointer to an array. */ |
2960 | datype = TREE_TYPE (TREE_TYPE (addr_expr))((contains_struct_check ((((contains_struct_check ((addr_expr ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2960, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2960, __FUNCTION__))->typed.type); |
2961 | if (TREE_CODE (datype)((enum tree_code) (datype)->base.code) != ARRAY_TYPE) |
2962 | return; |
2963 | |
2964 | /* The pointer to element type shall be trivially convertible to |
2965 | the expression pointer type. */ |
2966 | ddatype = TREE_TYPE (datype)((contains_struct_check ((datype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2966, __FUNCTION__))->typed.type); |
2967 | pddatype = build_pointer_type (ddatype); |
2968 | if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr))((tree_class_check ((((contains_struct_check ((expr), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2968, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2968, __FUNCTION__))->type_common.main_variant), |
2969 | pddatype)) |
2970 | return; |
2971 | |
2972 | /* The lower bound and element sizes must be constant. */ |
2973 | if (!TYPE_SIZE_UNIT (ddatype)((tree_class_check ((ddatype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2973, __FUNCTION__))->type_common.size_unit) |
2974 | || TREE_CODE (TYPE_SIZE_UNIT (ddatype))((enum tree_code) (((tree_class_check ((ddatype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2974, __FUNCTION__))->type_common.size_unit))->base.code ) != INTEGER_CST |
2975 | || !TYPE_DOMAIN (datype)((tree_check ((datype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2975, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values ) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))((tree_check5 ((((tree_check ((datype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2975, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2975, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval ) |
2976 | || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype)))((enum tree_code) (((tree_check5 ((((tree_check ((datype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2976, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2976, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval ))->base.code) != INTEGER_CST) |
2977 | return; |
2978 | |
2979 | /* All checks succeeded. Build a new node to merge the cast. */ |
2980 | *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0)(*((const_cast<tree*> (tree_operand_check ((addr_expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2980, __FUNCTION__))))), |
2981 | TYPE_MIN_VALUE (TYPE_DOMAIN (datype))((tree_check5 ((((tree_check ((datype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2981, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2981, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval ), |
2982 | NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr); |
2983 | *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p); |
2984 | |
2985 | /* We can have stripped a required restrict qualifier above. */ |
2986 | if (!useless_type_conversion_p (TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2986, __FUNCTION__))->typed.type), TREE_TYPE (*expr_p)((contains_struct_check ((*expr_p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2986, __FUNCTION__))->typed.type))) |
2987 | *expr_p = fold_convert (TREE_TYPE (expr), *expr_p)fold_convert_loc (((location_t) 0), ((contains_struct_check ( (expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2987, __FUNCTION__))->typed.type), *expr_p); |
2988 | } |
2989 | |
2990 | /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions |
2991 | underneath as appropriate. */ |
2992 | |
2993 | static enum gimplify_status |
2994 | gimplify_conversion (tree *expr_p) |
2995 | { |
2996 | location_t loc = EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 )); |
2997 | gcc_assert (CONVERT_EXPR_P (*expr_p))((void)(!(((((enum tree_code) (*expr_p)->base.code)) == NOP_EXPR || (((enum tree_code) (*expr_p)->base.code)) == CONVERT_EXPR )) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 2997, __FUNCTION__), 0 : 0)); |
2998 | |
2999 | /* Then strip away all but the outermost conversion. */ |
3000 | STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0))((*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3000, __FUNCTION__)))))) = tree_strip_sign_nop_conversions ( (const_cast<union tree_node *> ((((*((const_cast<tree *> (tree_operand_check ((*expr_p), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3000, __FUNCTION__)))))))))); |
3001 | |
3002 | /* And remove the outermost conversion if it's useless. */ |
3003 | if (tree_ssa_useless_type_conversion (*expr_p)) |
3004 | *expr_p = TREE_OPERAND (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3004, __FUNCTION__))))); |
3005 | |
3006 | /* If we still have a conversion at the toplevel, |
3007 | then canonicalize some constructs. */ |
3008 | if (CONVERT_EXPR_P (*expr_p)((((enum tree_code) (*expr_p)->base.code)) == NOP_EXPR || ( ((enum tree_code) (*expr_p)->base.code)) == CONVERT_EXPR)) |
3009 | { |
3010 | tree sub = TREE_OPERAND (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3010, __FUNCTION__))))); |
3011 | |
3012 | /* If a NOP conversion is changing the type of a COMPONENT_REF |
3013 | expression, then canonicalize its type now in order to expose more |
3014 | redundant conversions. */ |
3015 | if (TREE_CODE (sub)((enum tree_code) (sub)->base.code) == COMPONENT_REF) |
3016 | canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3016, __FUNCTION__)))))); |
3017 | |
3018 | /* If a NOP conversion is changing a pointer to array of foo |
3019 | to a pointer to foo, embed that change in the ADDR_EXPR. */ |
3020 | else if (TREE_CODE (sub)((enum tree_code) (sub)->base.code) == ADDR_EXPR) |
3021 | canonicalize_addr_expr (expr_p); |
3022 | } |
3023 | |
3024 | /* If we have a conversion to a non-register type force the |
3025 | use of a VIEW_CONVERT_EXPR instead. */ |
3026 | if (CONVERT_EXPR_P (*expr_p)((((enum tree_code) (*expr_p)->base.code)) == NOP_EXPR || ( ((enum tree_code) (*expr_p)->base.code)) == CONVERT_EXPR) && !is_gimple_reg_type (TREE_TYPE (*expr_p)((contains_struct_check ((*expr_p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3026, __FUNCTION__))->typed.type))) |
3027 | *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p)((contains_struct_check ((*expr_p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3027, __FUNCTION__))->typed.type), |
3028 | TREE_OPERAND (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3028, __FUNCTION__)))))); |
3029 | |
3030 | /* Canonicalize CONVERT_EXPR to NOP_EXPR. */ |
3031 | if (TREE_CODE (*expr_p)((enum tree_code) (*expr_p)->base.code) == CONVERT_EXPR) |
3032 | TREE_SET_CODE (*expr_p, NOP_EXPR)((*expr_p)->base.code = (NOP_EXPR)); |
3033 | |
3034 | return GS_OK; |
3035 | } |
3036 | |
3037 | /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a |
3038 | DECL_VALUE_EXPR, and it's worth re-examining things. */ |
3039 | |
3040 | static enum gimplify_status |
3041 | gimplify_var_or_parm_decl (tree *expr_p) |
3042 | { |
3043 | tree decl = *expr_p; |
3044 | |
3045 | /* ??? If this is a local variable, and it has not been seen in any |
3046 | outer BIND_EXPR, then it's probably the result of a duplicate |
3047 | declaration, for which we've already issued an error. It would |
3048 | be really nice if the front end wouldn't leak these at all. |
3049 | Currently the only known culprit is C++ destructors, as seen |
3050 | in g++.old-deja/g++.jason/binding.C. |
3051 | Another possible culpit are size expressions for variably modified |
3052 | types which are lost in the FE or not gimplified correctly. */ |
3053 | if (VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL) |
3054 | && !DECL_SEEN_IN_BIND_EXPR_P (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3054, __FUNCTION__))->decl_with_vis.seen_in_bind_expr) |
3055 | && !TREE_STATIC (decl)((decl)->base.static_flag) && !DECL_EXTERNAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3055, __FUNCTION__))->decl_common.decl_flag_1) |
3056 | && decl_function_context (decl) == current_function_decl) |
3057 | { |
3058 | gcc_assert (seen_error ())((void)(!(seen_error ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3058, __FUNCTION__), 0 : 0)); |
3059 | return GS_ERROR; |
3060 | } |
3061 | |
3062 | /* When within an OMP context, notice uses of variables. */ |
3063 | if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true)) |
3064 | return GS_ALL_DONE; |
3065 | |
3066 | /* If the decl is an alias for another expression, substitute it now. */ |
3067 | if (DECL_HAS_VALUE_EXPR_P (decl)((tree_check3 ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3067, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL)) ) ->decl_common.decl_flag_2)) |
3068 | { |
3069 | *expr_p = unshare_expr (DECL_VALUE_EXPR (decl)(decl_value_expr_lookup ((contains_struct_check ((decl), (TS_DECL_WRTL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3069, __FUNCTION__))))); |
3070 | return GS_OK; |
3071 | } |
3072 | |
3073 | return GS_ALL_DONE; |
3074 | } |
3075 | |
3076 | /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */ |
3077 | |
3078 | static void |
3079 | recalculate_side_effects (tree t) |
3080 | { |
3081 | enum tree_code code = TREE_CODE (t)((enum tree_code) (t)->base.code); |
3082 | int len = TREE_OPERAND_LENGTH (t)tree_operand_length (t); |
3083 | int i; |
3084 | |
3085 | switch (TREE_CODE_CLASS (code)tree_code_type_tmpl <0>::tree_code_type[(int) (code)]) |
3086 | { |
3087 | case tcc_expression: |
3088 | switch (code) |
3089 | { |
3090 | case INIT_EXPR: |
3091 | case MODIFY_EXPR: |
3092 | case VA_ARG_EXPR: |
3093 | case PREDECREMENT_EXPR: |
3094 | case PREINCREMENT_EXPR: |
3095 | case POSTDECREMENT_EXPR: |
3096 | case POSTINCREMENT_EXPR: |
3097 | /* All of these have side-effects, no matter what their |
3098 | operands are. */ |
3099 | return; |
3100 | |
3101 | default: |
3102 | break; |
3103 | } |
3104 | /* Fall through. */ |
3105 | |
3106 | case tcc_comparison: /* a comparison expression */ |
3107 | case tcc_unary: /* a unary arithmetic expression */ |
3108 | case tcc_binary: /* a binary arithmetic expression */ |
3109 | case tcc_reference: /* a reference */ |
3110 | case tcc_vl_exp: /* a function call */ |
3111 | TREE_SIDE_EFFECTS (t)((non_type_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3111, __FUNCTION__))->base.side_effects_flag) = TREE_THIS_VOLATILE (t)((t)->base.volatile_flag); |
3112 | for (i = 0; i < len; ++i) |
3113 | { |
3114 | tree op = TREE_OPERAND (t, i)(*((const_cast<tree*> (tree_operand_check ((t), (i), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3114, __FUNCTION__))))); |
3115 | if (op && TREE_SIDE_EFFECTS (op)((non_type_check ((op), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3115, __FUNCTION__))->base.side_effects_flag)) |
3116 | TREE_SIDE_EFFECTS (t)((non_type_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3116, __FUNCTION__))->base.side_effects_flag) = 1; |
3117 | } |
3118 | break; |
3119 | |
3120 | case tcc_constant: |
3121 | /* No side-effects. */ |
3122 | return; |
3123 | |
3124 | default: |
3125 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3125, __FUNCTION__)); |
3126 | } |
3127 | } |
3128 | |
3129 | /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR |
3130 | node *EXPR_P. |
3131 | |
3132 | compound_lval |
3133 | : min_lval '[' val ']' |
3134 | | min_lval '.' ID |
3135 | | compound_lval '[' val ']' |
3136 | | compound_lval '.' ID |
3137 | |
3138 | This is not part of the original SIMPLE definition, which separates |
3139 | array and member references, but it seems reasonable to handle them |
3140 | together. Also, this way we don't run into problems with union |
3141 | aliasing; gcc requires that for accesses through a union to alias, the |
3142 | union reference must be explicit, which was not always the case when we |
3143 | were splitting up array and member refs. |
3144 | |
3145 | PRE_P points to the sequence where side effects that must happen before |
3146 | *EXPR_P should be stored. |
3147 | |
3148 | POST_P points to the sequence where side effects that must happen after |
3149 | *EXPR_P should be stored. */ |
3150 | |
3151 | static enum gimplify_status |
3152 | gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, |
3153 | fallback_t fallback) |
3154 | { |
3155 | tree *p; |
3156 | enum gimplify_status ret = GS_ALL_DONE, tret; |
3157 | int i; |
3158 | location_t loc = EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 )); |
3159 | tree expr = *expr_p; |
3160 | |
3161 | /* Create a stack of the subexpressions so later we can walk them in |
3162 | order from inner to outer. */ |
3163 | auto_vec<tree, 10> expr_stack; |
3164 | |
3165 | /* We can handle anything that get_inner_reference can deal with. */ |
3166 | for (p = expr_p; ; p = &TREE_OPERAND (*p, 0)(*((const_cast<tree*> (tree_operand_check ((*p), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3166, __FUNCTION__)))))) |
3167 | { |
3168 | restart: |
3169 | /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */ |
3170 | if (TREE_CODE (*p)((enum tree_code) (*p)->base.code) == INDIRECT_REF) |
3171 | *p = fold_indirect_ref_loc (loc, *p); |
3172 | |
3173 | if (handled_component_p (*p)) |
3174 | ; |
3175 | /* Expand DECL_VALUE_EXPR now. In some cases that may expose |
3176 | additional COMPONENT_REFs. */ |
3177 | else if ((VAR_P (*p)(((enum tree_code) (*p)->base.code) == VAR_DECL) || TREE_CODE (*p)((enum tree_code) (*p)->base.code) == PARM_DECL) |
3178 | && gimplify_var_or_parm_decl (p) == GS_OK) |
3179 | goto restart; |
3180 | else |
3181 | break; |
3182 | |
3183 | expr_stack.safe_push (*p); |
3184 | } |
3185 | |
3186 | gcc_assert (expr_stack.length ())((void)(!(expr_stack.length ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3186, __FUNCTION__), 0 : 0)); |
3187 | |
3188 | /* Now EXPR_STACK is a stack of pointers to all the refs we've |
3189 | walked through and P points to the innermost expression. |
3190 | |
3191 | Java requires that we elaborated nodes in source order. That |
3192 | means we must gimplify the inner expression followed by each of |
3193 | the indices, in order. But we can't gimplify the inner |
3194 | expression until we deal with any variable bounds, sizes, or |
3195 | positions in order to deal with PLACEHOLDER_EXPRs. |
3196 | |
3197 | The base expression may contain a statement expression that |
3198 | has declarations used in size expressions, so has to be |
3199 | gimplified before gimplifying the size expressions. |
3200 | |
3201 | So we do this in three steps. First we deal with variable |
3202 | bounds, sizes, and positions, then we gimplify the base and |
3203 | ensure it is memory if needed, then we deal with the annotations |
3204 | for any variables in the components and any indices, from left |
3205 | to right. */ |
3206 | |
3207 | bool need_non_reg = false; |
3208 | for (i = expr_stack.length () - 1; i >= 0; i--) |
3209 | { |
3210 | tree t = expr_stack[i]; |
3211 | |
3212 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == ARRAY_REF || TREE_CODE (t)((enum tree_code) (t)->base.code) == ARRAY_RANGE_REF) |
3213 | { |
3214 | /* Deal with the low bound and element type size and put them into |
3215 | the ARRAY_REF. If these values are set, they have already been |
3216 | gimplified. */ |
3217 | if (TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3217, __FUNCTION__))))) == NULL_TREE(tree) nullptr) |
3218 | { |
3219 | tree low = unshare_expr (array_ref_low_bound (t)); |
3220 | if (!is_gimple_min_invariant (low)) |
3221 | { |
3222 | TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3222, __FUNCTION__))))) = low; |
3223 | } |
3224 | } |
3225 | |
3226 | if (TREE_OPERAND (t, 3)(*((const_cast<tree*> (tree_operand_check ((t), (3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3226, __FUNCTION__))))) == NULL_TREE(tree) nullptr) |
3227 | { |
3228 | tree elmt_size = array_ref_element_size (t); |
3229 | if (!is_gimple_min_invariant (elmt_size)) |
3230 | { |
3231 | elmt_size = unshare_expr (elmt_size); |
3232 | tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)))((contains_struct_check ((((contains_struct_check (((*((const_cast <tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3232, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3232, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3232, __FUNCTION__))->typed.type); |
3233 | tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type))size_int_kind (((((tree_class_check ((elmt_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3233, __FUNCTION__))->type_common.align) ? ((unsigned)1) << (((tree_class_check ((elmt_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3233, __FUNCTION__))->type_common.align) - 1) : 0) / (8) ), stk_sizetype); |
3234 | |
3235 | /* Divide the element size by the alignment of the element |
3236 | type (above). */ |
3237 | elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR, |
3238 | elmt_size, factor); |
3239 | |
3240 | TREE_OPERAND (t, 3)(*((const_cast<tree*> (tree_operand_check ((t), (3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3240, __FUNCTION__))))) = elmt_size; |
3241 | } |
3242 | } |
3243 | need_non_reg = true; |
3244 | } |
3245 | else if (TREE_CODE (t)((enum tree_code) (t)->base.code) == COMPONENT_REF) |
3246 | { |
3247 | /* Set the field offset into T and gimplify it. */ |
3248 | if (TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3248, __FUNCTION__))))) == NULL_TREE(tree) nullptr) |
3249 | { |
3250 | tree offset = component_ref_field_offset (t); |
3251 | if (!is_gimple_min_invariant (offset)) |
3252 | { |
3253 | offset = unshare_expr (offset); |
3254 | tree field = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3254, __FUNCTION__))))); |
3255 | tree factor |
3256 | = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT)size_int_kind ((((unsigned long)1) << (tree_check ((field ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3256, __FUNCTION__, (FIELD_DECL)))->decl_common.off_align ) / (8), stk_sizetype); |
3257 | |
3258 | /* Divide the offset by its alignment. */ |
3259 | offset = size_binop_loc (loc, EXACT_DIV_EXPR, |
3260 | offset, factor); |
3261 | |
3262 | TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3262, __FUNCTION__))))) = offset; |
3263 | } |
3264 | } |
3265 | need_non_reg = true; |
3266 | } |
3267 | } |
3268 | |
3269 | /* Step 2 is to gimplify the base expression. Make sure lvalue is set |
3270 | so as to match the min_lval predicate. Failure to do so may result |
3271 | in the creation of large aggregate temporaries. */ |
3272 | tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, |
3273 | fallback | fb_lvalue); |
3274 | ret = MIN (ret, tret)((ret) < (tret) ? (ret) : (tret)); |
3275 | if (ret == GS_ERROR) |
3276 | return GS_ERROR; |
3277 | |
3278 | /* Step 2a: if we have component references we do not support on |
3279 | registers then make sure the base isn't a register. Of course |
3280 | we can only do so if an rvalue is OK. */ |
3281 | if (need_non_reg && (fallback & fb_rvalue)) |
3282 | prepare_gimple_addressable (p, pre_p); |
3283 | |
3284 | /* Step 3: gimplify size expressions and the indices and operands of |
3285 | ARRAY_REF. During this loop we also remove any useless conversions. */ |
3286 | |
3287 | for (; expr_stack.length () > 0; ) |
3288 | { |
3289 | tree t = expr_stack.pop (); |
3290 | |
3291 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == ARRAY_REF || TREE_CODE (t)((enum tree_code) (t)->base.code) == ARRAY_RANGE_REF) |
3292 | { |
3293 | /* Gimplify the low bound and element type size. */ |
3294 | tret = gimplify_expr (&TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3294, __FUNCTION__))))), pre_p, post_p, |
3295 | is_gimple_reg, fb_rvalue); |
3296 | ret = MIN (ret, tret)((ret) < (tret) ? (ret) : (tret)); |
3297 | |
3298 | tret = gimplify_expr (&TREE_OPERAND (t, 3)(*((const_cast<tree*> (tree_operand_check ((t), (3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3298, __FUNCTION__))))), pre_p, post_p, |
3299 | is_gimple_reg, fb_rvalue); |
3300 | ret = MIN (ret, tret)((ret) < (tret) ? (ret) : (tret)); |
3301 | |
3302 | /* Gimplify the dimension. */ |
3303 | tret = gimplify_expr (&TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3303, __FUNCTION__))))), pre_p, post_p, |
3304 | is_gimple_val, fb_rvalue); |
3305 | ret = MIN (ret, tret)((ret) < (tret) ? (ret) : (tret)); |
3306 | } |
3307 | else if (TREE_CODE (t)((enum tree_code) (t)->base.code) == COMPONENT_REF) |
3308 | { |
3309 | tret = gimplify_expr (&TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3309, __FUNCTION__))))), pre_p, post_p, |
3310 | is_gimple_reg, fb_rvalue); |
3311 | ret = MIN (ret, tret)((ret) < (tret) ? (ret) : (tret)); |
3312 | } |
3313 | |
3314 | STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0))((*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3314, __FUNCTION__)))))) = tree_ssa_strip_useless_type_conversions ((*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3314, __FUNCTION__)))))); |
3315 | |
3316 | /* The innermost expression P may have originally had |
3317 | TREE_SIDE_EFFECTS set which would have caused all the outer |
3318 | expressions in *EXPR_P leading to P to also have had |
3319 | TREE_SIDE_EFFECTS set. */ |
3320 | recalculate_side_effects (t); |
3321 | } |
3322 | |
3323 | /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */ |
3324 | if ((fallback & fb_rvalue) && TREE_CODE (*expr_p)((enum tree_code) (*expr_p)->base.code) == COMPONENT_REF) |
3325 | { |
3326 | canonicalize_component_ref (expr_p); |
3327 | } |
3328 | |
3329 | expr_stack.release (); |
3330 | |
3331 | gcc_assert (*expr_p == expr || ret != GS_ALL_DONE)((void)(!(*expr_p == expr || ret != GS_ALL_DONE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3331, __FUNCTION__), 0 : 0)); |
3332 | |
3333 | return ret; |
3334 | } |
3335 | |
3336 | /* Gimplify the self modifying expression pointed to by EXPR_P |
3337 | (++, --, +=, -=). |
3338 | |
3339 | PRE_P points to the list where side effects that must happen before |
3340 | *EXPR_P should be stored. |
3341 | |
3342 | POST_P points to the list where side effects that must happen after |
3343 | *EXPR_P should be stored. |
3344 | |
3345 | WANT_VALUE is nonzero iff we want to use the value of this expression |
3346 | in another expression. |
3347 | |
3348 | ARITH_TYPE is the type the computation should be performed in. */ |
3349 | |
3350 | enum gimplify_status |
3351 | gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, |
3352 | bool want_value, tree arith_type) |
3353 | { |
3354 | enum tree_code code; |
3355 | tree lhs, lvalue, rhs, t1; |
3356 | gimple_seq post = NULLnullptr, *orig_post_p = post_p; |
3357 | bool postfix; |
3358 | enum tree_code arith_code; |
3359 | enum gimplify_status ret; |
3360 | location_t loc = EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 )); |
3361 | |
3362 | code = TREE_CODE (*expr_p)((enum tree_code) (*expr_p)->base.code); |
3363 | |
3364 | gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR((void)(!(code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3365, __FUNCTION__), 0 : 0)) |
3365 | || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)((void)(!(code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3365, __FUNCTION__), 0 : 0)); |
3366 | |
3367 | /* Prefix or postfix? */ |
3368 | if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) |
3369 | /* Faster to treat as prefix if result is not used. */ |
3370 | postfix = want_value; |
3371 | else |
3372 | postfix = false; |
3373 | |
3374 | /* For postfix, make sure the inner expression's post side effects |
3375 | are executed after side effects from this expression. */ |
3376 | if (postfix) |
3377 | post_p = &post; |
3378 | |
3379 | /* Add or subtract? */ |
3380 | if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) |
3381 | arith_code = PLUS_EXPR; |
3382 | else |
3383 | arith_code = MINUS_EXPR; |
3384 | |
3385 | /* Gimplify the LHS into a GIMPLE lvalue. */ |
3386 | lvalue = TREE_OPERAND (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3386, __FUNCTION__))))); |
3387 | ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue); |
3388 | if (ret == GS_ERROR) |
3389 | return ret; |
3390 | |
3391 | /* Extract the operands to the arithmetic operation. */ |
3392 | lhs = lvalue; |
3393 | rhs = TREE_OPERAND (*expr_p, 1)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3393, __FUNCTION__))))); |
3394 | |
3395 | /* For postfix operator, we evaluate the LHS to an rvalue and then use |
3396 | that as the result value and in the postqueue operation. */ |
3397 | if (postfix) |
3398 | { |
3399 | ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue); |
3400 | if (ret == GS_ERROR) |
3401 | return ret; |
3402 | |
3403 | lhs = get_initialized_tmp_var (lhs, pre_p); |
3404 | } |
3405 | |
3406 | /* For POINTERs increment, use POINTER_PLUS_EXPR. */ |
3407 | if (POINTER_TYPE_P (TREE_TYPE (lhs))(((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3407, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3407, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE )) |
3408 | { |
3409 | rhs = convert_to_ptrofftype_loc (loc, rhs); |
3410 | if (arith_code == MINUS_EXPR) |
3411 | rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs)((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3411, __FUNCTION__))->typed.type), rhs); |
3412 | t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs)fold_build2_loc (((location_t) 0), POINTER_PLUS_EXPR, ((contains_struct_check ((*expr_p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3412, __FUNCTION__))->typed.type), lhs, rhs ); |
3413 | } |
3414 | else |
3415 | t1 = fold_convert (TREE_TYPE (*expr_p),fold_convert_loc (((location_t) 0), ((contains_struct_check ( (*expr_p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3415, __FUNCTION__))->typed.type), fold_build2_loc (((location_t ) 0), arith_code, arith_type, fold_convert_loc (((location_t) 0), arith_type, lhs), fold_convert_loc (((location_t) 0), arith_type , rhs) )) |
3416 | fold_build2 (arith_code, arith_type,fold_convert_loc (((location_t) 0), ((contains_struct_check ( (*expr_p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3415, __FUNCTION__))->typed.type), fold_build2_loc (((location_t ) 0), arith_code, arith_type, fold_convert_loc (((location_t) 0), arith_type, lhs), fold_convert_loc (((location_t) 0), arith_type , rhs) )) |
3417 | fold_convert (arith_type, lhs),fold_convert_loc (((location_t) 0), ((contains_struct_check ( (*expr_p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3415, __FUNCTION__))->typed.type), fold_build2_loc (((location_t ) 0), arith_code, arith_type, fold_convert_loc (((location_t) 0), arith_type, lhs), fold_convert_loc (((location_t) 0), arith_type , rhs) )) |
3418 | fold_convert (arith_type, rhs)))fold_convert_loc (((location_t) 0), ((contains_struct_check ( (*expr_p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3415, __FUNCTION__))->typed.type), fold_build2_loc (((location_t ) 0), arith_code, arith_type, fold_convert_loc (((location_t) 0), arith_type, lhs), fold_convert_loc (((location_t) 0), arith_type , rhs) )); |
3419 | |
3420 | if (postfix) |
3421 | { |
3422 | gimplify_assign (lvalue, t1, pre_p); |
3423 | gimplify_seq_add_seq (orig_post_p, post); |
3424 | *expr_p = lhs; |
3425 | return GS_ALL_DONE; |
3426 | } |
3427 | else |
3428 | { |
3429 | *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue)((contains_struct_check ((lvalue), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3429, __FUNCTION__))->typed.type), lvalue, t1); |
3430 | return GS_OK; |
3431 | } |
3432 | } |
3433 | |
3434 | /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */ |
3435 | |
3436 | static void |
3437 | maybe_with_size_expr (tree *expr_p) |
3438 | { |
3439 | tree expr = *expr_p; |
3440 | tree type = TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3440, __FUNCTION__))->typed.type); |
3441 | tree size; |
3442 | |
3443 | /* If we've already wrapped this or the type is error_mark_node, we can't do |
3444 | anything. */ |
3445 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == WITH_SIZE_EXPR |
3446 | || type == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
3447 | return; |
3448 | |
3449 | /* If the size isn't known or is a constant, we have nothing to do. */ |
3450 | size = TYPE_SIZE_UNIT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3450, __FUNCTION__))->type_common.size_unit); |
3451 | if (!size || poly_int_tree_p (size)) |
3452 | return; |
3453 | |
3454 | /* Otherwise, make a WITH_SIZE_EXPR. */ |
3455 | size = unshare_expr (size); |
3456 | size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr)((size) == 0 || ((non_type_check ((size), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3456, __FUNCTION__))->base.constant_flag) ? (size) : substitute_placeholder_in_expr (size, expr)); |
3457 | *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size); |
3458 | } |
3459 | |
3460 | /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P |
3461 | Store any side-effects in PRE_P. CALL_LOCATION is the location of |
3462 | the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be |
3463 | gimplified to an SSA name. */ |
3464 | |
3465 | enum gimplify_status |
3466 | gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location, |
3467 | bool allow_ssa) |
3468 | { |
3469 | bool (*test) (tree); |
3470 | fallback_t fb; |
3471 | |
3472 | /* In general, we allow lvalues for function arguments to avoid |
3473 | extra overhead of copying large aggregates out of even larger |
3474 | aggregates into temporaries only to copy the temporaries to |
3475 | the argument list. Make optimizers happy by pulling out to |
3476 | temporaries those types that fit in registers. */ |
3477 | if (is_gimple_reg_type (TREE_TYPE (*arg_p)((contains_struct_check ((*arg_p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3477, __FUNCTION__))->typed.type))) |
3478 | test = is_gimple_val, fb = fb_rvalue; |
3479 | else |
3480 | { |
3481 | test = is_gimple_lvalue, fb = fb_either; |
3482 | /* Also strip a TARGET_EXPR that would force an extra copy. */ |
3483 | if (TREE_CODE (*arg_p)((enum tree_code) (*arg_p)->base.code) == TARGET_EXPR) |
3484 | { |
3485 | tree init = TARGET_EXPR_INITIAL (*arg_p)(*(tree_operand_check_code ((*arg_p), (TARGET_EXPR), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3485, __FUNCTION__))); |
3486 | if (init |
3487 | && !VOID_TYPE_P (TREE_TYPE (init))(((enum tree_code) (((contains_struct_check ((init), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3487, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE )) |
3488 | *arg_p = init; |
3489 | } |
3490 | } |
3491 | |
3492 | /* If this is a variable sized type, we must remember the size. */ |
3493 | maybe_with_size_expr (arg_p); |
3494 | |
3495 | /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */ |
3496 | /* Make sure arguments have the same location as the function call |
3497 | itself. */ |
3498 | protected_set_expr_location (*arg_p, call_location); |
3499 | |
3500 | /* There is a sequence point before a function call. Side effects in |
3501 | the argument list must occur before the actual call. So, when |
3502 | gimplifying arguments, force gimplify_expr to use an internal |
3503 | post queue which is then appended to the end of PRE_P. */ |
3504 | return gimplify_expr (arg_p, pre_p, NULLnullptr, test, fb, allow_ssa); |
3505 | } |
3506 | |
3507 | /* Don't fold inside offloading or taskreg regions: it can break code by |
3508 | adding decl references that weren't in the source. We'll do it during |
3509 | omplower pass instead. */ |
3510 | |
3511 | static bool |
3512 | maybe_fold_stmt (gimple_stmt_iterator *gsi) |
3513 | { |
3514 | struct gimplify_omp_ctx *ctx; |
3515 | for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context) |
3516 | if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0) |
3517 | return false; |
3518 | else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS) |
3519 | return false; |
3520 | /* Delay folding of builtins until the IL is in consistent state |
3521 | so the diagnostic machinery can do a better job. */ |
3522 | if (gimple_call_builtin_p (gsi_stmt (*gsi))) |
3523 | return false; |
3524 | return fold_stmt (gsi); |
3525 | } |
3526 | |
3527 | /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P. |
3528 | WANT_VALUE is true if the result of the call is desired. */ |
3529 | |
3530 | static enum gimplify_status |
3531 | gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value) |
3532 | { |
3533 | tree fndecl, parms, p, fnptrtype; |
3534 | enum gimplify_status ret; |
3535 | int i, nargs; |
3536 | gcall *call; |
3537 | bool builtin_va_start_p = false; |
3538 | location_t loc = EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 )); |
3539 | |
3540 | gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR)((void)(!(((enum tree_code) (*expr_p)->base.code) == CALL_EXPR ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3540, __FUNCTION__), 0 : 0)); |
3541 | |
3542 | /* For reliable diagnostics during inlining, it is necessary that |
3543 | every call_expr be annotated with file and line. */ |
3544 | if (! EXPR_HAS_LOCATION (*expr_p)(((IS_ADHOC_LOC (((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((*expr_p ))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((*expr_p ))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp .locus : ((location_t) 0)))) ? get_location_from_adhoc_loc (line_table , ((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 ))) : (((((*expr_p)) && ((tree_code_type_tmpl <0> ::tree_code_type[(int) (((enum tree_code) ((*expr_p))->base .code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((*expr_p ))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp .locus : ((location_t) 0)))) != ((location_t) 0))) |
3545 | SET_EXPR_LOCATION (*expr_p, input_location)(expr_check (((*expr_p)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3545, __FUNCTION__))->exp.locus = (input_location); |
3546 | |
3547 | /* Gimplify internal functions created in the FEs. */ |
3548 | if (CALL_EXPR_FN (*expr_p)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3548, __FUNCTION__, (CALL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3548, __FUNCTION__))))) == NULL_TREE(tree) nullptr) |
3549 | { |
3550 | if (want_value) |
3551 | return GS_ALL_DONE; |
3552 | |
3553 | nargs = call_expr_nargs (*expr_p)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((*expr_p), (tcc_vl_exp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3553, __FUNCTION__))->exp.operands[0]), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3553, __FUNCTION__)))) - 3); |
3554 | enum internal_fn ifn = CALL_EXPR_IFN (*expr_p)((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3554, __FUNCTION__, (CALL_EXPR)))->base.u.ifn); |
3555 | auto_vec<tree> vargs (nargs); |
3556 | |
3557 | if (ifn == IFN_ASSUME) |
3558 | { |
3559 | if (simple_condition_p (CALL_EXPR_ARG (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3559, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3559, __FUNCTION__))))))) |
3560 | { |
3561 | /* If the [[assume (cond)]]; condition is simple |
3562 | enough and can be evaluated unconditionally |
3563 | without side-effects, expand it as |
3564 | if (!cond) __builtin_unreachable (); */ |
3565 | tree fndecl = builtin_decl_explicit (BUILT_IN_UNREACHABLE); |
3566 | *expr_p = build3 (COND_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], |
3567 | CALL_EXPR_ARG (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3567, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3567, __FUNCTION__))))), void_nodeglobal_trees[TI_VOID], |
3568 | build_call_expr_loc (EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 )), |
3569 | fndecl, 0)); |
3570 | return GS_OK; |
3571 | } |
3572 | /* If not optimizing, ignore the assumptions. */ |
3573 | if (!optimizeglobal_options.x_optimize || seen_error ()) |
3574 | { |
3575 | *expr_p = NULL_TREE(tree) nullptr; |
3576 | return GS_ALL_DONE; |
3577 | } |
3578 | /* Temporarily, until gimple lowering, transform |
3579 | .ASSUME (cond); |
3580 | into: |
3581 | [[assume (guard)]] |
3582 | { |
3583 | guard = cond; |
3584 | } |
3585 | such that gimple lowering can outline the condition into |
3586 | a separate function easily. */ |
3587 | tree guard = create_tmp_var (boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE]); |
3588 | *expr_p = build2 (MODIFY_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], guard, |
3589 | gimple_boolify (CALL_EXPR_ARG (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3589, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3589, __FUNCTION__))))))); |
3590 | *expr_p = build3 (BIND_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], NULLnullptr, *expr_p, NULLnullptr); |
3591 | push_gimplify_context (); |
3592 | gimple_seq body = NULLnullptr; |
3593 | gimple *g = gimplify_and_return_first (*expr_p, &body); |
3594 | pop_gimplify_context (g); |
3595 | g = gimple_build_assume (guard, body); |
3596 | gimple_set_location (g, loc); |
3597 | gimplify_seq_add_stmt (pre_p, g); |
3598 | *expr_p = NULL_TREE(tree) nullptr; |
3599 | return GS_ALL_DONE; |
3600 | } |
3601 | |
3602 | for (i = 0; i < nargs; i++) |
3603 | { |
3604 | gimplify_arg (&CALL_EXPR_ARG (*expr_p, i)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3604, __FUNCTION__, (CALL_EXPR)))), ((i) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3604, __FUNCTION__))))), pre_p, |
3605 | EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 ))); |
3606 | vargs.quick_push (CALL_EXPR_ARG (*expr_p, i)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3606, __FUNCTION__, (CALL_EXPR)))), ((i) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3606, __FUNCTION__)))))); |
3607 | } |
3608 | |
3609 | gcall *call = gimple_build_call_internal_vec (ifn, vargs); |
3610 | gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p)((*expr_p)->base.nothrow_flag)); |
3611 | gimplify_seq_add_stmt (pre_p, call); |
3612 | return GS_ALL_DONE; |
3613 | } |
3614 | |
3615 | /* This may be a call to a builtin function. |
3616 | |
3617 | Builtin function calls may be transformed into different |
3618 | (and more efficient) builtin function calls under certain |
3619 | circumstances. Unfortunately, gimplification can muck things |
3620 | up enough that the builtin expanders are not aware that certain |
3621 | transformations are still valid. |
3622 | |
3623 | So we attempt transformation/gimplification of the call before |
3624 | we gimplify the CALL_EXPR. At this time we do not manage to |
3625 | transform all calls in the same manner as the expanders do, but |
3626 | we do transform most of them. */ |
3627 | fndecl = get_callee_fndecl (*expr_p); |
3628 | if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)) |
3629 | switch (DECL_FUNCTION_CODE (fndecl)) |
3630 | { |
3631 | CASE_BUILT_IN_ALLOCAcase BUILT_IN_ALLOCA: case BUILT_IN_ALLOCA_WITH_ALIGN: case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX: |
3632 | /* If the call has been built for a variable-sized object, then we |
3633 | want to restore the stack level when the enclosing BIND_EXPR is |
3634 | exited to reclaim the allocated space; otherwise, we precisely |
3635 | need to do the opposite and preserve the latest stack level. */ |
3636 | if (CALL_ALLOCA_FOR_VAR_P (*expr_p)((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3636, __FUNCTION__, (CALL_EXPR)))->base.protected_flag)) |
3637 | gimplify_ctxp->save_stack = true; |
3638 | else |
3639 | gimplify_ctxp->keep_stack = true; |
3640 | break; |
3641 | |
3642 | case BUILT_IN_VA_START: |
3643 | { |
3644 | builtin_va_start_p = TRUEtrue; |
3645 | if (call_expr_nargs (*expr_p)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((*expr_p), (tcc_vl_exp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3645, __FUNCTION__))->exp.operands[0]), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3645, __FUNCTION__)))) - 3) < 2) |
3646 | { |
3647 | error ("too few arguments to function %<va_start%>"); |
3648 | *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 ))); |
3649 | return GS_OK; |
3650 | } |
3651 | |
3652 | if (fold_builtin_next_arg (*expr_p, true)) |
3653 | { |
3654 | *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 ))); |
3655 | return GS_OK; |
3656 | } |
3657 | break; |
3658 | } |
3659 | |
3660 | case BUILT_IN_EH_RETURN: |
3661 | cfun(cfun + 0)->calls_eh_return = true; |
3662 | break; |
3663 | |
3664 | case BUILT_IN_CLEAR_PADDING: |
3665 | if (call_expr_nargs (*expr_p)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((*expr_p), (tcc_vl_exp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3665, __FUNCTION__))->exp.operands[0]), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3665, __FUNCTION__)))) - 3) == 1) |
3666 | { |
3667 | /* Remember the original type of the argument in an internal |
3668 | dummy second argument, as in GIMPLE pointer conversions are |
3669 | useless. Also mark this call as not for automatic |
3670 | initialization in the internal dummy third argument. */ |
3671 | p = CALL_EXPR_ARG (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3671, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3671, __FUNCTION__))))); |
3672 | *expr_p |
3673 | = build_call_expr_loc (EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 )), fndecl, 2, p, |
3674 | build_zero_cst (TREE_TYPE (p)((contains_struct_check ((p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3674, __FUNCTION__))->typed.type))); |
3675 | return GS_OK; |
3676 | } |
3677 | break; |
3678 | |
3679 | default: |
3680 | ; |
3681 | } |
3682 | if (fndecl && fndecl_built_in_p (fndecl)) |
3683 | { |
3684 | tree new_tree = fold_call_expr (input_location, *expr_p, !want_value); |
3685 | if (new_tree && new_tree != *expr_p) |
3686 | { |
3687 | /* There was a transformation of this call which computes the |
3688 | same value, but in a more efficient way. Return and try |
3689 | again. */ |
3690 | *expr_p = new_tree; |
3691 | return GS_OK; |
3692 | } |
3693 | } |
3694 | |
3695 | /* Remember the original function pointer type. */ |
3696 | fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3696, __FUNCTION__, (CALL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3696, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3696, __FUNCTION__))->typed.type); |
3697 | |
3698 | if (flag_openmpglobal_options.x_flag_openmp |
3699 | && fndecl |
3700 | && cfun(cfun + 0) |
3701 | && (cfun(cfun + 0)->curr_properties & PROP_gimple_any(1 << 0)) == 0) |
3702 | { |
3703 | tree variant = omp_resolve_declare_variant (fndecl); |
3704 | if (variant != fndecl) |
3705 | CALL_EXPR_FN (*expr_p)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3705, __FUNCTION__, (CALL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3705, __FUNCTION__))))) = build1 (ADDR_EXPR, fnptrtype, variant); |
3706 | } |
3707 | |
3708 | /* There is a sequence point before the call, so any side effects in |
3709 | the calling expression must occur before the actual call. Force |
3710 | gimplify_expr to use an internal post queue. */ |
3711 | ret = gimplify_expr (&CALL_EXPR_FN (*expr_p)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3711, __FUNCTION__, (CALL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3711, __FUNCTION__))))), pre_p, NULLnullptr, |
3712 | is_gimple_call_addr, fb_rvalue); |
3713 | |
3714 | if (ret == GS_ERROR) |
3715 | return GS_ERROR; |
3716 | |
3717 | nargs = call_expr_nargs (*expr_p)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((*expr_p), (tcc_vl_exp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3717, __FUNCTION__))->exp.operands[0]), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3717, __FUNCTION__)))) - 3); |
3718 | |
3719 | /* Get argument types for verification. */ |
3720 | fndecl = get_callee_fndecl (*expr_p); |
3721 | parms = NULL_TREE(tree) nullptr; |
3722 | if (fndecl) |
3723 | parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl))((tree_check2 ((((contains_struct_check ((fndecl), (TS_TYPED) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3723, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3723, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values); |
3724 | else |
3725 | parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype))((tree_check2 ((((contains_struct_check ((fnptrtype), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3725, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3725, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values); |
3726 | |
3727 | if (fndecl && DECL_ARGUMENTS (fndecl)((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3727, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments )) |
3728 | p = DECL_ARGUMENTS (fndecl)((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3728, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments ); |
3729 | else if (parms) |
3730 | p = parms; |
3731 | else |
3732 | p = NULL_TREE(tree) nullptr; |
3733 | for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p)((contains_struct_check ((p), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3733, __FUNCTION__))->common.chain)) |
3734 | ; |
3735 | |
3736 | /* If the last argument is __builtin_va_arg_pack () and it is not |
3737 | passed as a named argument, decrease the number of CALL_EXPR |
3738 | arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */ |
3739 | if (!p |
3740 | && i < nargs |
3741 | && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3741, __FUNCTION__, (CALL_EXPR)))), ((nargs - 1) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3741, __FUNCTION__))))))->base.code) == CALL_EXPR) |
3742 | { |
3743 | tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3743, __FUNCTION__, (CALL_EXPR)))), ((nargs - 1) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3743, __FUNCTION__))))); |
3744 | tree last_arg_fndecl = get_callee_fndecl (last_arg); |
3745 | |
3746 | if (last_arg_fndecl |
3747 | && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK)) |
3748 | { |
3749 | tree call = *expr_p; |
3750 | |
3751 | --nargs; |
3752 | *expr_p = build_call_array_loc (loc, TREE_TYPE (call)((contains_struct_check ((call), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3752, __FUNCTION__))->typed.type), |
3753 | CALL_EXPR_FN (call)(*((const_cast<tree*> (tree_operand_check (((tree_check ((call), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3753, __FUNCTION__, (CALL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3753, __FUNCTION__))))), |
3754 | nargs, CALL_EXPR_ARGP (call)(&((*((const_cast<tree*> (tree_operand_check (((tree_check ((call), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3754, __FUNCTION__, (CALL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3754, __FUNCTION__)))))) + 3)); |
3755 | |
3756 | /* Copy all CALL_EXPR flags, location and block, except |
3757 | CALL_EXPR_VA_ARG_PACK flag. */ |
3758 | CALL_EXPR_STATIC_CHAIN (*expr_p)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3758, __FUNCTION__, (CALL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3758, __FUNCTION__))))) = CALL_EXPR_STATIC_CHAIN (call)(*((const_cast<tree*> (tree_operand_check (((tree_check ((call), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3758, __FUNCTION__, (CALL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3758, __FUNCTION__))))); |
3759 | CALL_EXPR_TAILCALL (*expr_p)((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3759, __FUNCTION__, (CALL_EXPR)))->base.addressable_flag ) = CALL_EXPR_TAILCALL (call)((tree_check ((call), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3759, __FUNCTION__, (CALL_EXPR)))->base.addressable_flag ); |
3760 | CALL_EXPR_RETURN_SLOT_OPT (*expr_p)((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3760, __FUNCTION__, (CALL_EXPR)))->base.private_flag) |
3761 | = CALL_EXPR_RETURN_SLOT_OPT (call)((tree_check ((call), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3761, __FUNCTION__, (CALL_EXPR)))->base.private_flag); |
3762 | CALL_FROM_THUNK_P (*expr_p)((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3762, __FUNCTION__, (CALL_EXPR)))->base.protected_flag) = CALL_FROM_THUNK_P (call)((tree_check ((call), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3762, __FUNCTION__, (CALL_EXPR)))->base.protected_flag); |
3763 | SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call))(expr_check (((*expr_p)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3763, __FUNCTION__))->exp.locus = (((((call)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((call))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((call))->base.code))]) <= tcc_expression)) ? (call)->exp.locus : ((location_t) 0))); |
3764 | |
3765 | /* Set CALL_EXPR_VA_ARG_PACK. */ |
3766 | CALL_EXPR_VA_ARG_PACK (*expr_p)((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3766, __FUNCTION__, (CALL_EXPR)))->base.public_flag) = 1; |
3767 | } |
3768 | } |
3769 | |
3770 | /* If the call returns twice then after building the CFG the call |
3771 | argument computations will no longer dominate the call because |
3772 | we add an abnormal incoming edge to the call. So do not use SSA |
3773 | vars there. */ |
3774 | bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE(1 << 7); |
3775 | |
3776 | /* Gimplify the function arguments. */ |
3777 | if (nargs > 0) |
3778 | { |
3779 | for (i = (PUSH_ARGS_REVERSED1 ? nargs - 1 : 0); |
3780 | PUSH_ARGS_REVERSED1 ? i >= 0 : i < nargs; |
3781 | PUSH_ARGS_REVERSED1 ? i-- : i++) |
3782 | { |
3783 | enum gimplify_status t; |
3784 | |
3785 | /* Avoid gimplifying the second argument to va_start, which needs to |
3786 | be the plain PARM_DECL. */ |
3787 | if ((i != 1) || !builtin_va_start_p) |
3788 | { |
3789 | t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3789, __FUNCTION__, (CALL_EXPR)))), ((i) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3789, __FUNCTION__))))), pre_p, |
3790 | EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 )), ! returns_twice); |
3791 | |
3792 | if (t == GS_ERROR) |
3793 | ret = GS_ERROR; |
3794 | } |
3795 | } |
3796 | } |
3797 | |
3798 | /* Gimplify the static chain. */ |
3799 | if (CALL_EXPR_STATIC_CHAIN (*expr_p)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3799, __FUNCTION__, (CALL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3799, __FUNCTION__)))))) |
3800 | { |
3801 | if (fndecl && !DECL_STATIC_CHAIN (fndecl)((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3801, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.regdecl_flag )) |
3802 | CALL_EXPR_STATIC_CHAIN (*expr_p)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3802, __FUNCTION__, (CALL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3802, __FUNCTION__))))) = NULLnullptr; |
3803 | else |
3804 | { |
3805 | enum gimplify_status t; |
3806 | t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3806, __FUNCTION__, (CALL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3806, __FUNCTION__))))), pre_p, |
3807 | EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 )), ! returns_twice); |
3808 | if (t == GS_ERROR) |
3809 | ret = GS_ERROR; |
3810 | } |
3811 | } |
3812 | |
3813 | /* Verify the function result. */ |
3814 | if (want_value && fndecl |
3815 | && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype)))(((enum tree_code) (((contains_struct_check ((((contains_struct_check ((fnptrtype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3815, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3815, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE )) |
3816 | { |
3817 | error_at (loc, "using result of function returning %<void%>"); |
3818 | ret = GS_ERROR; |
3819 | } |
3820 | |
3821 | /* Try this again in case gimplification exposed something. */ |
3822 | if (ret != GS_ERROR) |
3823 | { |
3824 | tree new_tree = fold_call_expr (input_location, *expr_p, !want_value); |
3825 | |
3826 | if (new_tree && new_tree != *expr_p) |
3827 | { |
3828 | /* There was a transformation of this call which computes the |
3829 | same value, but in a more efficient way. Return and try |
3830 | again. */ |
3831 | *expr_p = new_tree; |
3832 | return GS_OK; |
3833 | } |
3834 | } |
3835 | else |
3836 | { |
3837 | *expr_p = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
3838 | return GS_ERROR; |
3839 | } |
3840 | |
3841 | /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its |
3842 | decl. This allows us to eliminate redundant or useless |
3843 | calls to "const" functions. */ |
3844 | if (TREE_CODE (*expr_p)((enum tree_code) (*expr_p)->base.code) == CALL_EXPR) |
3845 | { |
3846 | int flags = call_expr_flags (*expr_p); |
3847 | if (flags & (ECF_CONST(1 << 0) | ECF_PURE(1 << 1)) |
3848 | /* An infinite loop is considered a side effect. */ |
3849 | && !(flags & (ECF_LOOPING_CONST_OR_PURE(1 << 2)))) |
3850 | TREE_SIDE_EFFECTS (*expr_p)((non_type_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3850, __FUNCTION__))->base.side_effects_flag) = 0; |
3851 | } |
3852 | |
3853 | /* If the value is not needed by the caller, emit a new GIMPLE_CALL |
3854 | and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified |
3855 | form and delegate the creation of a GIMPLE_CALL to |
3856 | gimplify_modify_expr. This is always possible because when |
3857 | WANT_VALUE is true, the caller wants the result of this call into |
3858 | a temporary, which means that we will emit an INIT_EXPR in |
3859 | internal_get_tmp_var which will then be handled by |
3860 | gimplify_modify_expr. */ |
3861 | if (!want_value) |
3862 | { |
3863 | /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we |
3864 | have to do is replicate it as a GIMPLE_CALL tuple. */ |
3865 | gimple_stmt_iterator gsi; |
3866 | call = gimple_build_call_from_tree (*expr_p, fnptrtype); |
3867 | notice_special_calls (call); |
3868 | gimplify_seq_add_stmt (pre_p, call); |
3869 | gsi = gsi_last (*pre_p); |
3870 | maybe_fold_stmt (&gsi); |
3871 | *expr_p = NULL_TREE(tree) nullptr; |
3872 | } |
3873 | else |
3874 | /* Remember the original function type. */ |
3875 | CALL_EXPR_FN (*expr_p)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3875, __FUNCTION__, (CALL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3875, __FUNCTION__))))) = build1 (NOP_EXPR, fnptrtype, |
3876 | CALL_EXPR_FN (*expr_p)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3876, __FUNCTION__, (CALL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3876, __FUNCTION__)))))); |
3877 | |
3878 | return ret; |
3879 | } |
3880 | |
3881 | /* Handle shortcut semantics in the predicate operand of a COND_EXPR by |
3882 | rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs. |
3883 | |
3884 | TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the |
3885 | condition is true or false, respectively. If null, we should generate |
3886 | our own to skip over the evaluation of this specific expression. |
3887 | |
3888 | LOCUS is the source location of the COND_EXPR. |
3889 | |
3890 | This function is the tree equivalent of do_jump. |
3891 | |
3892 | shortcut_cond_r should only be called by shortcut_cond_expr. */ |
3893 | |
3894 | static tree |
3895 | shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p, |
3896 | location_t locus) |
3897 | { |
3898 | tree local_label = NULL_TREE(tree) nullptr; |
3899 | tree t, expr = NULLnullptr; |
3900 | |
3901 | /* OK, it's not a simple case; we need to pull apart the COND_EXPR to |
3902 | retain the shortcut semantics. Just insert the gotos here; |
3903 | shortcut_cond_expr will append the real blocks later. */ |
3904 | if (TREE_CODE (pred)((enum tree_code) (pred)->base.code) == TRUTH_ANDIF_EXPR) |
3905 | { |
3906 | location_t new_locus; |
3907 | |
3908 | /* Turn if (a && b) into |
3909 | |
3910 | if (a); else goto no; |
3911 | if (b) goto yes; else goto no; |
3912 | (no:) */ |
3913 | |
3914 | if (false_label_p == NULLnullptr) |
3915 | false_label_p = &local_label; |
3916 | |
3917 | /* Keep the original source location on the first 'if'. */ |
3918 | t = shortcut_cond_r (TREE_OPERAND (pred, 0)(*((const_cast<tree*> (tree_operand_check ((pred), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3918, __FUNCTION__))))), NULLnullptr, false_label_p, locus); |
3919 | append_to_statement_list (t, &expr); |
3920 | |
3921 | /* Set the source location of the && on the second 'if'. */ |
3922 | new_locus = rexpr_location (pred, locus); |
3923 | t = shortcut_cond_r (TREE_OPERAND (pred, 1)(*((const_cast<tree*> (tree_operand_check ((pred), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3923, __FUNCTION__))))), true_label_p, false_label_p, |
3924 | new_locus); |
3925 | append_to_statement_list (t, &expr); |
3926 | } |
3927 | else if (TREE_CODE (pred)((enum tree_code) (pred)->base.code) == TRUTH_ORIF_EXPR) |
3928 | { |
3929 | location_t new_locus; |
3930 | |
3931 | /* Turn if (a || b) into |
3932 | |
3933 | if (a) goto yes; |
3934 | if (b) goto yes; else goto no; |
3935 | (yes:) */ |
3936 | |
3937 | if (true_label_p == NULLnullptr) |
3938 | true_label_p = &local_label; |
3939 | |
3940 | /* Keep the original source location on the first 'if'. */ |
3941 | t = shortcut_cond_r (TREE_OPERAND (pred, 0)(*((const_cast<tree*> (tree_operand_check ((pred), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3941, __FUNCTION__))))), true_label_p, NULLnullptr, locus); |
3942 | append_to_statement_list (t, &expr); |
3943 | |
3944 | /* Set the source location of the || on the second 'if'. */ |
3945 | new_locus = rexpr_location (pred, locus); |
3946 | t = shortcut_cond_r (TREE_OPERAND (pred, 1)(*((const_cast<tree*> (tree_operand_check ((pred), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3946, __FUNCTION__))))), true_label_p, false_label_p, |
3947 | new_locus); |
3948 | append_to_statement_list (t, &expr); |
3949 | } |
3950 | else if (TREE_CODE (pred)((enum tree_code) (pred)->base.code) == COND_EXPR |
3951 | && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))(((enum tree_code) (((contains_struct_check (((*((const_cast< tree*> (tree_operand_check ((pred), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3951, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3951, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE ) |
3952 | && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2)))(((enum tree_code) (((contains_struct_check (((*((const_cast< tree*> (tree_operand_check ((pred), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3952, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3952, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE )) |
3953 | { |
3954 | location_t new_locus; |
3955 | |
3956 | /* As long as we're messing with gotos, turn if (a ? b : c) into |
3957 | if (a) |
3958 | if (b) goto yes; else goto no; |
3959 | else |
3960 | if (c) goto yes; else goto no; |
3961 | |
3962 | Don't do this if one of the arms has void type, which can happen |
3963 | in C++ when the arm is throw. */ |
3964 | |
3965 | /* Keep the original source location on the first 'if'. Set the source |
3966 | location of the ? on the second 'if'. */ |
3967 | new_locus = rexpr_location (pred, locus); |
3968 | expr = build3 (COND_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], TREE_OPERAND (pred, 0)(*((const_cast<tree*> (tree_operand_check ((pred), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3968, __FUNCTION__))))), |
3969 | shortcut_cond_r (TREE_OPERAND (pred, 1)(*((const_cast<tree*> (tree_operand_check ((pred), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3969, __FUNCTION__))))), true_label_p, |
3970 | false_label_p, locus), |
3971 | shortcut_cond_r (TREE_OPERAND (pred, 2)(*((const_cast<tree*> (tree_operand_check ((pred), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3971, __FUNCTION__))))), true_label_p, |
3972 | false_label_p, new_locus)); |
3973 | } |
3974 | else |
3975 | { |
3976 | expr = build3 (COND_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], pred, |
3977 | build_and_jump (true_label_p), |
3978 | build_and_jump (false_label_p)); |
3979 | SET_EXPR_LOCATION (expr, locus)(expr_check (((expr)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 3979, __FUNCTION__))->exp.locus = (locus); |
3980 | } |
3981 | |
3982 | if (local_label) |
3983 | { |
3984 | t = build1 (LABEL_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], local_label); |
3985 | append_to_statement_list (t, &expr); |
3986 | } |
3987 | |
3988 | return expr; |
3989 | } |
3990 | |
3991 | /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip |
3992 | any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent |
3993 | statement, if it is the last one. Otherwise, return NULL. */ |
3994 | |
3995 | static tree |
3996 | find_goto (tree expr) |
3997 | { |
3998 | if (!expr) |
3999 | return NULL_TREE(tree) nullptr; |
4000 | |
4001 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == GOTO_EXPR) |
4002 | return expr; |
4003 | |
4004 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) != STATEMENT_LIST) |
4005 | return NULL_TREE(tree) nullptr; |
4006 | |
4007 | tree_stmt_iterator i = tsi_start (expr); |
4008 | |
4009 | while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i))((enum tree_code) (tsi_stmt (i))->base.code) == DEBUG_BEGIN_STMT) |
4010 | tsi_next (&i); |
4011 | |
4012 | if (!tsi_one_before_end_p (i)) |
4013 | return NULL_TREE(tree) nullptr; |
4014 | |
4015 | return find_goto (tsi_stmt (i)); |
4016 | } |
4017 | |
4018 | /* Same as find_goto, except that it returns NULL if the destination |
4019 | is not a LABEL_DECL. */ |
4020 | |
4021 | static inline tree |
4022 | find_goto_label (tree expr) |
4023 | { |
4024 | tree dest = find_goto (expr); |
4025 | if (dest && TREE_CODE (GOTO_DESTINATION (dest))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check (((tree_check ((dest), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4025, __FUNCTION__, (GOTO_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4025, __FUNCTION__))))))->base.code) == LABEL_DECL) |
4026 | return dest; |
4027 | return NULL_TREE(tree) nullptr; |
4028 | } |
4029 | |
4030 | /* Given a conditional expression EXPR with short-circuit boolean |
4031 | predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the |
4032 | predicate apart into the equivalent sequence of conditionals. */ |
4033 | |
4034 | static tree |
4035 | shortcut_cond_expr (tree expr) |
4036 | { |
4037 | tree pred = TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4037, __FUNCTION__))))); |
4038 | tree then_ = TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4038, __FUNCTION__))))); |
4039 | tree else_ = TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4039, __FUNCTION__))))); |
4040 | tree true_label, false_label, end_label, t; |
4041 | tree *true_label_p; |
4042 | tree *false_label_p; |
4043 | bool emit_end, emit_false, jump_over_else; |
4044 | bool then_se = then_ && TREE_SIDE_EFFECTS (then_)((non_type_check ((then_), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4044, __FUNCTION__))->base.side_effects_flag); |
4045 | bool else_se = else_ && TREE_SIDE_EFFECTS (else_)((non_type_check ((else_), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4045, __FUNCTION__))->base.side_effects_flag); |
4046 | |
4047 | /* First do simple transformations. */ |
4048 | if (!else_se) |
4049 | { |
4050 | /* If there is no 'else', turn |
4051 | if (a && b) then c |
4052 | into |
4053 | if (a) if (b) then c. */ |
4054 | while (TREE_CODE (pred)((enum tree_code) (pred)->base.code) == TRUTH_ANDIF_EXPR) |
4055 | { |
4056 | /* Keep the original source location on the first 'if'. */ |
4057 | location_t locus = EXPR_LOC_OR_LOC (expr, input_location)((((IS_ADHOC_LOC (((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))-> base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))-> base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) ? get_location_from_adhoc_loc (line_table , ((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression )) ? (expr)->exp.locus : ((location_t) 0))) : (((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) != ((location_t ) 0)) ? (expr)->exp.locus : (input_location)); |
4058 | TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4058, __FUNCTION__))))) = TREE_OPERAND (pred, 1)(*((const_cast<tree*> (tree_operand_check ((pred), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4058, __FUNCTION__))))); |
4059 | /* Set the source location of the && on the second 'if'. */ |
4060 | if (rexpr_has_location (pred)) |
4061 | SET_EXPR_LOCATION (expr, rexpr_location (pred))(expr_check (((expr)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4061, __FUNCTION__))->exp.locus = (rexpr_location (pred) ); |
4062 | then_ = shortcut_cond_expr (expr); |
4063 | then_se = then_ && TREE_SIDE_EFFECTS (then_)((non_type_check ((then_), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4063, __FUNCTION__))->base.side_effects_flag); |
4064 | pred = TREE_OPERAND (pred, 0)(*((const_cast<tree*> (tree_operand_check ((pred), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4064, __FUNCTION__))))); |
4065 | expr = build3 (COND_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], pred, then_, NULL_TREE(tree) nullptr); |
4066 | SET_EXPR_LOCATION (expr, locus)(expr_check (((expr)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4066, __FUNCTION__))->exp.locus = (locus); |
4067 | } |
4068 | } |
4069 | |
4070 | if (!then_se) |
4071 | { |
4072 | /* If there is no 'then', turn |
4073 | if (a || b); else d |
4074 | into |
4075 | if (a); else if (b); else d. */ |
4076 | while (TREE_CODE (pred)((enum tree_code) (pred)->base.code) == TRUTH_ORIF_EXPR) |
4077 | { |
4078 | /* Keep the original source location on the first 'if'. */ |
4079 | location_t locus = EXPR_LOC_OR_LOC (expr, input_location)((((IS_ADHOC_LOC (((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))-> base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))-> base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) ? get_location_from_adhoc_loc (line_table , ((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression )) ? (expr)->exp.locus : ((location_t) 0))) : (((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) != ((location_t ) 0)) ? (expr)->exp.locus : (input_location)); |
4080 | TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4080, __FUNCTION__))))) = TREE_OPERAND (pred, 1)(*((const_cast<tree*> (tree_operand_check ((pred), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4080, __FUNCTION__))))); |
4081 | /* Set the source location of the || on the second 'if'. */ |
4082 | if (rexpr_has_location (pred)) |
4083 | SET_EXPR_LOCATION (expr, rexpr_location (pred))(expr_check (((expr)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4083, __FUNCTION__))->exp.locus = (rexpr_location (pred) ); |
4084 | else_ = shortcut_cond_expr (expr); |
4085 | else_se = else_ && TREE_SIDE_EFFECTS (else_)((non_type_check ((else_), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4085, __FUNCTION__))->base.side_effects_flag); |
4086 | pred = TREE_OPERAND (pred, 0)(*((const_cast<tree*> (tree_operand_check ((pred), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4086, __FUNCTION__))))); |
4087 | expr = build3 (COND_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], pred, NULL_TREE(tree) nullptr, else_); |
4088 | SET_EXPR_LOCATION (expr, locus)(expr_check (((expr)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4088, __FUNCTION__))->exp.locus = (locus); |
4089 | } |
4090 | } |
4091 | |
4092 | /* If we're done, great. */ |
4093 | if (TREE_CODE (pred)((enum tree_code) (pred)->base.code) != TRUTH_ANDIF_EXPR |
4094 | && TREE_CODE (pred)((enum tree_code) (pred)->base.code) != TRUTH_ORIF_EXPR) |
4095 | return expr; |
4096 | |
4097 | /* Otherwise we need to mess with gotos. Change |
4098 | if (a) c; else d; |
4099 | to |
4100 | if (a); else goto no; |
4101 | c; goto end; |
4102 | no: d; end: |
4103 | and recursively gimplify the condition. */ |
4104 | |
4105 | true_label = false_label = end_label = NULL_TREE(tree) nullptr; |
4106 | |
4107 | /* If our arms just jump somewhere, hijack those labels so we don't |
4108 | generate jumps to jumps. */ |
4109 | |
4110 | if (tree then_goto = find_goto_label (then_)) |
4111 | { |
4112 | true_label = GOTO_DESTINATION (then_goto)(*((const_cast<tree*> (tree_operand_check (((tree_check ((then_goto), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4112, __FUNCTION__, (GOTO_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4112, __FUNCTION__))))); |
4113 | then_ = NULLnullptr; |
4114 | then_se = false; |
4115 | } |
4116 | |
4117 | if (tree else_goto = find_goto_label (else_)) |
4118 | { |
4119 | false_label = GOTO_DESTINATION (else_goto)(*((const_cast<tree*> (tree_operand_check (((tree_check ((else_goto), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4119, __FUNCTION__, (GOTO_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4119, __FUNCTION__))))); |
4120 | else_ = NULLnullptr; |
4121 | else_se = false; |
4122 | } |
4123 | |
4124 | /* If we aren't hijacking a label for the 'then' branch, it falls through. */ |
4125 | if (true_label) |
4126 | true_label_p = &true_label; |
4127 | else |
4128 | true_label_p = NULLnullptr; |
4129 | |
4130 | /* The 'else' branch also needs a label if it contains interesting code. */ |
4131 | if (false_label || else_se) |
4132 | false_label_p = &false_label; |
4133 | else |
4134 | false_label_p = NULLnullptr; |
4135 | |
4136 | /* If there was nothing else in our arms, just forward the label(s). */ |
4137 | if (!then_se && !else_se) |
4138 | return shortcut_cond_r (pred, true_label_p, false_label_p, |
4139 | EXPR_LOC_OR_LOC (expr, input_location)((((IS_ADHOC_LOC (((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))-> base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))-> base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) ? get_location_from_adhoc_loc (line_table , ((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression )) ? (expr)->exp.locus : ((location_t) 0))) : (((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) != ((location_t ) 0)) ? (expr)->exp.locus : (input_location))); |
4140 | |
4141 | /* If our last subexpression already has a terminal label, reuse it. */ |
4142 | if (else_se) |
4143 | t = expr_last (else_); |
4144 | else if (then_se) |
4145 | t = expr_last (then_); |
4146 | else |
4147 | t = NULLnullptr; |
4148 | if (t && TREE_CODE (t)((enum tree_code) (t)->base.code) == LABEL_EXPR) |
4149 | end_label = LABEL_EXPR_LABEL (t)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4149, __FUNCTION__, (LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4149, __FUNCTION__))))); |
4150 | |
4151 | /* If we don't care about jumping to the 'else' branch, jump to the end |
4152 | if the condition is false. */ |
4153 | if (!false_label_p) |
4154 | false_label_p = &end_label; |
4155 | |
4156 | /* We only want to emit these labels if we aren't hijacking them. */ |
4157 | emit_end = (end_label == NULL_TREE(tree) nullptr); |
4158 | emit_false = (false_label == NULL_TREE(tree) nullptr); |
4159 | |
4160 | /* We only emit the jump over the else clause if we have to--if the |
4161 | then clause may fall through. Otherwise we can wind up with a |
4162 | useless jump and a useless label at the end of gimplified code, |
4163 | which will cause us to think that this conditional as a whole |
4164 | falls through even if it doesn't. If we then inline a function |
4165 | which ends with such a condition, that can cause us to issue an |
4166 | inappropriate warning about control reaching the end of a |
4167 | non-void function. */ |
4168 | jump_over_else = block_may_fallthru (then_); |
4169 | |
4170 | pred = shortcut_cond_r (pred, true_label_p, false_label_p, |
4171 | EXPR_LOC_OR_LOC (expr, input_location)((((IS_ADHOC_LOC (((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))-> base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))-> base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) ? get_location_from_adhoc_loc (line_table , ((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression )) ? (expr)->exp.locus : ((location_t) 0))) : (((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) != ((location_t ) 0)) ? (expr)->exp.locus : (input_location))); |
4172 | |
4173 | expr = NULLnullptr; |
4174 | append_to_statement_list (pred, &expr); |
4175 | |
4176 | append_to_statement_list (then_, &expr); |
4177 | if (else_se) |
4178 | { |
4179 | if (jump_over_else) |
4180 | { |
4181 | tree last = expr_last (expr); |
4182 | t = build_and_jump (&end_label); |
4183 | if (rexpr_has_location (last)) |
4184 | SET_EXPR_LOCATION (t, rexpr_location (last))(expr_check (((t)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4184, __FUNCTION__))->exp.locus = (rexpr_location (last) ); |
4185 | append_to_statement_list (t, &expr); |
4186 | } |
4187 | if (emit_false) |
4188 | { |
4189 | t = build1 (LABEL_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], false_label); |
4190 | append_to_statement_list (t, &expr); |
4191 | } |
4192 | append_to_statement_list (else_, &expr); |
4193 | } |
4194 | if (emit_end && end_label) |
4195 | { |
4196 | t = build1 (LABEL_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], end_label); |
4197 | append_to_statement_list (t, &expr); |
4198 | } |
4199 | |
4200 | return expr; |
4201 | } |
4202 | |
4203 | /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */ |
4204 | |
4205 | tree |
4206 | gimple_boolify (tree expr) |
4207 | { |
4208 | tree type = TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4208, __FUNCTION__))->typed.type); |
4209 | location_t loc = EXPR_LOCATION (expr)((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression )) ? (expr)->exp.locus : ((location_t) 0)); |
4210 | |
4211 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == NE_EXPR |
4212 | && TREE_CODE (TREE_OPERAND (expr, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4212, __FUNCTION__))))))->base.code) == CALL_EXPR |
4213 | && integer_zerop (TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4213, __FUNCTION__))))))) |
4214 | { |
4215 | tree call = TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4215, __FUNCTION__))))); |
4216 | tree fn = get_callee_fndecl (call); |
4217 | |
4218 | /* For __builtin_expect ((long) (x), y) recurse into x as well |
4219 | if x is truth_value_p. */ |
4220 | if (fn |
4221 | && fndecl_built_in_p (fn, BUILT_IN_EXPECT) |
4222 | && call_expr_nargs (call)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((call), (tcc_vl_exp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4222, __FUNCTION__))->exp.operands[0]), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4222, __FUNCTION__)))) - 3) == 2) |
4223 | { |
4224 | tree arg = CALL_EXPR_ARG (call, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((call), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4224, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4224, __FUNCTION__))))); |
4225 | if (arg) |
4226 | { |
4227 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == NOP_EXPR |
4228 | && TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4228, __FUNCTION__))->typed.type) == TREE_TYPE (call)((contains_struct_check ((call), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4228, __FUNCTION__))->typed.type)) |
4229 | arg = TREE_OPERAND (arg, 0)(*((const_cast<tree*> (tree_operand_check ((arg), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4229, __FUNCTION__))))); |
4230 | if (truth_value_p (TREE_CODE (arg)((enum tree_code) (arg)->base.code))) |
4231 | { |
4232 | arg = gimple_boolify (arg); |
4233 | CALL_EXPR_ARG (call, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((call), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4233, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4233, __FUNCTION__))))) |
4234 | = fold_convert_loc (loc, TREE_TYPE (call)((contains_struct_check ((call), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4234, __FUNCTION__))->typed.type), arg); |
4235 | } |
4236 | } |
4237 | } |
4238 | } |
4239 | |
4240 | switch (TREE_CODE (expr)((enum tree_code) (expr)->base.code)) |
4241 | { |
4242 | case TRUTH_AND_EXPR: |
4243 | case TRUTH_OR_EXPR: |
4244 | case TRUTH_XOR_EXPR: |
4245 | case TRUTH_ANDIF_EXPR: |
4246 | case TRUTH_ORIF_EXPR: |
4247 | /* Also boolify the arguments of truth exprs. */ |
4248 | TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4248, __FUNCTION__))))) = gimple_boolify (TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4248, __FUNCTION__)))))); |
4249 | /* FALLTHRU */ |
4250 | |
4251 | case TRUTH_NOT_EXPR: |
4252 | TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4252, __FUNCTION__))))) = gimple_boolify (TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4252, __FUNCTION__)))))); |
4253 | |
4254 | /* These expressions always produce boolean results. */ |
4255 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) != BOOLEAN_TYPE) |
4256 | TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4256, __FUNCTION__))->typed.type) = boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE]; |
4257 | return expr; |
4258 | |
4259 | case ANNOTATE_EXPR: |
4260 | switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1))((unsigned long) (*tree_int_cst_elt_check (((*((const_cast< tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4260, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4260, __FUNCTION__)))) |
4261 | { |
4262 | case annot_expr_ivdep_kind: |
4263 | case annot_expr_unroll_kind: |
4264 | case annot_expr_no_vector_kind: |
4265 | case annot_expr_vector_kind: |
4266 | case annot_expr_parallel_kind: |
4267 | TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4267, __FUNCTION__))))) = gimple_boolify (TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4267, __FUNCTION__)))))); |
4268 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) != BOOLEAN_TYPE) |
4269 | TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4269, __FUNCTION__))->typed.type) = boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE]; |
4270 | return expr; |
4271 | default: |
4272 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4272, __FUNCTION__)); |
4273 | } |
4274 | |
4275 | default: |
4276 | if (COMPARISON_CLASS_P (expr)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (expr)->base.code))] == tcc_comparison)) |
4277 | { |
4278 | /* These expressions always produce boolean results. */ |
4279 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) != BOOLEAN_TYPE) |
4280 | TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4280, __FUNCTION__))->typed.type) = boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE]; |
4281 | return expr; |
4282 | } |
4283 | /* Other expressions that get here must have boolean values, but |
4284 | might need to be converted to the appropriate mode. */ |
4285 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == BOOLEAN_TYPE) |
4286 | return expr; |
4287 | return fold_convert_loc (loc, boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], expr); |
4288 | } |
4289 | } |
4290 | |
4291 | /* Given a conditional expression *EXPR_P without side effects, gimplify |
4292 | its operands. New statements are inserted to PRE_P. */ |
4293 | |
4294 | static enum gimplify_status |
4295 | gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p) |
4296 | { |
4297 | tree expr = *expr_p, cond; |
4298 | enum gimplify_status ret, tret; |
4299 | enum tree_code code; |
4300 | |
4301 | cond = gimple_boolify (COND_EXPR_COND (expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4301, __FUNCTION__, (COND_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4301, __FUNCTION__))))))); |
4302 | |
4303 | /* We need to handle && and || specially, as their gimplification |
4304 | creates pure cond_expr, thus leading to an infinite cycle otherwise. */ |
4305 | code = TREE_CODE (cond)((enum tree_code) (cond)->base.code); |
4306 | if (code == TRUTH_ANDIF_EXPR) |
4307 | TREE_SET_CODE (cond, TRUTH_AND_EXPR)((cond)->base.code = (TRUTH_AND_EXPR)); |
4308 | else if (code == TRUTH_ORIF_EXPR) |
4309 | TREE_SET_CODE (cond, TRUTH_OR_EXPR)((cond)->base.code = (TRUTH_OR_EXPR)); |
4310 | ret = gimplify_expr (&cond, pre_p, NULLnullptr, is_gimple_val, fb_rvalue); |
4311 | COND_EXPR_COND (*expr_p)((*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4311, __FUNCTION__, (COND_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4311, __FUNCTION__)))))) = cond; |
4312 | |
4313 | tret = gimplify_expr (&COND_EXPR_THEN (expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4313, __FUNCTION__, (COND_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4313, __FUNCTION__)))))), pre_p, NULLnullptr, |
4314 | is_gimple_val, fb_rvalue); |
4315 | ret = MIN (ret, tret)((ret) < (tret) ? (ret) : (tret)); |
4316 | tret = gimplify_expr (&COND_EXPR_ELSE (expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4316, __FUNCTION__, (COND_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4316, __FUNCTION__)))))), pre_p, NULLnullptr, |
4317 | is_gimple_val, fb_rvalue); |
4318 | |
4319 | return MIN (ret, tret)((ret) < (tret) ? (ret) : (tret)); |
4320 | } |
4321 | |
4322 | /* Return true if evaluating EXPR could trap. |
4323 | EXPR is GENERIC, while tree_could_trap_p can be called |
4324 | only on GIMPLE. */ |
4325 | |
4326 | bool |
4327 | generic_expr_could_trap_p (tree expr) |
4328 | { |
4329 | unsigned i, n; |
4330 | |
4331 | if (!expr || is_gimple_val (expr)) |
4332 | return false; |
4333 | |
4334 | if (!EXPR_P (expr)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (expr)->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (expr)->base.code))]) <= tcc_expression) || tree_could_trap_p (expr)) |
4335 | return true; |
4336 | |
4337 | n = TREE_OPERAND_LENGTH (expr)tree_operand_length (expr); |
4338 | for (i = 0; i < n; i++) |
4339 | if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)(*((const_cast<tree*> (tree_operand_check ((expr), (i), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4339, __FUNCTION__))))))) |
4340 | return true; |
4341 | |
4342 | return false; |
4343 | } |
4344 | |
4345 | /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;' |
4346 | into |
4347 | |
4348 | if (p) if (p) |
4349 | t1 = a; a; |
4350 | else or else |
4351 | t1 = b; b; |
4352 | t1; |
4353 | |
4354 | The second form is used when *EXPR_P is of type void. |
4355 | |
4356 | PRE_P points to the list where side effects that must happen before |
4357 | *EXPR_P should be stored. */ |
4358 | |
4359 | static enum gimplify_status |
4360 | gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback) |
4361 | { |
4362 | tree expr = *expr_p; |
4363 | tree type = TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4363, __FUNCTION__))->typed.type); |
4364 | location_t loc = EXPR_LOCATION (expr)((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression )) ? (expr)->exp.locus : ((location_t) 0)); |
4365 | tree tmp, arm1, arm2; |
4366 | enum gimplify_status ret; |
4367 | tree label_true, label_false, label_cont; |
4368 | bool have_then_clause_p, have_else_clause_p; |
4369 | gcond *cond_stmt; |
4370 | enum tree_code pred_code; |
4371 | gimple_seq seq = NULLnullptr; |
4372 | |
4373 | /* If this COND_EXPR has a value, copy the values into a temporary within |
4374 | the arms. */ |
4375 | if (!VOID_TYPE_P (type)(((enum tree_code) (type)->base.code) == VOID_TYPE)) |
4376 | { |
4377 | tree then_ = TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4377, __FUNCTION__))))), else_ = TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4377, __FUNCTION__))))); |
4378 | tree result; |
4379 | |
4380 | /* If either an rvalue is ok or we do not require an lvalue, create the |
4381 | temporary. But we cannot do that if the type is addressable. */ |
4382 | if (((fallback & fb_rvalue) || !(fallback & fb_lvalue)) |
4383 | && !TREE_ADDRESSABLE (type)((type)->base.addressable_flag)) |
4384 | { |
4385 | if (gimplify_ctxp->allow_rhs_cond_expr |
4386 | /* If either branch has side effects or could trap, it can't be |
4387 | evaluated unconditionally. */ |
4388 | && !TREE_SIDE_EFFECTS (then_)((non_type_check ((then_), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4388, __FUNCTION__))->base.side_effects_flag) |
4389 | && !generic_expr_could_trap_p (then_) |
4390 | && !TREE_SIDE_EFFECTS (else_)((non_type_check ((else_), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4390, __FUNCTION__))->base.side_effects_flag) |
4391 | && !generic_expr_could_trap_p (else_)) |
4392 | return gimplify_pure_cond_expr (expr_p, pre_p); |
4393 | |
4394 | tmp = create_tmp_var (type, "iftmp"); |
4395 | result = tmp; |
4396 | } |
4397 | |
4398 | /* Otherwise, only create and copy references to the values. */ |
4399 | else |
4400 | { |
4401 | type = build_pointer_type (type); |
4402 | |
4403 | if (!VOID_TYPE_P (TREE_TYPE (then_))(((enum tree_code) (((contains_struct_check ((then_), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4403, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE )) |
4404 | then_ = build_fold_addr_expr_loc (loc, then_); |
4405 | |
4406 | if (!VOID_TYPE_P (TREE_TYPE (else_))(((enum tree_code) (((contains_struct_check ((else_), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4406, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE )) |
4407 | else_ = build_fold_addr_expr_loc (loc, else_); |
4408 | |
4409 | expr |
4410 | = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4410, __FUNCTION__))))), then_, else_); |
4411 | |
4412 | tmp = create_tmp_var (type, "iftmp"); |
4413 | result = build_simple_mem_ref_loc (loc, tmp); |
4414 | } |
4415 | |
4416 | /* Build the new then clause, `tmp = then_;'. But don't build the |
4417 | assignment if the value is void; in C++ it can be if it's a throw. */ |
4418 | if (!VOID_TYPE_P (TREE_TYPE (then_))(((enum tree_code) (((contains_struct_check ((then_), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4418, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE )) |
4419 | TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4419, __FUNCTION__))))) = build2 (INIT_EXPR, type, tmp, then_); |
4420 | |
4421 | /* Similarly, build the new else clause, `tmp = else_;'. */ |
4422 | if (!VOID_TYPE_P (TREE_TYPE (else_))(((enum tree_code) (((contains_struct_check ((else_), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4422, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE )) |
4423 | TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4423, __FUNCTION__))))) = build2 (INIT_EXPR, type, tmp, else_); |
4424 | |
4425 | TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4425, __FUNCTION__))->typed.type) = void_type_nodeglobal_trees[TI_VOID_TYPE]; |
4426 | recalculate_side_effects (expr); |
4427 | |
4428 | /* Move the COND_EXPR to the prequeue. */ |
4429 | gimplify_stmt (&expr, pre_p); |
4430 | |
4431 | *expr_p = result; |
4432 | return GS_ALL_DONE; |
4433 | } |
4434 | |
4435 | /* Remove any COMPOUND_EXPR so the following cases will be caught. */ |
4436 | STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0))while ((((((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4436, __FUNCTION__))))))->base.code)) == NOP_EXPR || ((( enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4436, __FUNCTION__))))))->base.code)) == CONVERT_EXPR) || ((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4436, __FUNCTION__))))))->base.code) == NON_LVALUE_EXPR) && (*((const_cast<tree*> (tree_operand_check ( ((*((const_cast<tree*> (tree_operand_check ((expr), (0) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4436, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4436, __FUNCTION__))))) != global_trees[TI_ERROR_MARK] && (((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4436, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4436, __FUNCTION__))->typed.type) == ((contains_struct_check (((*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4436, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4436, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4436, __FUNCTION__))->typed.type))) ((*((const_cast<tree *> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4436, __FUNCTION__)))))) = (*((const_cast<tree*> (tree_operand_check (((*((const_cast<tree*> (tree_operand_check ((expr), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4436, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4436, __FUNCTION__))))); |
4437 | if (TREE_CODE (TREE_OPERAND (expr, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4437, __FUNCTION__))))))->base.code) == COMPOUND_EXPR) |
4438 | gimplify_compound_expr (&TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4438, __FUNCTION__))))), pre_p, true); |
4439 | |
4440 | /* Make sure the condition has BOOLEAN_TYPE. */ |
4441 | TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4441, __FUNCTION__))))) = gimple_boolify (TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4441, __FUNCTION__)))))); |
4442 | |
4443 | /* Break apart && and || conditions. */ |
4444 | if (TREE_CODE (TREE_OPERAND (expr, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4444, __FUNCTION__))))))->base.code) == TRUTH_ANDIF_EXPR |
4445 | || TREE_CODE (TREE_OPERAND (expr, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4445, __FUNCTION__))))))->base.code) == TRUTH_ORIF_EXPR) |
4446 | { |
4447 | expr = shortcut_cond_expr (expr); |
4448 | |
4449 | if (expr != *expr_p) |
4450 | { |
4451 | *expr_p = expr; |
4452 | |
4453 | /* We can't rely on gimplify_expr to re-gimplify the expanded |
4454 | form properly, as cleanups might cause the target labels to be |
4455 | wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to |
4456 | set up a conditional context. */ |
4457 | gimple_push_condition (); |
4458 | gimplify_stmt (expr_p, &seq); |
4459 | gimple_pop_condition (pre_p); |
4460 | gimple_seq_add_seq (pre_p, seq); |
4461 | |
4462 | return GS_ALL_DONE; |
4463 | } |
4464 | } |
4465 | |
4466 | /* Now do the normal gimplification. */ |
4467 | |
4468 | /* Gimplify condition. */ |
4469 | ret = gimplify_expr (&TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4469, __FUNCTION__))))), pre_p, NULLnullptr, |
4470 | is_gimple_condexpr_for_cond, fb_rvalue); |
4471 | if (ret == GS_ERROR) |
4472 | return GS_ERROR; |
4473 | gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE)((void)(!((*((const_cast<tree*> (tree_operand_check ((expr ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4473, __FUNCTION__))))) != (tree) nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4473, __FUNCTION__), 0 : 0)); |
4474 | |
4475 | gimple_push_condition (); |
4476 | |
4477 | have_then_clause_p = have_else_clause_p = false; |
4478 | label_true = find_goto_label (TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4478, __FUNCTION__)))))); |
4479 | if (label_true |
4480 | && DECL_CONTEXT (GOTO_DESTINATION (label_true))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check (((tree_check ((label_true), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4480, __FUNCTION__, (GOTO_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4480, __FUNCTION__)))))), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4480, __FUNCTION__))->decl_minimal.context) == current_function_decl |
4481 | /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR |
4482 | have different locations, otherwise we end up with incorrect |
4483 | location information on the branches. */ |
4484 | && (optimizeglobal_options.x_optimize |
4485 | || !EXPR_HAS_LOCATION (expr)(((IS_ADHOC_LOC (((((expr)) && ((tree_code_type_tmpl < 0>::tree_code_type[(int) (((enum tree_code) ((expr))->base .code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))-> base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) ? get_location_from_adhoc_loc (line_table , ((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression )) ? (expr)->exp.locus : ((location_t) 0))) : (((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) != ((location_t ) 0)) |
4486 | || !rexpr_has_location (label_true) |
4487 | || EXPR_LOCATION (expr)((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression )) ? (expr)->exp.locus : ((location_t) 0)) == rexpr_location (label_true))) |
4488 | { |
4489 | have_then_clause_p = true; |
4490 | label_true = GOTO_DESTINATION (label_true)(*((const_cast<tree*> (tree_operand_check (((tree_check ((label_true), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4490, __FUNCTION__, (GOTO_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4490, __FUNCTION__))))); |
4491 | } |
4492 | else |
4493 | label_true = create_artificial_label (UNKNOWN_LOCATION((location_t) 0)); |
4494 | label_false = find_goto_label (TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4494, __FUNCTION__)))))); |
4495 | if (label_false |
4496 | && DECL_CONTEXT (GOTO_DESTINATION (label_false))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check (((tree_check ((label_false), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4496, __FUNCTION__, (GOTO_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4496, __FUNCTION__)))))), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4496, __FUNCTION__))->decl_minimal.context) == current_function_decl |
4497 | /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR |
4498 | have different locations, otherwise we end up with incorrect |
4499 | location information on the branches. */ |
4500 | && (optimizeglobal_options.x_optimize |
4501 | || !EXPR_HAS_LOCATION (expr)(((IS_ADHOC_LOC (((((expr)) && ((tree_code_type_tmpl < 0>::tree_code_type[(int) (((enum tree_code) ((expr))->base .code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))-> base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) ? get_location_from_adhoc_loc (line_table , ((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression )) ? (expr)->exp.locus : ((location_t) 0))) : (((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression)) ? (expr)->exp.locus : ((location_t) 0)))) != ((location_t ) 0)) |
4502 | || !rexpr_has_location (label_false) |
4503 | || EXPR_LOCATION (expr)((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression )) ? (expr)->exp.locus : ((location_t) 0)) == rexpr_location (label_false))) |
4504 | { |
4505 | have_else_clause_p = true; |
4506 | label_false = GOTO_DESTINATION (label_false)(*((const_cast<tree*> (tree_operand_check (((tree_check ((label_false), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4506, __FUNCTION__, (GOTO_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4506, __FUNCTION__))))); |
4507 | } |
4508 | else |
4509 | label_false = create_artificial_label (UNKNOWN_LOCATION((location_t) 0)); |
4510 | |
4511 | gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4511, __FUNCTION__, (COND_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4511, __FUNCTION__)))))), &pred_code, &arm1, |
4512 | &arm2); |
4513 | cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true, |
4514 | label_false); |
4515 | gimple_set_location (cond_stmt, EXPR_LOCATION (expr)((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression )) ? (expr)->exp.locus : ((location_t) 0))); |
4516 | copy_warning (cond_stmt, COND_EXPR_COND (expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4516, __FUNCTION__, (COND_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4516, __FUNCTION__))))))); |
4517 | gimplify_seq_add_stmt (&seq, cond_stmt); |
4518 | gimple_stmt_iterator gsi = gsi_last (seq); |
4519 | maybe_fold_stmt (&gsi); |
4520 | |
4521 | label_cont = NULL_TREE(tree) nullptr; |
4522 | if (!have_then_clause_p) |
4523 | { |
4524 | /* For if (...) {} else { code; } put label_true after |
4525 | the else block. */ |
4526 | if (TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4526, __FUNCTION__))))) == NULL_TREE(tree) nullptr |
4527 | && !have_else_clause_p |
4528 | && TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4528, __FUNCTION__))))) != NULL_TREE(tree) nullptr) |
4529 | { |
4530 | /* For if (0) {} else { code; } tell -Wimplicit-fallthrough |
4531 | handling that label_cont == label_true can be only reached |
4532 | through fallthrough from { code; }. */ |
4533 | if (integer_zerop (COND_EXPR_COND (expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4533, __FUNCTION__, (COND_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4533, __FUNCTION__)))))))) |
4534 | UNUSED_LABEL_P (label_true)((tree_check ((label_true), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4534, __FUNCTION__, (LABEL_DECL)))->base.default_def_flag ) = 1; |
4535 | label_cont = label_true; |
4536 | } |
4537 | else |
4538 | { |
4539 | bool then_side_effects |
4540 | = (TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4540, __FUNCTION__))))) |
4541 | && TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))((non_type_check (((*((const_cast<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4541, __FUNCTION__)))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4541, __FUNCTION__))->base.side_effects_flag)); |
4542 | gimplify_seq_add_stmt (&seq, gimple_build_label (label_true)); |
4543 | have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4543, __FUNCTION__))))), &seq); |
4544 | /* For if (...) { code; } else {} or |
4545 | if (...) { code; } else goto label; or |
4546 | if (...) { code; return; } else { ... } |
4547 | label_cont isn't needed. */ |
4548 | if (!have_else_clause_p |
4549 | && TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4549, __FUNCTION__))))) != NULL_TREE(tree) nullptr |
4550 | && gimple_seq_may_fallthru (seq)) |
4551 | { |
4552 | gimple *g; |
4553 | label_cont = create_artificial_label (UNKNOWN_LOCATION((location_t) 0)); |
4554 | |
4555 | /* For if (0) { non-side-effect-code } else { code } |
4556 | tell -Wimplicit-fallthrough handling that label_cont can |
4557 | be only reached through fallthrough from { code }. */ |
4558 | if (integer_zerop (COND_EXPR_COND (expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4558, __FUNCTION__, (COND_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4558, __FUNCTION__)))))))) |
4559 | { |
4560 | UNUSED_LABEL_P (label_true)((tree_check ((label_true), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4560, __FUNCTION__, (LABEL_DECL)))->base.default_def_flag ) = 1; |
4561 | if (!then_side_effects) |
4562 | UNUSED_LABEL_P (label_cont)((tree_check ((label_cont), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4562, __FUNCTION__, (LABEL_DECL)))->base.default_def_flag ) = 1; |
4563 | } |
4564 | |
4565 | g = gimple_build_goto (label_cont); |
4566 | |
4567 | /* GIMPLE_COND's are very low level; they have embedded |
4568 | gotos. This particular embedded goto should not be marked |
4569 | with the location of the original COND_EXPR, as it would |
4570 | correspond to the COND_EXPR's condition, not the ELSE or the |
4571 | THEN arms. To avoid marking it with the wrong location, flag |
4572 | it as "no location". */ |
4573 | gimple_set_do_not_emit_location (g); |
4574 | |
4575 | gimplify_seq_add_stmt (&seq, g); |
4576 | } |
4577 | } |
4578 | } |
4579 | if (!have_else_clause_p) |
4580 | { |
4581 | /* For if (1) { code } or if (1) { code } else { non-side-effect-code } |
4582 | tell -Wimplicit-fallthrough handling that label_false can be only |
4583 | reached through fallthrough from { code }. */ |
4584 | if (integer_nonzerop (COND_EXPR_COND (expr)((*((const_cast<tree*> (tree_operand_check (((tree_check ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4584, __FUNCTION__, (COND_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4584, __FUNCTION__))))))) |
4585 | && (TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4585, __FUNCTION__))))) == NULL_TREE(tree) nullptr |
4586 | || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2))((non_type_check (((*((const_cast<tree*> (tree_operand_check ((expr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4586, __FUNCTION__)))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4586, __FUNCTION__))->base.side_effects_flag))) |
4587 | UNUSED_LABEL_P (label_false)((tree_check ((label_false), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4587, __FUNCTION__, (LABEL_DECL)))->base.default_def_flag ) = 1; |
4588 | gimplify_seq_add_stmt (&seq, gimple_build_label (label_false)); |
4589 | have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4589, __FUNCTION__))))), &seq); |
4590 | } |
4591 | if (label_cont) |
4592 | gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont)); |
4593 | |
4594 | gimple_pop_condition (pre_p); |
4595 | gimple_seq_add_seq (pre_p, seq); |
4596 | |
4597 | if (ret == GS_ERROR) |
4598 | ; /* Do nothing. */ |
4599 | else if (have_then_clause_p || have_else_clause_p) |
4600 | ret = GS_ALL_DONE; |
4601 | else |
4602 | { |
4603 | /* Both arms are empty; replace the COND_EXPR with its predicate. */ |
4604 | expr = TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4604, __FUNCTION__))))); |
4605 | gimplify_stmt (&expr, pre_p); |
4606 | } |
4607 | |
4608 | *expr_p = NULLnullptr; |
4609 | return ret; |
4610 | } |
4611 | |
4612 | /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression, |
4613 | to be marked addressable. |
4614 | |
4615 | We cannot rely on such an expression being directly markable if a temporary |
4616 | has been created by the gimplification. In this case, we create another |
4617 | temporary and initialize it with a copy, which will become a store after we |
4618 | mark it addressable. This can happen if the front-end passed us something |
4619 | that it could not mark addressable yet, like a Fortran pass-by-reference |
4620 | parameter (int) floatvar. */ |
4621 | |
4622 | static void |
4623 | prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p) |
4624 | { |
4625 | while (handled_component_p (*expr_p)) |
4626 | expr_p = &TREE_OPERAND (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4626, __FUNCTION__))))); |
4627 | |
4628 | /* Do not allow an SSA name as the temporary. */ |
4629 | if (is_gimple_reg (*expr_p)) |
4630 | *expr_p = internal_get_tmp_var (*expr_p, seq_p, NULLnullptr, false, false, true); |
4631 | } |
4632 | |
4633 | /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with |
4634 | a call to __builtin_memcpy. */ |
4635 | |
4636 | static enum gimplify_status |
4637 | gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value, |
4638 | gimple_seq *seq_p) |
4639 | { |
4640 | tree t, to, to_ptr, from, from_ptr; |
4641 | gcall *gs; |
4642 | location_t loc = EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 )); |
4643 | |
4644 | to = TREE_OPERAND (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4644, __FUNCTION__))))); |
4645 | from = TREE_OPERAND (*expr_p, 1)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4645, __FUNCTION__))))); |
4646 | |
4647 | /* Mark the RHS addressable. Beware that it may not be possible to do so |
4648 | directly if a temporary has been created by the gimplification. */ |
4649 | prepare_gimple_addressable (&from, seq_p); |
4650 | |
4651 | mark_addressable (from); |
4652 | from_ptr = build_fold_addr_expr_loc (loc, from); |
4653 | gimplify_arg (&from_ptr, seq_p, loc); |
4654 | |
4655 | mark_addressable (to); |
4656 | to_ptr = build_fold_addr_expr_loc (loc, to); |
4657 | gimplify_arg (&to_ptr, seq_p, loc); |
4658 | |
4659 | t = builtin_decl_implicit (BUILT_IN_MEMCPY); |
4660 | |
4661 | gs = gimple_build_call (t, 3, to_ptr, from_ptr, size); |
4662 | gimple_call_set_alloca_for_var (gs, true); |
4663 | |
4664 | if (want_value) |
4665 | { |
4666 | /* tmp = memcpy() */ |
4667 | t = create_tmp_var (TREE_TYPE (to_ptr)((contains_struct_check ((to_ptr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4667, __FUNCTION__))->typed.type)); |
4668 | gimple_call_set_lhs (gs, t); |
4669 | gimplify_seq_add_stmt (seq_p, gs); |
4670 | |
4671 | *expr_p = build_simple_mem_ref (t)build_simple_mem_ref_loc (((location_t) 0), t); |
4672 | return GS_ALL_DONE; |
4673 | } |
4674 | |
4675 | gimplify_seq_add_stmt (seq_p, gs); |
4676 | *expr_p = NULLnullptr; |
4677 | return GS_ALL_DONE; |
4678 | } |
4679 | |
4680 | /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with |
4681 | a call to __builtin_memset. In this case we know that the RHS is |
4682 | a CONSTRUCTOR with an empty element list. */ |
4683 | |
4684 | static enum gimplify_status |
4685 | gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value, |
4686 | gimple_seq *seq_p) |
4687 | { |
4688 | tree t, from, to, to_ptr; |
4689 | gcall *gs; |
4690 | location_t loc = EXPR_LOCATION (*expr_p)((((*expr_p)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((*expr_p))->base.code))]) <= tcc_expression)) ? (*expr_p)->exp.locus : ((location_t) 0 )); |
4691 | |
4692 | /* Assert our assumptions, to abort instead of producing wrong code |
4693 | silently if they are not met. Beware that the RHS CONSTRUCTOR might |
4694 | not be immediately exposed. */ |
4695 | from = TREE_OPERAND (*expr_p, 1)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4695, __FUNCTION__))))); |
4696 | if (TREE_CODE (from)((enum tree_code) (from)->base.code) == WITH_SIZE_EXPR) |
4697 | from = TREE_OPERAND (from, 0)(*((const_cast<tree*> (tree_operand_check ((from), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4697, __FUNCTION__))))); |
4698 | |
4699 | gcc_assert (TREE_CODE (from) == CONSTRUCTOR((void)(!(((enum tree_code) (from)->base.code) == CONSTRUCTOR && vec_safe_is_empty (((tree_check ((from), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4700, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4700, __FUNCTION__), 0 : 0)) |
4700 | && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)))((void)(!(((enum tree_code) (from)->base.code) == CONSTRUCTOR && vec_safe_is_empty (((tree_check ((from), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4700, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4700, __FUNCTION__), 0 : 0)); |
4701 | |
4702 | /* Now proceed. */ |
4703 | to = TREE_OPERAND (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4703, __FUNCTION__))))); |
4704 | |
4705 | to_ptr = build_fold_addr_expr_loc (loc, to); |
4706 | gimplify_arg (&to_ptr, seq_p, loc); |
4707 | t = builtin_decl_implicit (BUILT_IN_MEMSET); |
4708 | |
4709 | gs = gimple_build_call (t, 3, to_ptr, integer_zero_nodeglobal_trees[TI_INTEGER_ZERO], size); |
4710 | |
4711 | if (want_value) |
4712 | { |
4713 | /* tmp = memset() */ |
4714 | t = create_tmp_var (TREE_TYPE (to_ptr)((contains_struct_check ((to_ptr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4714, __FUNCTION__))->typed.type)); |
4715 | gimple_call_set_lhs (gs, t); |
4716 | gimplify_seq_add_stmt (seq_p, gs); |
4717 | |
4718 | *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to)((contains_struct_check ((to), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4718, __FUNCTION__))->typed.type), t); |
4719 | return GS_ALL_DONE; |
4720 | } |
4721 | |
4722 | gimplify_seq_add_stmt (seq_p, gs); |
4723 | *expr_p = NULLnullptr; |
4724 | return GS_ALL_DONE; |
4725 | } |
4726 | |
4727 | /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree, |
4728 | determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an |
4729 | assignment. Return non-null if we detect a potential overlap. */ |
4730 | |
4731 | struct gimplify_init_ctor_preeval_data |
4732 | { |
4733 | /* The base decl of the lhs object. May be NULL, in which case we |
4734 | have to assume the lhs is indirect. */ |
4735 | tree lhs_base_decl; |
4736 | |
4737 | /* The alias set of the lhs object. */ |
4738 | alias_set_type lhs_alias_set; |
4739 | }; |
4740 | |
4741 | static tree |
4742 | gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata) |
4743 | { |
4744 | struct gimplify_init_ctor_preeval_data *data |
4745 | = (struct gimplify_init_ctor_preeval_data *) xdata; |
4746 | tree t = *tp; |
4747 | |
4748 | /* If we find the base object, obviously we have overlap. */ |
4749 | if (data->lhs_base_decl == t) |
4750 | return t; |
4751 | |
4752 | /* If the constructor component is indirect, determine if we have a |
4753 | potential overlap with the lhs. The only bits of information we |
4754 | have to go on at this point are addressability and alias sets. */ |
4755 | if ((INDIRECT_REF_P (t)(((enum tree_code) (t)->base.code) == INDIRECT_REF) |
4756 | || TREE_CODE (t)((enum tree_code) (t)->base.code) == MEM_REF) |
4757 | && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl)((data->lhs_base_decl)->base.addressable_flag)) |
4758 | && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t))) |
4759 | return t; |
4760 | |
4761 | /* If the constructor component is a call, determine if it can hide a |
4762 | potential overlap with the lhs through an INDIRECT_REF like above. |
4763 | ??? Ugh - this is completely broken. In fact this whole analysis |
4764 | doesn't look conservative. */ |
4765 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CALL_EXPR) |
4766 | { |
4767 | tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)))((contains_struct_check ((((contains_struct_check (((*((const_cast <tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4767, __FUNCTION__, (CALL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4767, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4767, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4767, __FUNCTION__))->typed.type); |
4768 | |
4769 | for (type = TYPE_ARG_TYPES (fntype)((tree_check2 ((fntype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4769, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values); type; type = TREE_CHAIN (type)((contains_struct_check ((type), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4769, __FUNCTION__))->common.chain)) |
4770 | if (POINTER_TYPE_P (TREE_VALUE (type))(((enum tree_code) (((tree_check ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4770, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == POINTER_TYPE || ((enum tree_code) (((tree_check ((type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4770, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == REFERENCE_TYPE) |
4771 | && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl)((data->lhs_base_decl)->base.addressable_flag)) |
4772 | && alias_sets_conflict_p (data->lhs_alias_set, |
4773 | get_alias_set |
4774 | (TREE_TYPE (TREE_VALUE (type))((contains_struct_check ((((tree_check ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4774, __FUNCTION__, (TREE_LIST)))->list.value)), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4774, __FUNCTION__))->typed.type)))) |
4775 | return t; |
4776 | } |
4777 | |
4778 | if (IS_TYPE_OR_DECL_P (t)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (t)->base.code))] == tcc_type) || (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (t)->base .code))] == tcc_declaration))) |
4779 | *walk_subtrees = 0; |
4780 | return NULLnullptr; |
4781 | } |
4782 | |
4783 | /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR, |
4784 | force values that overlap with the lhs (as described by *DATA) |
4785 | into temporaries. */ |
4786 | |
4787 | static void |
4788 | gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, |
4789 | struct gimplify_init_ctor_preeval_data *data) |
4790 | { |
4791 | enum gimplify_status one; |
4792 | |
4793 | /* If the value is constant, then there's nothing to pre-evaluate. */ |
4794 | if (TREE_CONSTANT (*expr_p)((non_type_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4794, __FUNCTION__))->base.constant_flag)) |
4795 | { |
4796 | /* Ensure it does not have side effects, it might contain a reference to |
4797 | the object we're initializing. */ |
4798 | gcc_assert (!TREE_SIDE_EFFECTS (*expr_p))((void)(!(!((non_type_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4798, __FUNCTION__))->base.side_effects_flag)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4798, __FUNCTION__), 0 : 0)); |
4799 | return; |
4800 | } |
4801 | |
4802 | /* If the type has non-trivial constructors, we can't pre-evaluate. */ |
4803 | if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p))((((contains_struct_check ((*expr_p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4803, __FUNCTION__))->typed.type))->base.addressable_flag )) |
4804 | return; |
4805 | |
4806 | /* Recurse for nested constructors. */ |
4807 | if (TREE_CODE (*expr_p)((enum tree_code) (*expr_p)->base.code) == CONSTRUCTOR) |
4808 | { |
4809 | unsigned HOST_WIDE_INTlong ix; |
4810 | constructor_elt *ce; |
4811 | vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p)((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4811, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); |
4812 | |
4813 | FOR_EACH_VEC_SAFE_ELT (v, ix, ce)for (ix = 0; vec_safe_iterate ((v), (ix), &(ce)); ++(ix)) |
4814 | gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data); |
4815 | |
4816 | return; |
4817 | } |
4818 | |
4819 | /* If this is a variable sized type, we must remember the size. */ |
4820 | maybe_with_size_expr (expr_p); |
4821 | |
4822 | /* Gimplify the constructor element to something appropriate for the rhs |
4823 | of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know |
4824 | the gimplifier will consider this a store to memory. Doing this |
4825 | gimplification now means that we won't have to deal with complicated |
4826 | language-specific trees, nor trees like SAVE_EXPR that can induce |
4827 | exponential search behavior. */ |
4828 | one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue); |
4829 | if (one == GS_ERROR) |
4830 | { |
4831 | *expr_p = NULLnullptr; |
4832 | return; |
4833 | } |
4834 | |
4835 | /* If we gimplified to a bare decl, we can be sure that it doesn't overlap |
4836 | with the lhs, since "a = { .x=a }" doesn't make sense. This will |
4837 | always be true for all scalars, since is_gimple_mem_rhs insists on a |
4838 | temporary variable for them. */ |
4839 | if (DECL_P (*expr_p)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*expr_p)->base.code))] == tcc_declaration)) |
4840 | return; |
4841 | |
4842 | /* If this is of variable size, we have no choice but to assume it doesn't |
4843 | overlap since we can't make a temporary for it. */ |
4844 | if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p)))((enum tree_code) (((tree_class_check ((((contains_struct_check ((*expr_p), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4844, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4844, __FUNCTION__))->type_common.size))->base.code) != INTEGER_CST) |
4845 | return; |
4846 | |
4847 | /* Otherwise, we must search for overlap ... */ |
4848 | if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL)walk_tree_1 (expr_p, gimplify_init_ctor_preeval_1, data, nullptr , nullptr)) |
4849 | return; |
4850 | |
4851 | /* ... and if found, force the value into a temporary. */ |
4852 | *expr_p = get_formal_tmp_var (*expr_p, pre_p); |
4853 | } |
4854 | |
4855 | /* A subroutine of gimplify_init_ctor_eval. Create a loop for |
4856 | a RANGE_EXPR in a CONSTRUCTOR for an array. |
4857 | |
4858 | var = lower; |
4859 | loop_entry: |
4860 | object[var] = value; |
4861 | if (var == upper) |
4862 | goto loop_exit; |
4863 | var = var + 1; |
4864 | goto loop_entry; |
4865 | loop_exit: |
4866 | |
4867 | We increment var _after_ the loop exit check because we might otherwise |
4868 | fail if upper == TYPE_MAX_VALUE (type for upper). |
4869 | |
4870 | Note that we never have to deal with SAVE_EXPRs here, because this has |
4871 | already been taken care of for us, in gimplify_init_ctor_preeval(). */ |
4872 | |
4873 | static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *, |
4874 | gimple_seq *, bool); |
4875 | |
4876 | static void |
4877 | gimplify_init_ctor_eval_range (tree object, tree lower, tree upper, |
4878 | tree value, tree array_elt_type, |
4879 | gimple_seq *pre_p, bool cleared) |
4880 | { |
4881 | tree loop_entry_label, loop_exit_label, fall_thru_label; |
4882 | tree var, var_type, cref, tmp; |
4883 | |
4884 | loop_entry_label = create_artificial_label (UNKNOWN_LOCATION((location_t) 0)); |
4885 | loop_exit_label = create_artificial_label (UNKNOWN_LOCATION((location_t) 0)); |
4886 | fall_thru_label = create_artificial_label (UNKNOWN_LOCATION((location_t) 0)); |
4887 | |
4888 | /* Create and initialize the index variable. */ |
4889 | var_type = TREE_TYPE (upper)((contains_struct_check ((upper), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4889, __FUNCTION__))->typed.type); |
4890 | var = create_tmp_var (var_type); |
4891 | gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower)); |
4892 | |
4893 | /* Add the loop entry label. */ |
4894 | gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label)); |
4895 | |
4896 | /* Build the reference. */ |
4897 | cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object), |
4898 | var, NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr); |
4899 | |
4900 | /* If we are a constructor, just call gimplify_init_ctor_eval to do |
4901 | the store. Otherwise just assign value to the reference. */ |
4902 | |
4903 | if (TREE_CODE (value)((enum tree_code) (value)->base.code) == CONSTRUCTOR) |
4904 | /* NB we might have to call ourself recursively through |
4905 | gimplify_init_ctor_eval if the value is a constructor. */ |
4906 | gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value)((tree_check ((value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4906, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), |
4907 | pre_p, cleared); |
4908 | else |
4909 | { |
4910 | if (gimplify_expr (&value, pre_p, NULLnullptr, is_gimple_val, fb_rvalue) |
4911 | != GS_ERROR) |
4912 | gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value)); |
4913 | } |
4914 | |
4915 | /* We exit the loop when the index var is equal to the upper bound. */ |
4916 | gimplify_seq_add_stmt (pre_p, |
4917 | gimple_build_cond (EQ_EXPR, var, upper, |
4918 | loop_exit_label, fall_thru_label)); |
4919 | |
4920 | gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label)); |
4921 | |
4922 | /* Otherwise, increment the index var... */ |
4923 | tmp = build2 (PLUS_EXPR, var_type, var, |
4924 | fold_convert (var_type, integer_one_node)fold_convert_loc (((location_t) 0), var_type, global_trees[TI_INTEGER_ONE ])); |
4925 | gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp)); |
4926 | |
4927 | /* ...and jump back to the loop entry. */ |
4928 | gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label)); |
4929 | |
4930 | /* Add the loop exit label. */ |
4931 | gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label)); |
4932 | } |
4933 | |
4934 | /* A subroutine of gimplify_init_constructor. Generate individual |
4935 | MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the |
4936 | assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the |
4937 | CONSTRUCTOR. CLEARED is true if the entire LHS object has been |
4938 | zeroed first. */ |
4939 | |
4940 | static void |
4941 | gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts, |
4942 | gimple_seq *pre_p, bool cleared) |
4943 | { |
4944 | tree array_elt_type = NULLnullptr; |
4945 | unsigned HOST_WIDE_INTlong ix; |
4946 | tree purpose, value; |
4947 | |
4948 | if (TREE_CODE (TREE_TYPE (object))((enum tree_code) (((contains_struct_check ((object), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4948, __FUNCTION__))->typed.type))->base.code) == ARRAY_TYPE) |
4949 | array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)))((tree_class_check ((((contains_struct_check ((((contains_struct_check ((object), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4949, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4949, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4949, __FUNCTION__))->type_common.main_variant); |
4950 | |
4951 | FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)for (ix = 0; (ix >= vec_safe_length (elts)) ? false : (((void ) (value = (*elts)[ix].value)), (purpose = (*elts)[ix].index) , true); (ix)++) |
4952 | { |
4953 | tree cref; |
4954 | |
4955 | /* NULL values are created above for gimplification errors. */ |
4956 | if (value == NULLnullptr) |
4957 | continue; |
4958 | |
4959 | if (cleared && initializer_zerop (value)) |
4960 | continue; |
4961 | |
4962 | /* ??? Here's to hoping the front end fills in all of the indices, |
4963 | so we don't have to figure out what's missing ourselves. */ |
4964 | gcc_assert (purpose)((void)(!(purpose) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4964, __FUNCTION__), 0 : 0)); |
4965 | |
4966 | /* Skip zero-sized fields, unless value has side-effects. This can |
4967 | happen with calls to functions returning a empty type, which |
4968 | we shouldn't discard. As a number of downstream passes don't |
4969 | expect sets of empty type fields, we rely on the gimplification of |
4970 | the MODIFY_EXPR we make below to drop the assignment statement. */ |
4971 | if (!TREE_SIDE_EFFECTS (value)((non_type_check ((value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4971, __FUNCTION__))->base.side_effects_flag) |
4972 | && TREE_CODE (purpose)((enum tree_code) (purpose)->base.code) == FIELD_DECL |
4973 | && is_empty_type (TREE_TYPE (purpose)((contains_struct_check ((purpose), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4973, __FUNCTION__))->typed.type))) |
4974 | continue; |
4975 | |
4976 | /* If we have a RANGE_EXPR, we have to build a loop to assign the |
4977 | whole range. */ |
4978 | if (TREE_CODE (purpose)((enum tree_code) (purpose)->base.code) == RANGE_EXPR) |
4979 | { |
4980 | tree lower = TREE_OPERAND (purpose, 0)(*((const_cast<tree*> (tree_operand_check ((purpose), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4980, __FUNCTION__))))); |
4981 | tree upper = TREE_OPERAND (purpose, 1)(*((const_cast<tree*> (tree_operand_check ((purpose), ( 1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4981, __FUNCTION__))))); |
4982 | |
4983 | /* If the lower bound is equal to upper, just treat it as if |
4984 | upper was the index. */ |
4985 | if (simple_cst_equal (lower, upper)) |
4986 | purpose = upper; |
4987 | else |
4988 | { |
4989 | gimplify_init_ctor_eval_range (object, lower, upper, value, |
4990 | array_elt_type, pre_p, cleared); |
4991 | continue; |
4992 | } |
4993 | } |
4994 | |
4995 | if (array_elt_type) |
4996 | { |
4997 | /* Do not use bitsizetype for ARRAY_REF indices. */ |
4998 | if (TYPE_DOMAIN (TREE_TYPE (object))((tree_check ((((contains_struct_check ((object), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4998, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 4998, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )) |
4999 | purpose |
5000 | = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),fold_convert_loc (((location_t) 0), ((contains_struct_check ( (((tree_check ((((contains_struct_check ((object), (TS_TYPED) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5000, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5000, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5000, __FUNCTION__))->typed.type), purpose) |
5001 | purpose)fold_convert_loc (((location_t) 0), ((contains_struct_check ( (((tree_check ((((contains_struct_check ((object), (TS_TYPED) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5000, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5000, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5000, __FUNCTION__))->typed.type), purpose); |
5002 | cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object), |
5003 | purpose, NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr); |
5004 | } |
5005 | else |
5006 | { |
5007 | gcc_assert (TREE_CODE (purpose) == FIELD_DECL)((void)(!(((enum tree_code) (purpose)->base.code) == FIELD_DECL ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5007, __FUNCTION__), 0 : 0)); |
5008 | cref = build3 (COMPONENT_REF, TREE_TYPE (purpose)((contains_struct_check ((purpose), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5008, __FUNCTION__))->typed.type), |
5009 | unshare_expr (object), purpose, NULL_TREE(tree) nullptr); |
5010 | } |
5011 | |
5012 | if (TREE_CODE (value)((enum tree_code) (value)->base.code) == CONSTRUCTOR |
5013 | && TREE_CODE (TREE_TYPE (value))((enum tree_code) (((contains_struct_check ((value), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5013, __FUNCTION__))->typed.type))->base.code) != VECTOR_TYPE) |
5014 | gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value)((tree_check ((value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5014, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), |
5015 | pre_p, cleared); |
5016 | else |
5017 | { |
5018 | tree init = build2 (INIT_EXPR, TREE_TYPE (cref)((contains_struct_check ((cref), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5018, __FUNCTION__))->typed.type), cref, value); |
5019 | gimplify_and_add (init, pre_p); |
5020 | ggc_free (init); |
5021 | } |
5022 | } |
5023 | } |
5024 | |
5025 | /* Return the appropriate RHS predicate for this LHS. */ |
5026 | |
5027 | gimple_predicate |
5028 | rhs_predicate_for (tree lhs) |
5029 | { |
5030 | if (is_gimple_reg (lhs)) |
5031 | return is_gimple_reg_rhs_or_call; |
5032 | else |
5033 | return is_gimple_mem_rhs_or_call; |
5034 | } |
5035 | |
5036 | /* Return the initial guess for an appropriate RHS predicate for this LHS, |
5037 | before the LHS has been gimplified. */ |
5038 | |
5039 | static gimple_predicate |
5040 | initial_rhs_predicate_for (tree lhs) |
5041 | { |
5042 | if (is_gimple_reg_type (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5042, __FUNCTION__))->typed.type))) |
5043 | return is_gimple_reg_rhs_or_call; |
5044 | else |
5045 | return is_gimple_mem_rhs_or_call; |
5046 | } |
5047 | |
5048 | /* Gimplify a C99 compound literal expression. This just means adding |
5049 | the DECL_EXPR before the current statement and using its anonymous |
5050 | decl instead. */ |
5051 | |
5052 | static enum gimplify_status |
5053 | gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p, |
5054 | bool (*gimple_test_f) (tree), |
5055 | fallback_t fallback) |
5056 | { |
5057 | tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p)(*((const_cast<tree*> (tree_operand_check (((tree_check ((*expr_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5057, __FUNCTION__, (COMPOUND_LITERAL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5057, __FUNCTION__))))); |
5058 | tree decl = DECL_EXPR_DECL (decl_s)(*((const_cast<tree*> (tree_operand_check (((tree_check ((decl_s), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5058, __FUNCTION__, (DECL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5058, __FUNCTION__))))); |
5059 | tree init = DECL_INITIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5059, __FUNCTION__))->decl_common.initial); |
5060 | /* Mark the decl as addressable if the compound literal |
5061 | expression is addressable now, otherwise it is marked too late |
5062 | after we gimplify the initialization expression. */ |
5063 | if (TREE_ADDRESSABLE (*expr_p)((*expr_p)->base.addressable_flag)) |
5064 | TREE_ADDRESSABLE (decl)((decl)->base.addressable_flag) = 1; |
5065 | /* Otherwise, if we don't need an lvalue and have a literal directly |
5066 | substitute it. Check if it matches the gimple predicate, as |
5067 | otherwise we'd generate a new temporary, and we can as well just |
5068 | use the decl we already have. */ |
5069 | else if (!TREE_ADDRESSABLE (decl)((decl)->base.addressable_flag) |
5070 | && !TREE_THIS_VOLATILE (decl)((decl)->base.volatile_flag) |
5071 | && init |
5072 | && (fallback & fb_lvalue) == 0 |
5073 | && gimple_test_f (init)) |
5074 | { |
5075 | *expr_p = init; |
5076 | return GS_OK; |
5077 | } |
5078 | |
5079 | /* If the decl is not addressable, then it is being used in some |
5080 | expression or on the right hand side of a statement, and it can |
5081 | be put into a readonly data section. */ |
5082 | if (!TREE_ADDRESSABLE (decl)((decl)->base.addressable_flag) && (fallback & fb_lvalue) == 0) |
5083 | TREE_READONLY (decl)((non_type_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5083, __FUNCTION__))->base.readonly_flag) = 1; |
5084 | |
5085 | /* This decl isn't mentioned in the enclosing block, so add it to the |
5086 | list of temps. FIXME it seems a bit of a kludge to say that |
5087 | anonymous artificial vars aren't pushed, but everything else is. */ |
5088 | if (DECL_NAME (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5088, __FUNCTION__))->decl_minimal.name) == NULL_TREE(tree) nullptr && !DECL_SEEN_IN_BIND_EXPR_P (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5088, __FUNCTION__))->decl_with_vis.seen_in_bind_expr)) |
5089 | gimple_add_tmp_var (decl); |
5090 | |
5091 | gimplify_and_add (decl_s, pre_p); |
5092 | *expr_p = decl; |
5093 | return GS_OK; |
5094 | } |
5095 | |
5096 | /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR, |
5097 | return a new CONSTRUCTOR if something changed. */ |
5098 | |
5099 | static tree |
5100 | optimize_compound_literals_in_ctor (tree orig_ctor) |
5101 | { |
5102 | tree ctor = orig_ctor; |
5103 | vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5103, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); |
5104 | unsigned int idx, num = vec_safe_length (elts); |
5105 | |
5106 | for (idx = 0; idx < num; idx++) |
5107 | { |
5108 | tree value = (*elts)[idx].value; |
5109 | tree newval = value; |
5110 | if (TREE_CODE (value)((enum tree_code) (value)->base.code) == CONSTRUCTOR) |
5111 | newval = optimize_compound_literals_in_ctor (value); |
5112 | else if (TREE_CODE (value)((enum tree_code) (value)->base.code) == COMPOUND_LITERAL_EXPR) |
5113 | { |
5114 | tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value)(*((const_cast<tree*> (tree_operand_check (((tree_check ((value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5114, __FUNCTION__, (COMPOUND_LITERAL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5114, __FUNCTION__))))); |
5115 | tree decl = DECL_EXPR_DECL (decl_s)(*((const_cast<tree*> (tree_operand_check (((tree_check ((decl_s), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5115, __FUNCTION__, (DECL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5115, __FUNCTION__))))); |
5116 | tree init = DECL_INITIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5116, __FUNCTION__))->decl_common.initial); |
5117 | |
5118 | if (!TREE_ADDRESSABLE (value)((value)->base.addressable_flag) |
5119 | && !TREE_ADDRESSABLE (decl)((decl)->base.addressable_flag) |
5120 | && init |
5121 | && TREE_CODE (init)((enum tree_code) (init)->base.code) == CONSTRUCTOR) |
5122 | newval = optimize_compound_literals_in_ctor (init); |
5123 | } |
5124 | if (newval == value) |
5125 | continue; |
5126 | |
5127 | if (ctor == orig_ctor) |
5128 | { |
5129 | ctor = copy_node (orig_ctor); |
5130 | CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5130, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts) = vec_safe_copy (elts); |
5131 | elts = CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5131, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); |
5132 | } |
5133 | (*elts)[idx].value = newval; |
5134 | } |
5135 | return ctor; |
5136 | } |
5137 | |
5138 | /* A subroutine of gimplify_modify_expr. Break out elements of a |
5139 | CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs. |
5140 | |
5141 | Note that we still need to clear any elements that don't have explicit |
5142 | initializers, so if not all elements are initialized we keep the |
5143 | original MODIFY_EXPR, we just remove all of the constructor elements. |
5144 | |
5145 | If NOTIFY_TEMP_CREATION is true, do not gimplify, just return |
5146 | GS_ERROR if we would have to create a temporary when gimplifying |
5147 | this constructor. Otherwise, return GS_OK. |
5148 | |
5149 | If NOTIFY_TEMP_CREATION is false, just do the gimplification. */ |
5150 | |
5151 | static enum gimplify_status |
5152 | gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, |
5153 | bool want_value, bool notify_temp_creation) |
5154 | { |
5155 | tree object, ctor, type; |
5156 | enum gimplify_status ret; |
5157 | vec<constructor_elt, va_gc> *elts; |
5158 | bool cleared = false; |
5159 | bool is_empty_ctor = false; |
5160 | bool is_init_expr = (TREE_CODE (*expr_p)((enum tree_code) (*expr_p)->base.code) == INIT_EXPR); |
5161 | |
5162 | gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR)((void)(!(((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((*expr_p), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5162, __FUNCTION__))))))->base.code) == CONSTRUCTOR) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5162, __FUNCTION__), 0 : 0)); |
5163 | |
5164 | if (!notify_temp_creation) |
5165 | { |
5166 | ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5166, __FUNCTION__))))), pre_p, post_p, |
5167 | is_gimple_lvalue, fb_lvalue); |
5168 | if (ret == GS_ERROR) |
5169 | return ret; |
5170 | } |
5171 | |
5172 | object = TREE_OPERAND (*expr_p, 0)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5172, __FUNCTION__))))); |
5173 | ctor = TREE_OPERAND (*expr_p, 1)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5173, __FUNCTION__))))) |
5174 | = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1)(*((const_cast<tree*> (tree_operand_check ((*expr_p), ( 1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5174, __FUNCTION__)))))); |
5175 | type = TREE_TYPE (ctor)((contains_struct_check ((ctor), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5175, __FUNCTION__))->typed.type); |
5176 | elts = CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5176, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); |
5177 | ret = GS_ALL_DONE; |
5178 | |
5179 | switch (TREE_CODE (type)((enum tree_code) (type)->base.code)) |
5180 | { |
5181 | case RECORD_TYPE: |
5182 | case UNION_TYPE: |
5183 | case QUAL_UNION_TYPE: |
5184 | case ARRAY_TYPE: |
5185 | { |
5186 | /* Use readonly data for initializers of this or smaller size |
5187 | regardless of the num_nonzero_elements / num_unique_nonzero_elements |
5188 | ratio. */ |
5189 | const HOST_WIDE_INTlong min_unique_size = 64; |
5190 | /* If num_nonzero_elements / num_unique_nonzero_elements ratio |
5191 | is smaller than this, use readonly data. */ |
5192 | const int unique_nonzero_ratio = 8; |
5193 | /* True if a single access of the object must be ensured. This is the |
5194 | case if the target is volatile, the type is non-addressable and more |
5195 | than one field need to be assigned. */ |
5196 | const bool ensure_single_access |
5197 | = TREE_THIS_VOLATILE (object)((object)->base.volatile_flag) |
5198 | && !TREE_ADDRESSABLE (type)((type)->base.addressable_flag) |
5199 | && vec_safe_length (elts) > 1; |
5200 | struct gimplify_init_ctor_preeval_data preeval_data; |
5201 | HOST_WIDE_INTlong num_ctor_elements, num_nonzero_elements; |
5202 | HOST_WIDE_INTlong num_unique_nonzero_elements; |
5203 | bool complete_p, valid_const_initializer; |
5204 | |
5205 | /* Aggregate types must lower constructors to initialization of |
5206 | individual elements. The exception is that a CONSTRUCTOR node |
5207 | with no elements indicates zero-initialization of the whole. */ |
5208 | if (vec_safe_is_empty (elts)) |
5209 | { |
5210 | if (notify_temp_creation) |
5211 | return GS_OK; |
5212 | |
5213 | /* The var will be initialized and so appear on lhs of |
5214 | assignment, it can't be TREE_READONLY anymore. */ |
5215 | if (VAR_P (object)(((enum tree_code) (object)->base.code) == VAR_DECL)) |
5216 | TREE_READONLY (object)((non_type_check ((object), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5216, __FUNCTION__))->base.readonly_flag) = 0; |
5217 | |
5218 | is_empty_ctor = true; |
5219 | break; |
5220 | } |
5221 | |
5222 | /* Fetch information about the constructor to direct later processing. |
5223 | We might want to make static versions of it in various cases, and |
5224 | can only do so if it known to be a valid constant initializer. */ |
5225 | valid_const_initializer |
5226 | = categorize_ctor_elements (ctor, &num_nonzero_elements, |
5227 | &num_unique_nonzero_elements, |
5228 | &num_ctor_elements, &complete_p); |
5229 | |
5230 | /* If a const aggregate variable is being initialized, then it |
5231 | should never be a lose to promote the variable to be static. */ |
5232 | if (valid_const_initializer |
5233 | && num_nonzero_elements > 1 |
5234 | && TREE_READONLY (object)((non_type_check ((object), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5234, __FUNCTION__))->base.readonly_flag) |
5235 | && VAR_P (object)(((enum tree_code) (object)->base.code) == VAR_DECL) |
5236 | && !DECL_REGISTER (object)((contains_struct_check ((object), (TS_DECL_WRTL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5236, __FUNCTION__))->decl_common.decl_flag_0) |
5237 | && (flag_merge_constantsglobal_options.x_flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)((object)->base.addressable_flag)) |
5238 | /* For ctors that have many repeated nonzero elements |
5239 | represented through RANGE_EXPRs, prefer initializing |
5240 | those through runtime loops over copies of large amounts |
5241 | of data from readonly data section. */ |
5242 | && (num_unique_nonzero_elements |
5243 | > num_nonzero_elements / unique_nonzero_ratio |
5244 | || ((unsigned HOST_WIDE_INTlong) int_size_in_bytes (type) |
5245 | <= (unsigned HOST_WIDE_INTlong) min_unique_size))) |
5246 | { |
5247 | if (notify_temp_creation) |
5248 | return GS_ERROR; |
5249 | |
5250 | DECL_INITIAL (object)((contains_struct_check ((object), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5250, __FUNCTION__))->decl_common.initial) = ctor; |
5251 | TREE_STATIC (object)((object)->base.static_flag) = 1; |
5252 | if (!DECL_NAME (object)((contains_struct_check ((object), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5252, __FUNCTION__))->decl_minimal.name)) |
5253 | DECL_NAME (object)((contains_struct_check ((object), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5253, __FUNCTION__))->decl_minimal.name) = create_tmp_var_name ("C"); |
5254 | walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL)walk_tree_1 (&((contains_struct_check ((object), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5254, __FUNCTION__))->decl_common.initial), force_labels_r , nullptr, nullptr, nullptr); |
5255 | |
5256 | /* ??? C++ doesn't automatically append a .<number> to the |
5257 | assembler name, and even when it does, it looks at FE private |
5258 | data structures to figure out what that number should be, |
5259 | which are not set for this variable. I suppose this is |
5260 | important for local statics for inline functions, which aren't |
5261 | "local" in the object file sense. So in order to get a unique |
5262 | TU-local symbol, we must invoke the lhd version now. */ |
5263 | lhd_set_decl_assembler_name (object); |
5264 | |
5265 | *expr_p = NULL_TREE(tree) nullptr; |
5266 | break; |
5267 | } |
5268 | |
5269 | /* The var will be initialized and so appear on lhs of |
5270 | assignment, it can't be TREE_READONLY anymore. */ |
5271 | if (VAR_P (object)(((enum tree_code) (object)->base.code) == VAR_DECL) && !notify_temp_creation) |
5272 | TREE_READONLY (object)((non_type_check ((object), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5272, __FUNCTION__))->base.readonly_flag) = 0; |
5273 | |
5274 | /* If there are "lots" of initialized elements, even discounting |
5275 | those that are not address constants (and thus *must* be |
5276 | computed at runtime), then partition the constructor into |
5277 | constant and non-constant parts. Block copy the constant |
5278 | parts in, then generate code for the non-constant parts. */ |
5279 | /* TODO. There's code in cp/typeck.cc to do this. */ |
5280 | |
5281 | if (int_size_in_bytes (TREE_TYPE (ctor)((contains_struct_check ((ctor), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5281, __FUNCTION__))->typed.type)) < 0) |
5282 | /* store_constructor will ignore the clearing of variable-sized |
5283 | objects. Initializers for such objects must explicitly set |
5284 | every field that needs to be set. */ |
5285 | cleared = false; |
5286 | else if (!complete_p) |
5287 | /* If the constructor isn't complete, clear the whole object |
5288 | beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it. |
5289 | |
5290 | ??? This ought not to be needed. For any element not present |
5291 | in the initializer, we should simply set them to zero. Except |
5292 | we'd need to *find* the elements that are not present, and that |
5293 | requires trickery to avoid quadratic compile-time behavior in |
5294 | large cases or excessive memory use in small cases. */ |
5295 | cleared = !CONSTRUCTOR_NO_CLEARING (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimplify.cc" , 5295, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag); |
5296 | else if (num_ctor_elements - num_nonzero_elements |
5297 | > CLEAR_RATIO (optimize_function_for_speed_p (cfun))((optimize_function_for_speed_p ((cfun + 0))) ? ix86_cost-> clear_ratio : 2) |
5298 | && num_nonzero_elements < num_ctor_elements / 4) |
5299 | /* If there are "lots" of zeros, it's more efficient to clear |
5300 | the memory and then set the nonzero elements. */ |
5301 | cleared = true; |
5302 | else if (ensure_single_access && num_nonzero_elements == 0) |
5303 | /* If a single access to the target must be ensured and all elements |
5304 | are zero, then it's optimal to clear whatever their number. */ |
5305 | cleared = true; |
5306 | else |
5307 | cleared = false; |
5308 | |
5309 | /* If there are "lots" of initialized elements, and all of them |
5310 | are valid address constants, then the entire initializer can |
5311 |