Bug Summary

File:build/gcc/tree-cfg.cc
Warning:line 3537, column 2
Value stored to 'lhs' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-suse-linux -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name tree-cfg.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -resource-dir /usr/lib64/clang/15.0.7 -D IN_GCC -D HAVE_CONFIG_H -I . -I . -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/. -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../include -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcpp/include -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcody -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber/bid -I ../libdecnumber -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libbacktrace -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/x86_64-suse-linux -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/backward -internal-isystem /usr/lib64/clang/15.0.7/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-narrowing -Wwrite-strings -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fdeprecated-macro -fdebug-compilation-dir=/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=plist-html -analyzer-config silence-checkers=core.NullDereference -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /buildworker/marxinbox-gcc-clang-static-analyzer/objdir/clang-static-analyzer/2023-03-27-141847-20772-1/report-Qc28yj.plist -x c++ /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc
1/* Control flow functions for trees.
2 Copyright (C) 2001-2023 Free Software Foundation, Inc.
3 Contributed by Diego Novillo <dnovillo@redhat.com>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "backend.h"
25#include "target.h"
26#include "rtl.h"
27#include "tree.h"
28#include "gimple.h"
29#include "cfghooks.h"
30#include "tree-pass.h"
31#include "ssa.h"
32#include "cgraph.h"
33#include "gimple-pretty-print.h"
34#include "diagnostic-core.h"
35#include "fold-const.h"
36#include "trans-mem.h"
37#include "stor-layout.h"
38#include "print-tree.h"
39#include "cfganal.h"
40#include "gimple-iterator.h"
41#include "gimple-fold.h"
42#include "tree-eh.h"
43#include "gimplify-me.h"
44#include "gimple-walk.h"
45#include "tree-cfg.h"
46#include "tree-ssa-loop-manip.h"
47#include "tree-ssa-loop-niter.h"
48#include "tree-into-ssa.h"
49#include "tree-dfa.h"
50#include "tree-ssa.h"
51#include "except.h"
52#include "cfgloop.h"
53#include "tree-ssa-propagate.h"
54#include "value-prof.h"
55#include "tree-inline.h"
56#include "tree-ssa-live.h"
57#include "tree-ssa-dce.h"
58#include "omp-general.h"
59#include "omp-expand.h"
60#include "tree-cfgcleanup.h"
61#include "gimplify.h"
62#include "attribs.h"
63#include "selftest.h"
64#include "opts.h"
65#include "asan.h"
66#include "profile.h"
67#include "sreal.h"
68
69/* This file contains functions for building the Control Flow Graph (CFG)
70 for a function tree. */
71
72/* Local declarations. */
73
74/* Initial capacity for the basic block array. */
75static const int initial_cfg_capacity = 20;
76
77/* This hash table allows us to efficiently lookup all CASE_LABEL_EXPRs
78 which use a particular edge. The CASE_LABEL_EXPRs are chained together
79 via their CASE_CHAIN field, which we clear after we're done with the
80 hash table to prevent problems with duplication of GIMPLE_SWITCHes.
81
82 Access to this list of CASE_LABEL_EXPRs allows us to efficiently
83 update the case vector in response to edge redirections.
84
85 Right now this table is set up and torn down at key points in the
86 compilation process. It would be nice if we could make the table
87 more persistent. The key is getting notification of changes to
88 the CFG (particularly edge removal, creation and redirection). */
89
90static hash_map<edge, tree> *edge_to_cases;
91
92/* If we record edge_to_cases, this bitmap will hold indexes
93 of basic blocks that end in a GIMPLE_SWITCH which we touched
94 due to edge manipulations. */
95
96static bitmap touched_switch_bbs;
97
98/* OpenMP region idxs for blocks during cfg pass. */
99static vec<int> bb_to_omp_idx;
100
101/* CFG statistics. */
102struct cfg_stats_d
103{
104 long num_merged_labels;
105};
106
107static struct cfg_stats_d cfg_stats;
108
109/* Data to pass to replace_block_vars_by_duplicates_1. */
110struct replace_decls_d
111{
112 hash_map<tree, tree> *vars_map;
113 tree to_context;
114};
115
116/* Hash table to store last discriminator assigned for each locus. */
117struct locus_discrim_map
118{
119 int location_line;
120 int discriminator;
121};
122
123/* Hashtable helpers. */
124
125struct locus_discrim_hasher : free_ptr_hash <locus_discrim_map>
126{
127 static inline hashval_t hash (const locus_discrim_map *);
128 static inline bool equal (const locus_discrim_map *,
129 const locus_discrim_map *);
130};
131
132/* Trivial hash function for a location_t. ITEM is a pointer to
133 a hash table entry that maps a location_t to a discriminator. */
134
135inline hashval_t
136locus_discrim_hasher::hash (const locus_discrim_map *item)
137{
138 return item->location_line;
139}
140
141/* Equality function for the locus-to-discriminator map. A and B
142 point to the two hash table entries to compare. */
143
144inline bool
145locus_discrim_hasher::equal (const locus_discrim_map *a,
146 const locus_discrim_map *b)
147{
148 return a->location_line == b->location_line;
149}
150
151static hash_table<locus_discrim_hasher> *discriminator_per_locus;
152
153/* Basic blocks and flowgraphs. */
154static void make_blocks (gimple_seq);
155
156/* Edges. */
157static void make_edges (void);
158static void assign_discriminators (void);
159static void make_cond_expr_edges (basic_block);
160static void make_gimple_switch_edges (gswitch *, basic_block);
161static bool make_goto_expr_edges (basic_block);
162static void make_gimple_asm_edges (basic_block);
163static edge gimple_redirect_edge_and_branch (edge, basic_block);
164static edge gimple_try_redirect_by_replacing_jump (edge, basic_block);
165
166/* Various helpers. */
167static inline bool stmt_starts_bb_p (gimple *, gimple *);
168static int gimple_verify_flow_info (void);
169static void gimple_make_forwarder_block (edge);
170static gimple *first_non_label_stmt (basic_block);
171static bool verify_gimple_transaction (gtransaction *);
172static bool call_can_make_abnormal_goto (gimple *);
173
174/* Flowgraph optimization and cleanup. */
175static void gimple_merge_blocks (basic_block, basic_block);
176static bool gimple_can_merge_blocks_p (basic_block, basic_block);
177static void remove_bb (basic_block);
178static edge find_taken_edge_computed_goto (basic_block, tree);
179static edge find_taken_edge_cond_expr (const gcond *, tree);
180
181void
182init_empty_tree_cfg_for_function (struct function *fn)
183{
184 /* Initialize the basic block array. */
185 init_flow (fn);
186 profile_status_for_fn (fn)((fn)->cfg->x_profile_status) = PROFILE_ABSENT;
187 n_basic_blocks_for_fn (fn)((fn)->cfg->x_n_basic_blocks) = NUM_FIXED_BLOCKS(2);
188 last_basic_block_for_fn (fn)((fn)->cfg->x_last_basic_block) = NUM_FIXED_BLOCKS(2);
189 vec_safe_grow_cleared (basic_block_info_for_fn (fn)((fn)->cfg->x_basic_block_info),
190 initial_cfg_capacity, true);
191
192 /* Build a mapping of labels to their associated blocks. */
193 vec_safe_grow_cleared (label_to_block_map_for_fn (fn)((fn)->cfg->x_label_to_block_map),
194 initial_cfg_capacity, true);
195
196 SET_BASIC_BLOCK_FOR_FN (fn, ENTRY_BLOCK, ENTRY_BLOCK_PTR_FOR_FN (fn))((*((fn)->cfg->x_basic_block_info))[((0))] = (((fn)->
cfg->x_entry_block_ptr)))
;
197 SET_BASIC_BLOCK_FOR_FN (fn, EXIT_BLOCK, EXIT_BLOCK_PTR_FOR_FN (fn))((*((fn)->cfg->x_basic_block_info))[((1))] = (((fn)->
cfg->x_exit_block_ptr)))
;
198
199 ENTRY_BLOCK_PTR_FOR_FN (fn)((fn)->cfg->x_entry_block_ptr)->next_bb
200 = EXIT_BLOCK_PTR_FOR_FN (fn)((fn)->cfg->x_exit_block_ptr);
201 EXIT_BLOCK_PTR_FOR_FN (fn)((fn)->cfg->x_exit_block_ptr)->prev_bb
202 = ENTRY_BLOCK_PTR_FOR_FN (fn)((fn)->cfg->x_entry_block_ptr);
203}
204
205void
206init_empty_tree_cfg (void)
207{
208 init_empty_tree_cfg_for_function (cfun(cfun + 0));
209}
210
211/*---------------------------------------------------------------------------
212 Create basic blocks
213---------------------------------------------------------------------------*/
214
215/* Entry point to the CFG builder for trees. SEQ is the sequence of
216 statements to be added to the flowgraph. */
217
218static void
219build_gimple_cfg (gimple_seq seq)
220{
221 /* Register specific gimple functions. */
222 gimple_register_cfg_hooks ();
223
224 memset ((void *) &cfg_stats, 0, sizeof (cfg_stats));
225
226 init_empty_tree_cfg ();
227
228 make_blocks (seq);
229
230 /* Make sure there is always at least one block, even if it's empty. */
231 if (n_basic_blocks_for_fn (cfun)(((cfun + 0))->cfg->x_n_basic_blocks) == NUM_FIXED_BLOCKS(2))
232 create_empty_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun)(((cfun + 0))->cfg->x_entry_block_ptr));
233
234 /* Adjust the size of the array. */
235 if (basic_block_info_for_fn (cfun)(((cfun + 0))->cfg->x_basic_block_info)->length ()
236 < (size_t) n_basic_blocks_for_fn (cfun)(((cfun + 0))->cfg->x_n_basic_blocks))
237 vec_safe_grow_cleared (basic_block_info_for_fn (cfun)(((cfun + 0))->cfg->x_basic_block_info),
238 n_basic_blocks_for_fn (cfun)(((cfun + 0))->cfg->x_n_basic_blocks));
239
240 /* To speed up statement iterator walks, we first purge dead labels. */
241 cleanup_dead_labels ();
242
243 /* Group case nodes to reduce the number of edges.
244 We do this after cleaning up dead labels because otherwise we miss
245 a lot of obvious case merging opportunities. */
246 group_case_labels ();
247
248 /* Create the edges of the flowgraph. */
249 discriminator_per_locus = new hash_table<locus_discrim_hasher> (13);
250 make_edges ();
251 assign_discriminators ();
252 cleanup_dead_labels ();
253 delete discriminator_per_locus;
254 discriminator_per_locus = NULLnullptr;
255}
256
257/* Look for ANNOTATE calls with loop annotation kind in BB; if found, remove
258 them and propagate the information to LOOP. We assume that the annotations
259 come immediately before the condition in BB, if any. */
260
261static void
262replace_loop_annotate_in_block (basic_block bb, class loop *loop)
263{
264 gimple_stmt_iterator gsi = gsi_last_bb (bb);
265 gimple *stmt = gsi_stmt (gsi);
266
267 if (!(stmt && gimple_code (stmt) == GIMPLE_COND))
268 return;
269
270 for (gsi_prev_nondebug (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
271 {
272 stmt = gsi_stmt (gsi);
273 if (gimple_code (stmt) != GIMPLE_CALL)
274 break;
275 if (!gimple_call_internal_p (stmt)
276 || gimple_call_internal_fn (stmt) != IFN_ANNOTATE)
277 break;
278
279 switch ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1)))
280 {
281 case annot_expr_ivdep_kind:
282 loop->safelen = INT_MAX2147483647;
283 break;
284 case annot_expr_unroll_kind:
285 loop->unroll
286 = (unsigned short) tree_to_shwi (gimple_call_arg (stmt, 2));
287 cfun(cfun + 0)->has_unroll = true;
288 break;
289 case annot_expr_no_vector_kind:
290 loop->dont_vectorize = true;
291 break;
292 case annot_expr_vector_kind:
293 loop->force_vectorize = true;
294 cfun(cfun + 0)->has_force_vectorize_loops = true;
295 break;
296 case annot_expr_parallel_kind:
297 loop->can_be_parallel = true;
298 loop->safelen = INT_MAX2147483647;
299 break;
300 default:
301 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 301, __FUNCTION__))
;
302 }
303
304 stmt = gimple_build_assign (gimple_call_lhs (stmt),
305 gimple_call_arg (stmt, 0));
306 gsi_replace (&gsi, stmt, true);
307 }
308}
309
310/* Look for ANNOTATE calls with loop annotation kind; if found, remove
311 them and propagate the information to the loop. We assume that the
312 annotations come immediately before the condition of the loop. */
313
314static void
315replace_loop_annotate (void)
316{
317 basic_block bb;
318 gimple_stmt_iterator gsi;
319 gimple *stmt;
320
321 for (auto loop : loops_list (cfun(cfun + 0), 0))
322 {
323 /* First look into the header. */
324 replace_loop_annotate_in_block (loop->header, loop);
325
326 /* Then look into the latch, if any. */
327 if (loop->latch)
328 replace_loop_annotate_in_block (loop->latch, loop);
329
330 /* Push the global flag_finite_loops state down to individual loops. */
331 loop->finite_p = flag_finite_loopsglobal_options.x_flag_finite_loops;
332 }
333
334 /* Remove IFN_ANNOTATE. Safeguard for the case loop->latch == NULL. */
335 FOR_EACH_BB_FN (bb, cfun)for (bb = ((cfun + 0))->cfg->x_entry_block_ptr->next_bb
; bb != ((cfun + 0))->cfg->x_exit_block_ptr; bb = bb->
next_bb)
336 {
337 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
338 {
339 stmt = gsi_stmt (gsi);
340 if (gimple_code (stmt) != GIMPLE_CALL)
341 continue;
342 if (!gimple_call_internal_p (stmt)
343 || gimple_call_internal_fn (stmt) != IFN_ANNOTATE)
344 continue;
345
346 switch ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1)))
347 {
348 case annot_expr_ivdep_kind:
349 case annot_expr_unroll_kind:
350 case annot_expr_no_vector_kind:
351 case annot_expr_vector_kind:
352 case annot_expr_parallel_kind:
353 break;
354 default:
355 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 355, __FUNCTION__))
;
356 }
357
358 warning_at (gimple_location (stmt), 0, "ignoring loop annotation");
359 stmt = gimple_build_assign (gimple_call_lhs (stmt),
360 gimple_call_arg (stmt, 0));
361 gsi_replace (&gsi, stmt, true);
362 }
363 }
364}
365
366static unsigned int
367execute_build_cfg (void)
368{
369 gimple_seq body = gimple_body (current_function_decl);
370
371 build_gimple_cfg (body);
372 gimple_set_body (current_function_decl, NULLnullptr);
373 if (dump_file && (dump_flags & TDF_DETAILS))
374 {
375 fprintf (dump_file, "Scope blocks:\n");
376 dump_scope_blocks (dump_file, dump_flags);
377 }
378 cleanup_tree_cfg ();
379
380 bb_to_omp_idx.release ();
381
382 loop_optimizer_init (AVOID_CFG_MODIFICATIONS(LOOPS_MAY_HAVE_MULTIPLE_LATCHES));
383 replace_loop_annotate ();
384 return 0;
385}
386
387namespace {
388
389const pass_data pass_data_build_cfg =
390{
391 GIMPLE_PASS, /* type */
392 "cfg", /* name */
393 OPTGROUP_NONE, /* optinfo_flags */
394 TV_TREE_CFG, /* tv_id */
395 PROP_gimple_leh(1 << 2), /* properties_required */
396 ( PROP_cfg(1 << 3) | PROP_loops(1 << 11) ), /* properties_provided */
397 0, /* properties_destroyed */
398 0, /* todo_flags_start */
399 0, /* todo_flags_finish */
400};
401
402class pass_build_cfg : public gimple_opt_pass
403{
404public:
405 pass_build_cfg (gcc::context *ctxt)
406 : gimple_opt_pass (pass_data_build_cfg, ctxt)
407 {}
408
409 /* opt_pass methods: */
410 unsigned int execute (function *) final override
411 {
412 return execute_build_cfg ();
413 }
414
415}; // class pass_build_cfg
416
417} // anon namespace
418
419gimple_opt_pass *
420make_pass_build_cfg (gcc::context *ctxt)
421{
422 return new pass_build_cfg (ctxt);
423}
424
425
426/* Return true if T is a computed goto. */
427
428bool
429computed_goto_p (gimple *t)
430{
431 return (gimple_code (t) == GIMPLE_GOTO
432 && TREE_CODE (gimple_goto_dest (t))((enum tree_code) (gimple_goto_dest (t))->base.code) != LABEL_DECL);
433}
434
435/* Returns true if the sequence of statements STMTS only contains
436 a call to __builtin_unreachable (). */
437
438bool
439gimple_seq_unreachable_p (gimple_seq stmts)
440{
441 if (stmts == NULLnullptr
442 /* Return false if -fsanitize=unreachable, we don't want to
443 optimize away those calls, but rather turn them into
444 __ubsan_handle_builtin_unreachable () or __builtin_trap ()
445 later. */
446 || sanitize_flags_p (SANITIZE_UNREACHABLE))
447 return false;
448
449 gimple_stmt_iterator gsi = gsi_last (stmts);
450
451 if (!gimple_call_builtin_p (gsi_stmt (gsi), BUILT_IN_UNREACHABLE))
452 return false;
453
454 for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
455 {
456 gimple *stmt = gsi_stmt (gsi);
457 if (gimple_code (stmt) != GIMPLE_LABEL
458 && !is_gimple_debug (stmt)
459 && !gimple_clobber_p (stmt))
460 return false;
461 }
462 return true;
463}
464
465/* Returns true for edge E where e->src ends with a GIMPLE_COND and
466 the other edge points to a bb with just __builtin_unreachable ().
467 I.e. return true for C->M edge in:
468 <bb C>:
469 ...
470 if (something)
471 goto <bb N>;
472 else
473 goto <bb M>;
474 <bb N>:
475 __builtin_unreachable ();
476 <bb M>: */
477
478bool
479assert_unreachable_fallthru_edge_p (edge e)
480{
481 basic_block pred_bb = e->src;
482 gimple *last = last_stmt (pred_bb);
483 if (last && gimple_code (last) == GIMPLE_COND)
484 {
485 basic_block other_bb = EDGE_SUCC (pred_bb, 0)(*(pred_bb)->succs)[(0)]->dest;
486 if (other_bb == e->dest)
487 other_bb = EDGE_SUCC (pred_bb, 1)(*(pred_bb)->succs)[(1)]->dest;
488 if (EDGE_COUNT (other_bb->succs)vec_safe_length (other_bb->succs) == 0)
489 return gimple_seq_unreachable_p (bb_seq (other_bb));
490 }
491 return false;
492}
493
494
495/* Initialize GF_CALL_CTRL_ALTERING flag, which indicates the call
496 could alter control flow except via eh. We initialize the flag at
497 CFG build time and only ever clear it later. */
498
499static void
500gimple_call_initialize_ctrl_altering (gimple *stmt)
501{
502 int flags = gimple_call_flags (stmt);
503
504 /* A call alters control flow if it can make an abnormal goto. */
505 if (call_can_make_abnormal_goto (stmt)
506 /* A call also alters control flow if it does not return. */
507 || flags & ECF_NORETURN(1 << 3)
508 /* TM ending statements have backedges out of the transaction.
509 Return true so we split the basic block containing them.
510 Note that the TM_BUILTIN test is merely an optimization. */
511 || ((flags & ECF_TM_BUILTIN(1 << 13))
512 && is_tm_ending_fndecl (gimple_call_fndecl (stmt)))
513 /* BUILT_IN_RETURN call is same as return statement. */
514 || gimple_call_builtin_p (stmt, BUILT_IN_RETURN)
515 /* IFN_UNIQUE should be the last insn, to make checking for it
516 as cheap as possible. */
517 || (gimple_call_internal_p (stmt)
518 && gimple_call_internal_unique_p (stmt)))
519 gimple_call_set_ctrl_altering (stmt, true);
520 else
521 gimple_call_set_ctrl_altering (stmt, false);
522}
523
524
525/* Insert SEQ after BB and build a flowgraph. */
526
527static basic_block
528make_blocks_1 (gimple_seq seq, basic_block bb)
529{
530 gimple_stmt_iterator i = gsi_start (seq);
531 gimple *stmt = NULLnullptr;
532 gimple *prev_stmt = NULLnullptr;
533 bool start_new_block = true;
534 bool first_stmt_of_seq = true;
535
536 while (!gsi_end_p (i))
537 {
538 /* PREV_STMT should only be set to a debug stmt if the debug
539 stmt is before nondebug stmts. Once stmt reaches a nondebug
540 nonlabel, prev_stmt will be set to it, so that
541 stmt_starts_bb_p will know to start a new block if a label is
542 found. However, if stmt was a label after debug stmts only,
543 keep the label in prev_stmt even if we find further debug
544 stmts, for there may be other labels after them, and they
545 should land in the same block. */
546 if (!prev_stmt || !stmt || !is_gimple_debug (stmt))
547 prev_stmt = stmt;
548 stmt = gsi_stmt (i);
549
550 if (stmt && is_gimple_call (stmt))
551 gimple_call_initialize_ctrl_altering (stmt);
552
553 /* If the statement starts a new basic block or if we have determined
554 in a previous pass that we need to create a new block for STMT, do
555 so now. */
556 if (start_new_block || stmt_starts_bb_p (stmt, prev_stmt))
557 {
558 if (!first_stmt_of_seq)
559 gsi_split_seq_before (&i, &seq);
560 bb = create_basic_block (seq, bb);
561 start_new_block = false;
562 prev_stmt = NULLnullptr;
563 }
564
565 /* Now add STMT to BB and create the subgraphs for special statement
566 codes. */
567 gimple_set_bb (stmt, bb);
568
569 /* If STMT is a basic block terminator, set START_NEW_BLOCK for the
570 next iteration. */
571 if (stmt_ends_bb_p (stmt))
572 {
573 /* If the stmt can make abnormal goto use a new temporary
574 for the assignment to the LHS. This makes sure the old value
575 of the LHS is available on the abnormal edge. Otherwise
576 we will end up with overlapping life-ranges for abnormal
577 SSA names. */
578 if (gimple_has_lhs (stmt)
579 && stmt_can_make_abnormal_goto (stmt)
580 && is_gimple_reg_type (TREE_TYPE (gimple_get_lhs (stmt))((contains_struct_check ((gimple_get_lhs (stmt)), (TS_TYPED),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 580, __FUNCTION__))->typed.type)
))
581 {
582 tree lhs = gimple_get_lhs (stmt);
583 tree tmp = create_tmp_var (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 583, __FUNCTION__))->typed.type)
);
584 gimple *s = gimple_build_assign (lhs, tmp);
585 gimple_set_location (s, gimple_location (stmt));
586 gimple_set_block (s, gimple_block (stmt));
587 gimple_set_lhs (stmt, tmp);
588 gsi_insert_after (&i, s, GSI_SAME_STMT);
589 }
590 start_new_block = true;
591 }
592
593 gsi_next (&i);
594 first_stmt_of_seq = false;
595 }
596 return bb;
597}
598
599/* Build a flowgraph for the sequence of stmts SEQ. */
600
601static void
602make_blocks (gimple_seq seq)
603{
604 /* Look for debug markers right before labels, and move the debug
605 stmts after the labels. Accepting labels among debug markers
606 adds no value, just complexity; if we wanted to annotate labels
607 with view numbers (so sequencing among markers would matter) or
608 somesuch, we're probably better off still moving the labels, but
609 adding other debug annotations in their original positions or
610 emitting nonbind or bind markers associated with the labels in
611 the original position of the labels.
612
613 Moving labels would probably be simpler, but we can't do that:
614 moving labels assigns label ids to them, and doing so because of
615 debug markers makes for -fcompare-debug and possibly even codegen
616 differences. So, we have to move the debug stmts instead. To
617 that end, we scan SEQ backwards, marking the position of the
618 latest (earliest we find) label, and moving debug stmts that are
619 not separated from it by nondebug nonlabel stmts after the
620 label. */
621 if (MAY_HAVE_DEBUG_MARKER_STMTSglobal_options.x_debug_nonbind_markers_p)
622 {
623 gimple_stmt_iterator label = gsi_none ();
624
625 for (gimple_stmt_iterator i = gsi_last (seq); !gsi_end_p (i); gsi_prev (&i))
626 {
627 gimple *stmt = gsi_stmt (i);
628
629 /* If this is the first label we encounter (latest in SEQ)
630 before nondebug stmts, record its position. */
631 if (is_a <glabel *> (stmt))
632 {
633 if (gsi_end_p (label))
634 label = i;
635 continue;
636 }
637
638 /* Without a recorded label position to move debug stmts to,
639 there's nothing to do. */
640 if (gsi_end_p (label))
641 continue;
642
643 /* Move the debug stmt at I after LABEL. */
644 if (is_gimple_debug (stmt))
645 {
646 gcc_assert (gimple_debug_nonbind_marker_p (stmt))((void)(!(gimple_debug_nonbind_marker_p (stmt)) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 646, __FUNCTION__), 0 : 0))
;
647 /* As STMT is removed, I advances to the stmt after
648 STMT, so the gsi_prev in the for "increment"
649 expression gets us to the stmt we're to visit after
650 STMT. LABEL, however, would advance to the moved
651 stmt if we passed it to gsi_move_after, so pass it a
652 copy instead, so as to keep LABEL pointing to the
653 LABEL. */
654 gimple_stmt_iterator copy = label;
655 gsi_move_after (&i, &copy);
656 continue;
657 }
658
659 /* There aren't any (more?) debug stmts before label, so
660 there isn't anything else to move after it. */
661 label = gsi_none ();
662 }
663 }
664
665 make_blocks_1 (seq, ENTRY_BLOCK_PTR_FOR_FN (cfun)(((cfun + 0))->cfg->x_entry_block_ptr));
666}
667
668/* Create and return a new empty basic block after bb AFTER. */
669
670static basic_block
671create_bb (void *h, void *e, basic_block after)
672{
673 basic_block bb;
674
675 gcc_assert (!e)((void)(!(!e) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 675, __FUNCTION__), 0 : 0))
;
676
677 /* Create and initialize a new basic block. Since alloc_block uses
678 GC allocation that clears memory to allocate a basic block, we do
679 not have to clear the newly allocated basic block here. */
680 bb = alloc_block ();
681
682 bb->index = last_basic_block_for_fn (cfun)(((cfun + 0))->cfg->x_last_basic_block);
683 bb->flags = BB_NEW;
684 set_bb_seq (bb, h ? (gimple_seq) h : NULLnullptr);
685
686 /* Add the new block to the linked list of blocks. */
687 link_block (bb, after);
688
689 /* Grow the basic block array if needed. */
690 if ((size_t) last_basic_block_for_fn (cfun)(((cfun + 0))->cfg->x_last_basic_block)
691 == basic_block_info_for_fn (cfun)(((cfun + 0))->cfg->x_basic_block_info)->length ())
692 vec_safe_grow_cleared (basic_block_info_for_fn (cfun)(((cfun + 0))->cfg->x_basic_block_info),
693 last_basic_block_for_fn (cfun)(((cfun + 0))->cfg->x_last_basic_block) + 1);
694
695 /* Add the newly created block to the array. */
696 SET_BASIC_BLOCK_FOR_FN (cfun, last_basic_block_for_fn (cfun), bb)((*(((cfun + 0))->cfg->x_basic_block_info))[((((cfun + 0
))->cfg->x_last_basic_block))] = (bb))
;
697
698 n_basic_blocks_for_fn (cfun)(((cfun + 0))->cfg->x_n_basic_blocks)++;
699 last_basic_block_for_fn (cfun)(((cfun + 0))->cfg->x_last_basic_block)++;
700
701 return bb;
702}
703
704
705/*---------------------------------------------------------------------------
706 Edge creation
707---------------------------------------------------------------------------*/
708
709/* If basic block BB has an abnormal edge to a basic block
710 containing IFN_ABNORMAL_DISPATCHER internal call, return
711 that the dispatcher's basic block, otherwise return NULL. */
712
713basic_block
714get_abnormal_succ_dispatcher (basic_block bb)
715{
716 edge e;
717 edge_iterator ei;
718
719 FOR_EACH_EDGE (e, ei, bb->succs)for ((ei) = ei_start_1 (&((bb->succs))); ei_cond ((ei)
, &(e)); ei_next (&(ei)))
720 if ((e->flags & (EDGE_ABNORMAL | EDGE_EH)) == EDGE_ABNORMAL)
721 {
722 gimple_stmt_iterator gsi
723 = gsi_start_nondebug_after_labels_bb (e->dest);
724 gimple *g = gsi_stmt (gsi);
725 if (g && gimple_call_internal_p (g, IFN_ABNORMAL_DISPATCHER))
726 return e->dest;
727 }
728 return NULLnullptr;
729}
730
731/* Helper function for make_edges. Create a basic block with
732 with ABNORMAL_DISPATCHER internal call in it if needed, and
733 create abnormal edges from BBS to it and from it to FOR_BB
734 if COMPUTED_GOTO is false, otherwise factor the computed gotos. */
735
736static void
737handle_abnormal_edges (basic_block *dispatcher_bbs, basic_block for_bb,
738 auto_vec<basic_block> *bbs, bool computed_goto)
739{
740 basic_block *dispatcher = dispatcher_bbs + (computed_goto ? 1 : 0);
741 unsigned int idx = 0;
742 basic_block bb;
743 bool inner = false;
744
745 if (!bb_to_omp_idx.is_empty ())
746 {
747 dispatcher = dispatcher_bbs + 2 * bb_to_omp_idx[for_bb->index];
748 if (bb_to_omp_idx[for_bb->index] != 0)
749 inner = true;
750 }
751
752 /* If the dispatcher has been created already, then there are basic
753 blocks with abnormal edges to it, so just make a new edge to
754 for_bb. */
755 if (*dispatcher == NULLnullptr)
756 {
757 /* Check if there are any basic blocks that need to have
758 abnormal edges to this dispatcher. If there are none, return
759 early. */
760 if (bb_to_omp_idx.is_empty ())
761 {
762 if (bbs->is_empty ())
763 return;
764 }
765 else
766 {
767 FOR_EACH_VEC_ELT (*bbs, idx, bb)for (idx = 0; (*bbs).iterate ((idx), &(bb)); ++(idx))
768 if (bb_to_omp_idx[bb->index] == bb_to_omp_idx[for_bb->index])
769 break;
770 if (bb == NULLnullptr)
771 return;
772 }
773
774 /* Create the dispatcher bb. */
775 *dispatcher = create_basic_block (NULLnullptr, for_bb);
776 if (computed_goto)
777 {
778 /* Factor computed gotos into a common computed goto site. Also
779 record the location of that site so that we can un-factor the
780 gotos after we have converted back to normal form. */
781 gimple_stmt_iterator gsi = gsi_start_bb (*dispatcher);
782
783 /* Create the destination of the factored goto. Each original
784 computed goto will put its desired destination into this
785 variable and jump to the label we create immediately below. */
786 tree var = create_tmp_var (ptr_type_nodeglobal_trees[TI_PTR_TYPE], "gotovar");
787
788 /* Build a label for the new block which will contain the
789 factored computed goto. */
790 tree factored_label_decl
791 = create_artificial_label (UNKNOWN_LOCATION((location_t) 0));
792 gimple *factored_computed_goto_label
793 = gimple_build_label (factored_label_decl);
794 gsi_insert_after (&gsi, factored_computed_goto_label, GSI_NEW_STMT);
795
796 /* Build our new computed goto. */
797 gimple *factored_computed_goto = gimple_build_goto (var);
798 gsi_insert_after (&gsi, factored_computed_goto, GSI_NEW_STMT);
799
800 FOR_EACH_VEC_ELT (*bbs, idx, bb)for (idx = 0; (*bbs).iterate ((idx), &(bb)); ++(idx))
801 {
802 if (!bb_to_omp_idx.is_empty ()
803 && bb_to_omp_idx[bb->index] != bb_to_omp_idx[for_bb->index])
804 continue;
805
806 gsi = gsi_last_bb (bb);
807 gimple *last = gsi_stmt (gsi);
808
809 gcc_assert (computed_goto_p (last))((void)(!(computed_goto_p (last)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 809, __FUNCTION__), 0 : 0))
;
810
811 /* Copy the original computed goto's destination into VAR. */
812 gimple *assignment
813 = gimple_build_assign (var, gimple_goto_dest (last));
814 gsi_insert_before (&gsi, assignment, GSI_SAME_STMT);
815
816 edge e = make_edge (bb, *dispatcher, EDGE_FALLTHRU);
817 e->goto_locus = gimple_location (last);
818 gsi_remove (&gsi, true);
819 }
820 }
821 else
822 {
823 tree arg = inner ? boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE] : boolean_false_nodeglobal_trees[TI_BOOLEAN_FALSE];
824 gcall *g = gimple_build_call_internal (IFN_ABNORMAL_DISPATCHER,
825 1, arg);
826 gimple_call_set_ctrl_altering (g, true);
827 gimple_stmt_iterator gsi = gsi_after_labels (*dispatcher);
828 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
829
830 /* Create predecessor edges of the dispatcher. */
831 FOR_EACH_VEC_ELT (*bbs, idx, bb)for (idx = 0; (*bbs).iterate ((idx), &(bb)); ++(idx))
832 {
833 if (!bb_to_omp_idx.is_empty ()
834 && bb_to_omp_idx[bb->index] != bb_to_omp_idx[for_bb->index])
835 continue;
836 make_edge (bb, *dispatcher, EDGE_ABNORMAL);
837 }
838 }
839 }
840
841 make_edge (*dispatcher, for_bb, EDGE_ABNORMAL);
842}
843
844/* Creates outgoing edges for BB. Returns 1 when it ends with an
845 computed goto, returns 2 when it ends with a statement that
846 might return to this function via an nonlocal goto, otherwise
847 return 0. Updates *PCUR_REGION with the OMP region this BB is in. */
848
849static int
850make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index)
851{
852 gimple *last = last_stmt (bb);
853 bool fallthru = false;
854 int ret = 0;
855
856 if (!last)
857 return ret;
858
859 switch (gimple_code (last))
860 {
861 case GIMPLE_GOTO:
862 if (make_goto_expr_edges (bb))
863 ret = 1;
864 fallthru = false;
865 break;
866 case GIMPLE_RETURN:
867 {
868 edge e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun)(((cfun + 0))->cfg->x_exit_block_ptr), 0);
869 e->goto_locus = gimple_location (last);
870 fallthru = false;
871 }
872 break;
873 case GIMPLE_COND:
874 make_cond_expr_edges (bb);
875 fallthru = false;
876 break;
877 case GIMPLE_SWITCH:
878 make_gimple_switch_edges (as_a <gswitch *> (last), bb);
879 fallthru = false;
880 break;
881 case GIMPLE_RESX:
882 make_eh_edges (last);
883 fallthru = false;
884 break;
885 case GIMPLE_EH_DISPATCH:
886 fallthru = make_eh_dispatch_edges (as_a <geh_dispatch *> (last));
887 break;
888
889 case GIMPLE_CALL:
890 /* If this function receives a nonlocal goto, then we need to
891 make edges from this call site to all the nonlocal goto
892 handlers. */
893 if (stmt_can_make_abnormal_goto (last))
894 ret = 2;
895
896 /* If this statement has reachable exception handlers, then
897 create abnormal edges to them. */
898 make_eh_edges (last);
899
900 /* BUILTIN_RETURN is really a return statement. */
901 if (gimple_call_builtin_p (last, BUILT_IN_RETURN))
902 {
903 make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun)(((cfun + 0))->cfg->x_exit_block_ptr), 0);
904 fallthru = false;
905 }
906 /* Some calls are known not to return. */
907 else
908 fallthru = !gimple_call_noreturn_p (last);
909 break;
910
911 case GIMPLE_ASSIGN:
912 /* A GIMPLE_ASSIGN may throw internally and thus be considered
913 control-altering. */
914 if (is_ctrl_altering_stmt (last))
915 make_eh_edges (last);
916 fallthru = true;
917 break;
918
919 case GIMPLE_ASM:
920 make_gimple_asm_edges (bb);
921 fallthru = true;
922 break;
923
924 CASE_GIMPLE_OMPcase GIMPLE_OMP_PARALLEL: case GIMPLE_OMP_TASK: case GIMPLE_OMP_FOR
: case GIMPLE_OMP_SECTIONS: case GIMPLE_OMP_SECTIONS_SWITCH: case
GIMPLE_OMP_SINGLE: case GIMPLE_OMP_TARGET: case GIMPLE_OMP_TEAMS
: case GIMPLE_OMP_SCOPE: case GIMPLE_OMP_SECTION: case GIMPLE_OMP_MASTER
: case GIMPLE_OMP_MASKED: case GIMPLE_OMP_TASKGROUP: case GIMPLE_OMP_ORDERED
: case GIMPLE_OMP_CRITICAL: case GIMPLE_OMP_SCAN: case GIMPLE_OMP_RETURN
: case GIMPLE_OMP_ATOMIC_LOAD: case GIMPLE_OMP_ATOMIC_STORE: case
GIMPLE_OMP_CONTINUE
:
925 fallthru = omp_make_gimple_edges (bb, pcur_region, pomp_index);
926 break;
927
928 case GIMPLE_TRANSACTION:
929 {
930 gtransaction *txn = as_a <gtransaction *> (last);
931 tree label1 = gimple_transaction_label_norm (txn);
932 tree label2 = gimple_transaction_label_uninst (txn);
933
934 if (label1)
935 make_edge (bb, label_to_block (cfun(cfun + 0), label1), EDGE_FALLTHRU);
936 if (label2)
937 make_edge (bb, label_to_block (cfun(cfun + 0), label2),
938 EDGE_TM_UNINSTRUMENTED | (label1 ? 0 : EDGE_FALLTHRU));
939
940 tree label3 = gimple_transaction_label_over (txn);
941 if (gimple_transaction_subcode (txn)
942 & (GTMA_HAVE_ABORT(1u << 2) | GTMA_IS_OUTER(1u << 0)))
943 make_edge (bb, label_to_block (cfun(cfun + 0), label3), EDGE_TM_ABORT);
944
945 fallthru = false;
946 }
947 break;
948
949 default:
950 gcc_assert (!stmt_ends_bb_p (last))((void)(!(!stmt_ends_bb_p (last)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 950, __FUNCTION__), 0 : 0))
;
951 fallthru = true;
952 break;
953 }
954
955 if (fallthru)
956 make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
957
958 return ret;
959}
960
961/* Join all the blocks in the flowgraph. */
962
963static void
964make_edges (void)
965{
966 basic_block bb;
967 struct omp_region *cur_region = NULLnullptr;
968 auto_vec<basic_block> ab_edge_goto;
969 auto_vec<basic_block> ab_edge_call;
970 int cur_omp_region_idx = 0;
971
972 /* Create an edge from entry to the first block with executable
973 statements in it. */
974 make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)(((cfun + 0))->cfg->x_entry_block_ptr),
975 BASIC_BLOCK_FOR_FN (cfun, NUM_FIXED_BLOCKS)((*(((cfun + 0))->cfg->x_basic_block_info))[((2))]),
976 EDGE_FALLTHRU);
977
978 /* Traverse the basic block array placing edges. */
979 FOR_EACH_BB_FN (bb, cfun)for (bb = ((cfun + 0))->cfg->x_entry_block_ptr->next_bb
; bb != ((cfun + 0))->cfg->x_exit_block_ptr; bb = bb->
next_bb)
980 {
981 int mer;
982
983 if (!bb_to_omp_idx.is_empty ())
984 bb_to_omp_idx[bb->index] = cur_omp_region_idx;
985
986 mer = make_edges_bb (bb, &cur_region, &cur_omp_region_idx);
987 if (mer == 1)
988 ab_edge_goto.safe_push (bb);
989 else if (mer == 2)
990 ab_edge_call.safe_push (bb);
991
992 if (cur_region && bb_to_omp_idx.is_empty ())
993 bb_to_omp_idx.safe_grow_cleared (n_basic_blocks_for_fn (cfun)(((cfun + 0))->cfg->x_n_basic_blocks), true);
994 }
995
996 /* Computed gotos are hell to deal with, especially if there are
997 lots of them with a large number of destinations. So we factor
998 them to a common computed goto location before we build the
999 edge list. After we convert back to normal form, we will un-factor
1000 the computed gotos since factoring introduces an unwanted jump.
1001 For non-local gotos and abnormal edges from calls to calls that return
1002 twice or forced labels, factor the abnormal edges too, by having all
1003 abnormal edges from the calls go to a common artificial basic block
1004 with ABNORMAL_DISPATCHER internal call and abnormal edges from that
1005 basic block to all forced labels and calls returning twice.
1006 We do this per-OpenMP structured block, because those regions
1007 are guaranteed to be single entry single exit by the standard,
1008 so it is not allowed to enter or exit such regions abnormally this way,
1009 thus all computed gotos, non-local gotos and setjmp/longjmp calls
1010 must not transfer control across SESE region boundaries. */
1011 if (!ab_edge_goto.is_empty () || !ab_edge_call.is_empty ())
1012 {
1013 gimple_stmt_iterator gsi;
1014 basic_block dispatcher_bb_array[2] = { NULLnullptr, NULLnullptr };
1015 basic_block *dispatcher_bbs = dispatcher_bb_array;
1016 int count = n_basic_blocks_for_fn (cfun)(((cfun + 0))->cfg->x_n_basic_blocks);
1017
1018 if (!bb_to_omp_idx.is_empty ())
1019 dispatcher_bbs = XCNEWVEC (basic_block, 2 * count)((basic_block *) xcalloc ((2 * count), sizeof (basic_block)));
1020
1021 FOR_EACH_BB_FN (bb, cfun)for (bb = ((cfun + 0))->cfg->x_entry_block_ptr->next_bb
; bb != ((cfun + 0))->cfg->x_exit_block_ptr; bb = bb->
next_bb)
1022 {
1023 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1024 {
1025 glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (gsi));
1026 tree target;
1027
1028 if (!label_stmt)
1029 break;
1030
1031 target = gimple_label_label (label_stmt);
1032
1033 /* Make an edge to every label block that has been marked as a
1034 potential target for a computed goto or a non-local goto. */
1035 if (FORCED_LABEL (target)((tree_check ((target), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1035, __FUNCTION__, (LABEL_DECL)))->base.side_effects_flag
)
)
1036 handle_abnormal_edges (dispatcher_bbs, bb, &ab_edge_goto,
1037 true);
1038 if (DECL_NONLOCAL (target)((contains_struct_check ((target), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1038, __FUNCTION__))->decl_common.nonlocal_flag)
)
1039 {
1040 handle_abnormal_edges (dispatcher_bbs, bb, &ab_edge_call,
1041 false);
1042 break;
1043 }
1044 }
1045
1046 if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
1047 gsi_next_nondebug (&gsi);
1048 if (!gsi_end_p (gsi))
1049 {
1050 /* Make an edge to every setjmp-like call. */
1051 gimple *call_stmt = gsi_stmt (gsi);
1052 if (is_gimple_call (call_stmt)
1053 && ((gimple_call_flags (call_stmt) & ECF_RETURNS_TWICE(1 << 7))
1054 || gimple_call_builtin_p (call_stmt,
1055 BUILT_IN_SETJMP_RECEIVER)))
1056 handle_abnormal_edges (dispatcher_bbs, bb, &ab_edge_call,
1057 false);
1058 }
1059 }
1060
1061 if (!bb_to_omp_idx.is_empty ())
1062 XDELETE (dispatcher_bbs)free ((void*) (dispatcher_bbs));
1063 }
1064
1065 omp_free_regions ();
1066}
1067
1068/* Add SEQ after GSI. Start new bb after GSI, and created further bbs as
1069 needed. Returns true if new bbs were created.
1070 Note: This is transitional code, and should not be used for new code. We
1071 should be able to get rid of this by rewriting all target va-arg
1072 gimplification hooks to use an interface gimple_build_cond_value as described
1073 in https://gcc.gnu.org/ml/gcc-patches/2015-02/msg01194.html. */
1074
1075bool
1076gimple_find_sub_bbs (gimple_seq seq, gimple_stmt_iterator *gsi)
1077{
1078 gimple *stmt = gsi_stmt (*gsi);
1079 basic_block bb = gimple_bb (stmt);
1080 basic_block lastbb, afterbb;
1081 int old_num_bbs = n_basic_blocks_for_fn (cfun)(((cfun + 0))->cfg->x_n_basic_blocks);
1082 edge e;
1083 lastbb = make_blocks_1 (seq, bb);
1084 if (old_num_bbs == n_basic_blocks_for_fn (cfun)(((cfun + 0))->cfg->x_n_basic_blocks))
1085 return false;
1086 e = split_block (bb, stmt);
1087 /* Move e->dest to come after the new basic blocks. */
1088 afterbb = e->dest;
1089 unlink_block (afterbb);
1090 link_block (afterbb, lastbb);
1091 redirect_edge_succ (e, bb->next_bb);
1092 bb = bb->next_bb;
1093 while (bb != afterbb)
1094 {
1095 struct omp_region *cur_region = NULLnullptr;
1096 profile_count cnt = profile_count::zero ();
1097 bool all = true;
1098
1099 int cur_omp_region_idx = 0;
1100 int mer = make_edges_bb (bb, &cur_region, &cur_omp_region_idx);
1101 gcc_assert (!mer && !cur_region)((void)(!(!mer && !cur_region) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1101, __FUNCTION__), 0 : 0))
;
1102 add_bb_to_loop (bb, afterbb->loop_father);
1103
1104 edge e;
1105 edge_iterator ei;
1106 FOR_EACH_EDGE (e, ei, bb->preds)for ((ei) = ei_start_1 (&((bb->preds))); ei_cond ((ei)
, &(e)); ei_next (&(ei)))
1107 {
1108 if (e->count ().initialized_p ())
1109 cnt += e->count ();
1110 else
1111 all = false;
1112 }
1113 tree_guess_outgoing_edge_probabilities (bb);
1114 if (all || profile_status_for_fn (cfun)(((cfun + 0))->cfg->x_profile_status) == PROFILE_READ)
1115 bb->count = cnt;
1116
1117 bb = bb->next_bb;
1118 }
1119 return true;
1120}
1121
1122/* Find the next available discriminator value for LOCUS. The
1123 discriminator distinguishes among several basic blocks that
1124 share a common locus, allowing for more accurate sample-based
1125 profiling. */
1126
1127static int
1128next_discriminator_for_locus (int line)
1129{
1130 struct locus_discrim_map item;
1131 struct locus_discrim_map **slot;
1132
1133 item.location_line = line;
1134 item.discriminator = 0;
1135 slot = discriminator_per_locus->find_slot_with_hash (&item, line, INSERT);
1136 gcc_assert (slot)((void)(!(slot) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1136, __FUNCTION__), 0 : 0))
;
1137 if (*slot == HTAB_EMPTY_ENTRY((void *) 0))
1138 {
1139 *slot = XNEW (struct locus_discrim_map)((struct locus_discrim_map *) xmalloc (sizeof (struct locus_discrim_map
)))
;
1140 gcc_assert (*slot)((void)(!(*slot) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1140, __FUNCTION__), 0 : 0))
;
1141 (*slot)->location_line = line;
1142 (*slot)->discriminator = 0;
1143 }
1144 (*slot)->discriminator++;
1145 return (*slot)->discriminator;
1146}
1147
1148/* Return TRUE if LOCUS1 and LOCUS2 refer to the same source line. */
1149
1150static bool
1151same_line_p (location_t locus1, expanded_location *from, location_t locus2)
1152{
1153 expanded_location to;
1154
1155 if (locus1 == locus2)
1156 return true;
1157
1158 to = expand_location (locus2);
1159
1160 if (from->line != to.line)
1161 return false;
1162 if (from->file == to.file)
1163 return true;
1164 return (from->file != NULLnullptr
1165 && to.file != NULLnullptr
1166 && filename_cmp (from->file, to.file) == 0);
1167}
1168
1169/* Assign a unique discriminator value to all statements in block bb that
1170 have the same line number as locus. */
1171
1172static void
1173assign_discriminator (location_t locus, basic_block bb)
1174{
1175 gimple_stmt_iterator gsi;
1176 int discriminator;
1177
1178 if (locus == UNKNOWN_LOCATION((location_t) 0))
1179 return;
1180
1181 expanded_location locus_e = expand_location (locus);
1182
1183 discriminator = next_discriminator_for_locus (locus_e.line);
1184
1185 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1186 {
1187 gimple *stmt = gsi_stmt (gsi);
1188 location_t stmt_locus = gimple_location (stmt);
1189 if (same_line_p (locus, &locus_e, stmt_locus))
1190 gimple_set_location (stmt,
1191 location_with_discriminator (stmt_locus, discriminator));
1192 }
1193}
1194
1195/* Assign discriminators to statement locations. */
1196
1197static void
1198assign_discriminators (void)
1199{
1200 basic_block bb;
1201
1202 FOR_EACH_BB_FN (bb, cfun)for (bb = ((cfun + 0))->cfg->x_entry_block_ptr->next_bb
; bb != ((cfun + 0))->cfg->x_exit_block_ptr; bb = bb->
next_bb)
1203 {
1204 edge e;
1205 edge_iterator ei;
1206 gimple_stmt_iterator gsi;
1207 location_t curr_locus = UNKNOWN_LOCATION((location_t) 0);
1208 expanded_location curr_locus_e = {};
1209 int curr_discr = 0;
1210
1211 /* Traverse the basic block, if two function calls within a basic block
1212 are mapped to the same line, assign a new discriminator because a call
1213 stmt could be a split point of a basic block. */
1214 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1215 {
1216 gimple *stmt = gsi_stmt (gsi);
1217
1218 if (curr_locus == UNKNOWN_LOCATION((location_t) 0))
1219 {
1220 curr_locus = gimple_location (stmt);
1221 curr_locus_e = expand_location (curr_locus);
1222 }
1223 else if (!same_line_p (curr_locus, &curr_locus_e, gimple_location (stmt)))
1224 {
1225 curr_locus = gimple_location (stmt);
1226 curr_locus_e = expand_location (curr_locus);
1227 curr_discr = 0;
1228 }
1229 else if (curr_discr != 0)
1230 {
1231 location_t loc = gimple_location (stmt);
1232 location_t dloc = location_with_discriminator (loc, curr_discr);
1233 gimple_set_location (stmt, dloc);
1234 }
1235 /* Allocate a new discriminator for CALL stmt. */
1236 if (gimple_code (stmt) == GIMPLE_CALL)
1237 curr_discr = next_discriminator_for_locus (curr_locus);
1238 }
1239
1240 gimple *last = last_stmt (bb);
1241 location_t locus = last ? gimple_location (last) : UNKNOWN_LOCATION((location_t) 0);
1242 if (locus == UNKNOWN_LOCATION((location_t) 0))
1243 continue;
1244
1245 expanded_location locus_e = expand_location (locus);
1246
1247 FOR_EACH_EDGE (e, ei, bb->succs)for ((ei) = ei_start_1 (&((bb->succs))); ei_cond ((ei)
, &(e)); ei_next (&(ei)))
1248 {
1249 gimple *first = first_non_label_stmt (e->dest);
1250 gimple *last = last_stmt (e->dest);
1251
1252 gimple *stmt_on_same_line = NULLnullptr;
1253 if (first && same_line_p (locus, &locus_e,
1254 gimple_location (first)))
1255 stmt_on_same_line = first;
1256 else if (last && same_line_p (locus, &locus_e,
1257 gimple_location (last)))
1258 stmt_on_same_line = last;
1259
1260 if (stmt_on_same_line)
1261 {
1262 if (has_discriminator (gimple_location (stmt_on_same_line))
1263 && !has_discriminator (locus))
1264 assign_discriminator (locus, bb);
1265 else
1266 assign_discriminator (locus, e->dest);
1267 }
1268 }
1269 }
1270}
1271
1272/* Create the edges for a GIMPLE_COND starting at block BB. */
1273
1274static void
1275make_cond_expr_edges (basic_block bb)
1276{
1277 gcond *entry = as_a <gcond *> (last_stmt (bb));
1278 gimple *then_stmt, *else_stmt;
1279 basic_block then_bb, else_bb;
1280 tree then_label, else_label;
1281 edge e;
1282
1283 gcc_assert (entry)((void)(!(entry) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1283, __FUNCTION__), 0 : 0))
;
1284 gcc_assert (gimple_code (entry) == GIMPLE_COND)((void)(!(gimple_code (entry) == GIMPLE_COND) ? fancy_abort (
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1284, __FUNCTION__), 0 : 0))
;
1285
1286 /* Entry basic blocks for each component. */
1287 then_label = gimple_cond_true_label (entry);
1288 else_label = gimple_cond_false_label (entry);
1289 then_bb = label_to_block (cfun(cfun + 0), then_label);
1290 else_bb = label_to_block (cfun(cfun + 0), else_label);
1291 then_stmt = first_stmt (then_bb);
1292 else_stmt = first_stmt (else_bb);
1293
1294 e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1295 e->goto_locus = gimple_location (then_stmt);
1296 e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1297 if (e)
1298 e->goto_locus = gimple_location (else_stmt);
1299
1300 /* We do not need the labels anymore. */
1301 gimple_cond_set_true_label (entry, NULL_TREE(tree) nullptr);
1302 gimple_cond_set_false_label (entry, NULL_TREE(tree) nullptr);
1303}
1304
1305
1306/* Called for each element in the hash table (P) as we delete the
1307 edge to cases hash table.
1308
1309 Clear all the CASE_CHAINs to prevent problems with copying of
1310 SWITCH_EXPRs and structure sharing rules, then free the hash table
1311 element. */
1312
1313bool
1314edge_to_cases_cleanup (edge const &, tree const &value, void *)
1315{
1316 tree t, next;
1317
1318 for (t = value; t; t = next)
1319 {
1320 next = CASE_CHAIN (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1320, __FUNCTION__, (CASE_LABEL_EXPR)))), (3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1320, __FUNCTION__)))))
;
1321 CASE_CHAIN (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1321, __FUNCTION__, (CASE_LABEL_EXPR)))), (3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1321, __FUNCTION__)))))
= NULLnullptr;
1322 }
1323
1324 return true;
1325}
1326
1327/* Start recording information mapping edges to case labels. */
1328
1329void
1330start_recording_case_labels (void)
1331{
1332 gcc_assert (edge_to_cases == NULL)((void)(!(edge_to_cases == nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1332, __FUNCTION__), 0 : 0))
;
1333 edge_to_cases = new hash_map<edge, tree>;
1334 touched_switch_bbs = BITMAP_ALLOCbitmap_alloc (NULLnullptr);
1335}
1336
1337/* Return nonzero if we are recording information for case labels. */
1338
1339static bool
1340recording_case_labels_p (void)
1341{
1342 return (edge_to_cases != NULLnullptr);
1343}
1344
1345/* Stop recording information mapping edges to case labels and
1346 remove any information we have recorded. */
1347void
1348end_recording_case_labels (void)
1349{
1350 bitmap_iterator bi;
1351 unsigned i;
1352 edge_to_cases->traverse<void *, edge_to_cases_cleanup> (NULLnullptr);
1353 delete edge_to_cases;
1354 edge_to_cases = NULLnullptr;
1355 EXECUTE_IF_SET_IN_BITMAP (touched_switch_bbs, 0, i, bi)for (bmp_iter_set_init (&(bi), (touched_switch_bbs), (0),
&(i)); bmp_iter_set (&(bi), &(i)); bmp_iter_next
(&(bi), &(i)))
1356 {
1357 basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i)((*(((cfun + 0))->cfg->x_basic_block_info))[(i)]);
1358 if (bb)
1359 {
1360 gimple *stmt = last_stmt (bb);
1361 if (stmt && gimple_code (stmt) == GIMPLE_SWITCH)
1362 group_case_labels_stmt (as_a <gswitch *> (stmt));
1363 }
1364 }
1365 BITMAP_FREE (touched_switch_bbs)((void) (bitmap_obstack_free ((bitmap) touched_switch_bbs), (
touched_switch_bbs) = (bitmap) nullptr))
;
1366}
1367
1368/* If we are inside a {start,end}_recording_cases block, then return
1369 a chain of CASE_LABEL_EXPRs from T which reference E.
1370
1371 Otherwise return NULL. */
1372
1373tree
1374get_cases_for_edge (edge e, gswitch *t)
1375{
1376 tree *slot;
1377 size_t i, n;
1378
1379 /* If we are not recording cases, then we do not have CASE_LABEL_EXPR
1380 chains available. Return NULL so the caller can detect this case. */
1381 if (!recording_case_labels_p ())
1382 return NULLnullptr;
1383
1384 slot = edge_to_cases->get (e);
1385 if (slot)
1386 return *slot;
1387
1388 /* If we did not find E in the hash table, then this must be the first
1389 time we have been queried for information about E & T. Add all the
1390 elements from T to the hash table then perform the query again. */
1391
1392 n = gimple_switch_num_labels (t);
1393 for (i = 0; i < n; i++)
1394 {
1395 tree elt = gimple_switch_label (t, i);
1396 tree lab = CASE_LABEL (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1396, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1396, __FUNCTION__)))))
;
1397 basic_block label_bb = label_to_block (cfun(cfun + 0), lab);
1398 edge this_edge = find_edge (e->src, label_bb);
1399
1400 /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create
1401 a new chain. */
1402 tree &s = edge_to_cases->get_or_insert (this_edge);
1403 CASE_CHAIN (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1403, __FUNCTION__, (CASE_LABEL_EXPR)))), (3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1403, __FUNCTION__)))))
= s;
1404 s = elt;
1405 }
1406
1407 return *edge_to_cases->get (e);
1408}
1409
1410/* Create the edges for a GIMPLE_SWITCH starting at block BB. */
1411
1412static void
1413make_gimple_switch_edges (gswitch *entry, basic_block bb)
1414{
1415 size_t i, n;
1416
1417 n = gimple_switch_num_labels (entry);
1418
1419 for (i = 0; i < n; ++i)
1420 {
1421 basic_block label_bb = gimple_switch_label_bb (cfun(cfun + 0), entry, i);
1422 make_edge (bb, label_bb, 0);
1423 }
1424}
1425
1426
1427/* Return the basic block holding label DEST. */
1428
1429basic_block
1430label_to_block (struct function *ifun, tree dest)
1431{
1432 int uid = LABEL_DECL_UID (dest)((tree_check ((dest), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1432, __FUNCTION__, (LABEL_DECL)))->label_decl.label_decl_uid
)
;
1433
1434 /* We would die hard when faced by an undefined label. Emit a label to
1435 the very first basic block. This will hopefully make even the dataflow
1436 and undefined variable warnings quite right. */
1437 if (seen_error () && uid < 0)
1438 {
1439 gimple_stmt_iterator gsi =
1440 gsi_start_bb (BASIC_BLOCK_FOR_FN (cfun, NUM_FIXED_BLOCKS)((*(((cfun + 0))->cfg->x_basic_block_info))[((2))]));
1441 gimple *stmt;
1442
1443 stmt = gimple_build_label (dest);
1444 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
1445 uid = LABEL_DECL_UID (dest)((tree_check ((dest), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1445, __FUNCTION__, (LABEL_DECL)))->label_decl.label_decl_uid
)
;
1446 }
1447 if (vec_safe_length (ifun->cfg->x_label_to_block_map) <= (unsigned int) uid)
1448 return NULLnullptr;
1449 return (*ifun->cfg->x_label_to_block_map)[uid];
1450}
1451
1452/* Create edges for a goto statement at block BB. Returns true
1453 if abnormal edges should be created. */
1454
1455static bool
1456make_goto_expr_edges (basic_block bb)
1457{
1458 gimple_stmt_iterator last = gsi_last_bb (bb);
1459 gimple *goto_t = gsi_stmt (last);
1460
1461 /* A simple GOTO creates normal edges. */
1462 if (simple_goto_p (goto_t))
1463 {
1464 tree dest = gimple_goto_dest (goto_t);
1465 basic_block label_bb = label_to_block (cfun(cfun + 0), dest);
1466 edge e = make_edge (bb, label_bb, EDGE_FALLTHRU);
1467 e->goto_locus = gimple_location (goto_t);
1468 gsi_remove (&last, true);
1469 return false;
1470 }
1471
1472 /* A computed GOTO creates abnormal edges. */
1473 return true;
1474}
1475
1476/* Create edges for an asm statement with labels at block BB. */
1477
1478static void
1479make_gimple_asm_edges (basic_block bb)
1480{
1481 gasm *stmt = as_a <gasm *> (last_stmt (bb));
1482 int i, n = gimple_asm_nlabels (stmt);
1483
1484 for (i = 0; i < n; ++i)
1485 {
1486 tree label = TREE_VALUE (gimple_asm_label_op (stmt, i))((tree_check ((gimple_asm_label_op (stmt, i)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1486, __FUNCTION__, (TREE_LIST)))->list.value)
;
1487 basic_block label_bb = label_to_block (cfun(cfun + 0), label);
1488 make_edge (bb, label_bb, 0);
1489 }
1490}
1491
1492/*---------------------------------------------------------------------------
1493 Flowgraph analysis
1494---------------------------------------------------------------------------*/
1495
1496/* Cleanup useless labels in basic blocks. This is something we wish
1497 to do early because it allows us to group case labels before creating
1498 the edges for the CFG, and it speeds up block statement iterators in
1499 all passes later on.
1500 We rerun this pass after CFG is created, to get rid of the labels that
1501 are no longer referenced. After then we do not run it any more, since
1502 (almost) no new labels should be created. */
1503
1504/* A map from basic block index to the leading label of that block. */
1505struct label_record
1506{
1507 /* The label. */
1508 tree label;
1509
1510 /* True if the label is referenced from somewhere. */
1511 bool used;
1512};
1513
1514/* Given LABEL return the first label in the same basic block. */
1515
1516static tree
1517main_block_label (tree label, label_record *label_for_bb)
1518{
1519 basic_block bb = label_to_block (cfun(cfun + 0), label);
1520 tree main_label = label_for_bb[bb->index].label;
1521
1522 /* label_to_block possibly inserted undefined label into the chain. */
1523 if (!main_label)
1524 {
1525 label_for_bb[bb->index].label = label;
1526 main_label = label;
1527 }
1528
1529 label_for_bb[bb->index].used = true;
1530 return main_label;
1531}
1532
1533/* Clean up redundant labels within the exception tree. */
1534
1535static void
1536cleanup_dead_labels_eh (label_record *label_for_bb)
1537{
1538 eh_landing_pad lp;
1539 eh_region r;
1540 tree lab;
1541 int i;
1542
1543 if (cfun(cfun + 0)->eh == NULLnullptr)
1544 return;
1545
1546 for (i = 1; vec_safe_iterate (cfun(cfun + 0)->eh->lp_array, i, &lp); ++i)
1547 if (lp && lp->post_landing_pad)
1548 {
1549 lab = main_block_label (lp->post_landing_pad, label_for_bb);
1550 if (lab != lp->post_landing_pad)
1551 {
1552 EH_LANDING_PAD_NR (lp->post_landing_pad)((tree_check ((lp->post_landing_pad), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1552, __FUNCTION__, (LABEL_DECL)))->label_decl.eh_landing_pad_nr
)
= 0;
1553 lp->post_landing_pad = lab;
1554 EH_LANDING_PAD_NR (lab)((tree_check ((lab), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1554, __FUNCTION__, (LABEL_DECL)))->label_decl.eh_landing_pad_nr
)
= lp->index;
1555 }
1556 }
1557
1558 FOR_ALL_EH_REGION (r)for ((r) = ((cfun + 0))->eh->region_tree; (r) != nullptr
; (r) = ehr_next (r, nullptr))
1559 switch (r->type)
1560 {
1561 case ERT_CLEANUP:
1562 case ERT_MUST_NOT_THROW:
1563 break;
1564
1565 case ERT_TRY:
1566 {
1567 eh_catch c;
1568 for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
1569 {
1570 lab = c->label;
1571 if (lab)
1572 c->label = main_block_label (lab, label_for_bb);
1573 }
1574 }
1575 break;
1576
1577 case ERT_ALLOWED_EXCEPTIONS:
1578 lab = r->u.allowed.label;
1579 if (lab)
1580 r->u.allowed.label = main_block_label (lab, label_for_bb);
1581 break;
1582 }
1583}
1584
1585
1586/* Cleanup redundant labels. This is a three-step process:
1587 1) Find the leading label for each block.
1588 2) Redirect all references to labels to the leading labels.
1589 3) Cleanup all useless labels. */
1590
1591void
1592cleanup_dead_labels (void)
1593{
1594 basic_block bb;
1595 label_record *label_for_bb = XCNEWVEC (struct label_record,((struct label_record *) xcalloc (((((cfun + 0))->cfg->
x_last_basic_block)), sizeof (struct label_record)))
1596 last_basic_block_for_fn (cfun))((struct label_record *) xcalloc (((((cfun + 0))->cfg->
x_last_basic_block)), sizeof (struct label_record)))
;
1597
1598 /* Find a suitable label for each block. We use the first user-defined
1599 label if there is one, or otherwise just the first label we see. */
1600 FOR_EACH_BB_FN (bb, cfun)for (bb = ((cfun + 0))->cfg->x_entry_block_ptr->next_bb
; bb != ((cfun + 0))->cfg->x_exit_block_ptr; bb = bb->
next_bb)
1601 {
1602 gimple_stmt_iterator i;
1603
1604 for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
1605 {
1606 tree label;
1607 glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (i));
1608
1609 if (!label_stmt)
1610 break;
1611
1612 label = gimple_label_label (label_stmt);
1613
1614 /* If we have not yet seen a label for the current block,
1615 remember this one and see if there are more labels. */
1616 if (!label_for_bb[bb->index].label)
1617 {
1618 label_for_bb[bb->index].label = label;
1619 continue;
1620 }
1621
1622 /* If we did see a label for the current block already, but it
1623 is an artificially created label, replace it if the current
1624 label is a user defined label. */
1625 if (!DECL_ARTIFICIAL (label)((contains_struct_check ((label), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1625, __FUNCTION__))->decl_common.artificial_flag)
1626 && DECL_ARTIFICIAL (label_for_bb[bb->index].label)((contains_struct_check ((label_for_bb[bb->index].label), (
TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1626, __FUNCTION__))->decl_common.artificial_flag)
)
1627 {
1628 label_for_bb[bb->index].label = label;
1629 break;
1630 }
1631 }
1632 }
1633
1634 /* Now redirect all jumps/branches to the selected label.
1635 First do so for each block ending in a control statement. */
1636 FOR_EACH_BB_FN (bb, cfun)for (bb = ((cfun + 0))->cfg->x_entry_block_ptr->next_bb
; bb != ((cfun + 0))->cfg->x_exit_block_ptr; bb = bb->
next_bb)
1637 {
1638 gimple *stmt = last_stmt (bb);
1639 tree label, new_label;
1640
1641 if (!stmt)
1642 continue;
1643
1644 switch (gimple_code (stmt))
1645 {
1646 case GIMPLE_COND:
1647 {
1648 gcond *cond_stmt = as_a <gcond *> (stmt);
1649 label = gimple_cond_true_label (cond_stmt);
1650 if (label)
1651 {
1652 new_label = main_block_label (label, label_for_bb);
1653 if (new_label != label)
1654 gimple_cond_set_true_label (cond_stmt, new_label);
1655 }
1656
1657 label = gimple_cond_false_label (cond_stmt);
1658 if (label)
1659 {
1660 new_label = main_block_label (label, label_for_bb);
1661 if (new_label != label)
1662 gimple_cond_set_false_label (cond_stmt, new_label);
1663 }
1664 }
1665 break;
1666
1667 case GIMPLE_SWITCH:
1668 {
1669 gswitch *switch_stmt = as_a <gswitch *> (stmt);
1670 size_t i, n = gimple_switch_num_labels (switch_stmt);
1671
1672 /* Replace all destination labels. */
1673 for (i = 0; i < n; ++i)
1674 {
1675 tree case_label = gimple_switch_label (switch_stmt, i);
1676 label = CASE_LABEL (case_label)(*((const_cast<tree*> (tree_operand_check (((tree_check
((case_label), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1676, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1676, __FUNCTION__)))))
;
1677 new_label = main_block_label (label, label_for_bb);
1678 if (new_label != label)
1679 CASE_LABEL (case_label)(*((const_cast<tree*> (tree_operand_check (((tree_check
((case_label), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1679, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1679, __FUNCTION__)))))
= new_label;
1680 }
1681 break;
1682 }
1683
1684 case GIMPLE_ASM:
1685 {
1686 gasm *asm_stmt = as_a <gasm *> (stmt);
1687 int i, n = gimple_asm_nlabels (asm_stmt);
1688
1689 for (i = 0; i < n; ++i)
1690 {
1691 tree cons = gimple_asm_label_op (asm_stmt, i);
1692 tree label = main_block_label (TREE_VALUE (cons)((tree_check ((cons), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1692, __FUNCTION__, (TREE_LIST)))->list.value)
, label_for_bb);
1693 TREE_VALUE (cons)((tree_check ((cons), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1693, __FUNCTION__, (TREE_LIST)))->list.value)
= label;
1694 }
1695 break;
1696 }
1697
1698 /* We have to handle gotos until they're removed, and we don't
1699 remove them until after we've created the CFG edges. */
1700 case GIMPLE_GOTO:
1701 if (!computed_goto_p (stmt))
1702 {
1703 ggoto *goto_stmt = as_a <ggoto *> (stmt);
1704 label = gimple_goto_dest (goto_stmt);
1705 new_label = main_block_label (label, label_for_bb);
1706 if (new_label != label)
1707 gimple_goto_set_dest (goto_stmt, new_label);
1708 }
1709 break;
1710
1711 case GIMPLE_TRANSACTION:
1712 {
1713 gtransaction *txn = as_a <gtransaction *> (stmt);
1714
1715 label = gimple_transaction_label_norm (txn);
1716 if (label)
1717 {
1718 new_label = main_block_label (label, label_for_bb);
1719 if (new_label != label)
1720 gimple_transaction_set_label_norm (txn, new_label);
1721 }
1722
1723 label = gimple_transaction_label_uninst (txn);
1724 if (label)
1725 {
1726 new_label = main_block_label (label, label_for_bb);
1727 if (new_label != label)
1728 gimple_transaction_set_label_uninst (txn, new_label);
1729 }
1730
1731 label = gimple_transaction_label_over (txn);
1732 if (label)
1733 {
1734 new_label = main_block_label (label, label_for_bb);
1735 if (new_label != label)
1736 gimple_transaction_set_label_over (txn, new_label);
1737 }
1738 }
1739 break;
1740
1741 default:
1742 break;
1743 }
1744 }
1745
1746 /* Do the same for the exception region tree labels. */
1747 cleanup_dead_labels_eh (label_for_bb);
1748
1749 /* Finally, purge dead labels. All user-defined labels and labels that
1750 can be the target of non-local gotos and labels which have their
1751 address taken are preserved. */
1752 FOR_EACH_BB_FN (bb, cfun)for (bb = ((cfun + 0))->cfg->x_entry_block_ptr->next_bb
; bb != ((cfun + 0))->cfg->x_exit_block_ptr; bb = bb->
next_bb)
1753 {
1754 gimple_stmt_iterator i;
1755 tree label_for_this_bb = label_for_bb[bb->index].label;
1756
1757 if (!label_for_this_bb)
1758 continue;
1759
1760 /* If the main label of the block is unused, we may still remove it. */
1761 if (!label_for_bb[bb->index].used)
1762 label_for_this_bb = NULLnullptr;
1763
1764 for (i = gsi_start_bb (bb); !gsi_end_p (i); )
1765 {
1766 tree label;
1767 glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (i));
1768
1769 if (!label_stmt)
1770 break;
1771
1772 label = gimple_label_label (label_stmt);
1773
1774 if (label == label_for_this_bb
1775 || !DECL_ARTIFICIAL (label)((contains_struct_check ((label), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1775, __FUNCTION__))->decl_common.artificial_flag)
1776 || DECL_NONLOCAL (label)((contains_struct_check ((label), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1776, __FUNCTION__))->decl_common.nonlocal_flag)
1777 || FORCED_LABEL (label)((tree_check ((label), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1777, __FUNCTION__, (LABEL_DECL)))->base.side_effects_flag
)
)
1778 gsi_next (&i);
1779 else
1780 {
1781 gcc_checking_assert (EH_LANDING_PAD_NR (label) == 0)((void)(!(((tree_check ((label), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1781, __FUNCTION__, (LABEL_DECL)))->label_decl.eh_landing_pad_nr
) == 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1781, __FUNCTION__), 0 : 0))
;
1782 gsi_remove (&i, true);
1783 }
1784 }
1785 }
1786
1787 free (label_for_bb);
1788}
1789
1790/* Scan the sorted vector of cases in STMT (a GIMPLE_SWITCH) and combine
1791 the ones jumping to the same label.
1792 Eg. three separate entries 1: 2: 3: become one entry 1..3: */
1793
1794bool
1795group_case_labels_stmt (gswitch *stmt)
1796{
1797 int old_size = gimple_switch_num_labels (stmt);
1798 int i, next_index, new_size;
1799 basic_block default_bb = NULLnullptr;
1800 hash_set<tree> *removed_labels = NULLnullptr;
1801
1802 default_bb = gimple_switch_default_bb (cfun(cfun + 0), stmt);
1803
1804 /* Look for possible opportunities to merge cases. */
1805 new_size = i = 1;
1806 while (i < old_size)
1807 {
1808 tree base_case, base_high;
1809 basic_block base_bb;
1810
1811 base_case = gimple_switch_label (stmt, i);
1812
1813 gcc_assert (base_case)((void)(!(base_case) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1813, __FUNCTION__), 0 : 0))
;
1814 base_bb = label_to_block (cfun(cfun + 0), CASE_LABEL (base_case)(*((const_cast<tree*> (tree_operand_check (((tree_check
((base_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1814, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1814, __FUNCTION__)))))
);
1815
1816 /* Discard cases that have the same destination as the default case or
1817 whose destination blocks have already been removed as unreachable. */
1818 if (base_bb == NULLnullptr
1819 || base_bb == default_bb
1820 || (removed_labels
1821 && removed_labels->contains (CASE_LABEL (base_case)(*((const_cast<tree*> (tree_operand_check (((tree_check
((base_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1821, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1821, __FUNCTION__)))))
)))
1822 {
1823 i++;
1824 continue;
1825 }
1826
1827 base_high = CASE_HIGH (base_case)(*((const_cast<tree*> (tree_operand_check (((tree_check
((base_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1827, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1827, __FUNCTION__)))))
1828 ? CASE_HIGH (base_case)(*((const_cast<tree*> (tree_operand_check (((tree_check
((base_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1828, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1828, __FUNCTION__)))))
1829 : CASE_LOW (base_case)(*((const_cast<tree*> (tree_operand_check (((tree_check
((base_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1829, __FUNCTION__, (CASE_LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1829, __FUNCTION__)))))
;
1830 next_index = i + 1;
1831
1832 /* Try to merge case labels. Break out when we reach the end
1833 of the label vector or when we cannot merge the next case
1834 label with the current one. */
1835 while (next_index < old_size)
1836 {
1837 tree merge_case = gimple_switch_label (stmt, next_index);
1838 basic_block merge_bb = label_to_block (cfun(cfun + 0), CASE_LABEL (merge_case)(*((const_cast<tree*> (tree_operand_check (((tree_check
((merge_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1838, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1838, __FUNCTION__)))))
);
1839 wide_int bhp1 = wi::to_wide (base_high) + 1;
1840
1841 /* Merge the cases if they jump to the same place,
1842 and their ranges are consecutive. */
1843 if (merge_bb == base_bb
1844 && (removed_labels == NULLnullptr
1845 || !removed_labels->contains (CASE_LABEL (merge_case)(*((const_cast<tree*> (tree_operand_check (((tree_check
((merge_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1845, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1845, __FUNCTION__)))))
))
1846 && wi::to_wide (CASE_LOW (merge_case)(*((const_cast<tree*> (tree_operand_check (((tree_check
((merge_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1846, __FUNCTION__, (CASE_LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1846, __FUNCTION__)))))
) == bhp1)
1847 {
1848 base_high
1849 = (CASE_HIGH (merge_case)(*((const_cast<tree*> (tree_operand_check (((tree_check
((merge_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1849, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1849, __FUNCTION__)))))
1850 ? CASE_HIGH (merge_case)(*((const_cast<tree*> (tree_operand_check (((tree_check
((merge_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1850, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1850, __FUNCTION__)))))
: CASE_LOW (merge_case)(*((const_cast<tree*> (tree_operand_check (((tree_check
((merge_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1850, __FUNCTION__, (CASE_LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1850, __FUNCTION__)))))
);
1851 CASE_HIGH (base_case)(*((const_cast<tree*> (tree_operand_check (((tree_check
((base_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1851, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1851, __FUNCTION__)))))
= base_high;
1852 next_index++;
1853 }
1854 else
1855 break;
1856 }
1857
1858 /* Discard cases that have an unreachable destination block. */
1859 if (EDGE_COUNT (base_bb->succs)vec_safe_length (base_bb->succs) == 0
1860 && gimple_seq_unreachable_p (bb_seq (base_bb))
1861 /* Don't optimize this if __builtin_unreachable () is the
1862 implicitly added one by the C++ FE too early, before
1863 -Wreturn-type can be diagnosed. We'll optimize it later
1864 during switchconv pass or any other cfg cleanup. */
1865 && (gimple_in_ssa_p (cfun(cfun + 0))
1866 || (LOCATION_LOCUS (gimple_location (last_stmt (base_bb)))((IS_ADHOC_LOC (gimple_location (last_stmt (base_bb)))) ? get_location_from_adhoc_loc
(line_table, gimple_location (last_stmt (base_bb))) : (gimple_location
(last_stmt (base_bb))))
1867 != BUILTINS_LOCATION((location_t) 1))))
1868 {
1869 edge base_edge = find_edge (gimple_bb (stmt), base_bb);
1870 if (base_edge != NULLnullptr)
1871 {
1872 for (gimple_stmt_iterator gsi = gsi_start_bb (base_bb);
1873 !gsi_end_p (gsi); gsi_next (&gsi))
1874 if (glabel *stmt = dyn_cast <glabel *> (gsi_stmt (gsi)))
1875 {
1876 if (FORCED_LABEL (gimple_label_label (stmt))((tree_check ((gimple_label_label (stmt)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1876, __FUNCTION__, (LABEL_DECL)))->base.side_effects_flag
)
1877 || DECL_NONLOCAL (gimple_label_label (stmt))((contains_struct_check ((gimple_label_label (stmt)), (TS_DECL_COMMON
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1877, __FUNCTION__))->decl_common.nonlocal_flag)
)
1878 {
1879 /* Forced/non-local labels aren't going to be removed,
1880 but they will be moved to some neighbouring basic
1881 block. If some later case label refers to one of
1882 those labels, we should throw that case away rather
1883 than keeping it around and refering to some random
1884 other basic block without an edge to it. */
1885 if (removed_labels == NULLnullptr)
1886 removed_labels = new hash_set<tree>;
1887 removed_labels->add (gimple_label_label (stmt));
1888 }
1889 }
1890 else
1891 break;
1892 remove_edge_and_dominated_blocks (base_edge);
1893 }
1894 i = next_index;
1895 continue;
1896 }
1897
1898 if (new_size < i)
1899 gimple_switch_set_label (stmt, new_size,
1900 gimple_switch_label (stmt, i));
1901 i = next_index;
1902 new_size++;
1903 }
1904
1905 gcc_assert (new_size <= old_size)((void)(!(new_size <= old_size) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1905, __FUNCTION__), 0 : 0))
;
1906
1907 if (new_size < old_size)
1908 gimple_switch_set_num_labels (stmt, new_size);
1909
1910 delete removed_labels;
1911 return new_size < old_size;
1912}
1913
1914/* Look for blocks ending in a multiway branch (a GIMPLE_SWITCH),
1915 and scan the sorted vector of cases. Combine the ones jumping to the
1916 same label. */
1917
1918bool
1919group_case_labels (void)
1920{
1921 basic_block bb;
1922 bool changed = false;
1923
1924 FOR_EACH_BB_FN (bb, cfun)for (bb = ((cfun + 0))->cfg->x_entry_block_ptr->next_bb
; bb != ((cfun + 0))->cfg->x_exit_block_ptr; bb = bb->
next_bb)
1925 {
1926 gimple *stmt = last_stmt (bb);
1927 if (stmt && gimple_code (stmt) == GIMPLE_SWITCH)
1928 changed |= group_case_labels_stmt (as_a <gswitch *> (stmt));
1929 }
1930
1931 return changed;
1932}
1933
1934/* Checks whether we can merge block B into block A. */
1935
1936static bool
1937gimple_can_merge_blocks_p (basic_block a, basic_block b)
1938{
1939 gimple *stmt;
1940
1941 if (!single_succ_p (a))
1942 return false;
1943
1944 if (single_succ_edge (a)->flags & EDGE_COMPLEX(EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_PRESERVE
)
)
1945 return false;
1946
1947 if (single_succ (a) != b)
1948 return false;
1949
1950 if (!single_pred_p (b))
1951 return false;
1952
1953 if (a == ENTRY_BLOCK_PTR_FOR_FN (cfun)(((cfun + 0))->cfg->x_entry_block_ptr)
1954 || b == EXIT_BLOCK_PTR_FOR_FN (cfun)(((cfun + 0))->cfg->x_exit_block_ptr))
1955 return false;
1956
1957 /* If A ends by a statement causing exceptions or something similar, we
1958 cannot merge the blocks. */
1959 stmt = last_stmt (a);
1960 if (stmt && stmt_ends_bb_p (stmt))
1961 return false;
1962
1963 /* Do not allow a block with only a non-local label to be merged. */
1964 if (stmt)
1965 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
1966 if (DECL_NONLOCAL (gimple_label_label (label_stmt))((contains_struct_check ((gimple_label_label (label_stmt)), (
TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1966, __FUNCTION__))->decl_common.nonlocal_flag)
)
1967 return false;
1968
1969 /* Examine the labels at the beginning of B. */
1970 for (gimple_stmt_iterator gsi = gsi_start_bb (b); !gsi_end_p (gsi);
1971 gsi_next (&gsi))
1972 {
1973 tree lab;
1974 glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (gsi));
1975 if (!label_stmt)
1976 break;
1977 lab = gimple_label_label (label_stmt);
1978
1979 /* Do not remove user forced labels or for -O0 any user labels. */
1980 if (!DECL_ARTIFICIAL (lab)((contains_struct_check ((lab), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1980, __FUNCTION__))->decl_common.artificial_flag)
&& (!optimizeglobal_options.x_optimize || FORCED_LABEL (lab)((tree_check ((lab), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 1980, __FUNCTION__, (LABEL_DECL)))->base.side_effects_flag
)
))
1981 return false;
1982 }
1983
1984 /* Protect simple loop latches. We only want to avoid merging
1985 the latch with the loop header or with a block in another
1986 loop in this case. */
1987 if (current_loops((cfun + 0)->x_current_loops)
1988 && b->loop_father->latch == b
1989 && loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES)
1990 && (b->loop_father->header == a
1991 || b->loop_father != a->loop_father))
1992 return false;
1993
1994 /* It must be possible to eliminate all phi nodes in B. If ssa form
1995 is not up-to-date and a name-mapping is registered, we cannot eliminate
1996 any phis. Symbols marked for renaming are never a problem though. */
1997 for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);
1998 gsi_next (&gsi))
1999 {
2000 gphi *phi = gsi.phi ();
2001 /* Technically only new names matter. */
2002 if (name_registered_for_update_p (PHI_RESULT (phi)get_def_from_ptr (gimple_phi_result_ptr (phi))))
2003 return false;
2004 }
2005
2006 /* When not optimizing, don't merge if we'd lose goto_locus. */
2007 if (!optimizeglobal_options.x_optimize
2008 && single_succ_edge (a)->goto_locus != UNKNOWN_LOCATION((location_t) 0))
2009 {
2010 location_t goto_locus = single_succ_edge (a)->goto_locus;
2011 gimple_stmt_iterator prev, next;
2012 prev = gsi_last_nondebug_bb (a);
2013 next = gsi_after_labels (b);
2014 if (!gsi_end_p (next) && is_gimple_debug (gsi_stmt (next)))
2015 gsi_next_nondebug (&next);
2016 if ((gsi_end_p (prev)
2017 || gimple_location (gsi_stmt (prev)) != goto_locus)
2018 && (gsi_end_p (next)
2019 || gimple_location (gsi_stmt (next)) != goto_locus))
2020 return false;
2021 }
2022
2023 return true;
2024}
2025
2026/* Replaces all uses of NAME by VAL. */
2027
2028void
2029replace_uses_by (tree name, tree val)
2030{
2031 imm_use_iterator imm_iter;
2032 use_operand_p use;
2033 gimple *stmt;
2034 edge e;
2035
2036 FOR_EACH_IMM_USE_STMT (stmt, imm_iter, name)for (struct auto_end_imm_use_stmt_traverse auto_end_imm_use_stmt_traverse
((((stmt) = first_imm_use_stmt (&(imm_iter), (name))), &
(imm_iter))); !end_imm_use_stmt_p (&(imm_iter)); (void) (
(stmt) = next_imm_use_stmt (&(imm_iter))))
2037 {
2038 /* Mark the block if we change the last stmt in it. */
2039 if (cfgcleanup_altered_bbs
2040 && stmt_ends_bb_p (stmt))
2041 bitmap_set_bit (cfgcleanup_altered_bbs, gimple_bb (stmt)->index);
2042
2043 FOR_EACH_IMM_USE_ON_STMT (use, imm_iter)for ((use) = first_imm_use_on_stmt (&(imm_iter)); !end_imm_use_on_stmt_p
(&(imm_iter)); (void) ((use) = next_imm_use_on_stmt (&
(imm_iter))))
2044 {
2045 replace_exp (use, val);
2046
2047 if (gimple_code (stmt) == GIMPLE_PHI)
2048 {
2049 e = gimple_phi_arg_edge (as_a <gphi *> (stmt),
2050 PHI_ARG_INDEX_FROM_USE (use)phi_arg_index_from_use (use));
2051 if (e->flags & EDGE_ABNORMAL
2052 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)(tree_check ((val), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2052, __FUNCTION__, (SSA_NAME)))->base.asm_written_flag
)
2053 {
2054 /* This can only occur for virtual operands, since
2055 for the real ones SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
2056 would prevent replacement. */
2057 gcc_checking_assert (virtual_operand_p (name))((void)(!(virtual_operand_p (name)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2057, __FUNCTION__), 0 : 0))
;
2058 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)(tree_check ((val), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2058, __FUNCTION__, (SSA_NAME)))->base.asm_written_flag
= 1;
2059 }
2060 }
2061 }
2062
2063 if (gimple_code (stmt) != GIMPLE_PHI)
2064 {
2065 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
2066 gimple *orig_stmt = stmt;
2067 size_t i;
2068
2069 /* FIXME. It shouldn't be required to keep TREE_CONSTANT
2070 on ADDR_EXPRs up-to-date on GIMPLE. Propagation will
2071 only change sth from non-invariant to invariant, and only
2072 when propagating constants. */
2073 if (is_gimple_min_invariant (val))
2074 for (i = 0; i < gimple_num_ops (stmt); i++)
2075 {
2076 tree op = gimple_op (stmt, i);
2077 /* Operands may be empty here. For example, the labels
2078 of a GIMPLE_COND are nulled out following the creation
2079 of the corresponding CFG edges. */
2080 if (op && TREE_CODE (op)((enum tree_code) (op)->base.code) == ADDR_EXPR)
2081 recompute_tree_invariant_for_addr_expr (op);
2082 }
2083
2084 if (fold_stmt (&gsi))
2085 stmt = gsi_stmt (gsi);
2086
2087 if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
2088 gimple_purge_dead_eh_edges (gimple_bb (stmt));
2089
2090 update_stmt (stmt);
2091 }
2092 }
2093
2094 gcc_checking_assert (has_zero_uses (name))((void)(!(has_zero_uses (name)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2094, __FUNCTION__), 0 : 0))
;
2095
2096 /* Also update the trees stored in loop structures. */
2097 if (current_loops((cfun + 0)->x_current_loops))
2098 {
2099 for (auto loop : loops_list (cfun(cfun + 0), 0))
2100 substitute_in_loop_info (loop, name, val);
2101 }
2102}
2103
2104/* Merge block B into block A. */
2105
2106static void
2107gimple_merge_blocks (basic_block a, basic_block b)
2108{
2109 gimple_stmt_iterator last, gsi;
2110 gphi_iterator psi;
2111
2112 if (dump_file)
2113 fprintf (dump_file, "Merging blocks %d and %d\n", a->index, b->index);
2114
2115 /* Remove all single-valued PHI nodes from block B of the form
2116 V_i = PHI <V_j> by propagating V_j to all the uses of V_i. */
2117 gsi = gsi_last_bb (a);
2118 for (psi = gsi_start_phis (b); !gsi_end_p (psi); )
2119 {
2120 gimple *phi = gsi_stmt (psi);
2121 tree def = gimple_phi_result (phi), use = gimple_phi_arg_def (phi, 0);
2122 gimple *copy;
2123 bool may_replace_uses = (virtual_operand_p (def)
2124 || may_propagate_copy (def, use));
2125
2126 /* In case we maintain loop closed ssa form, do not propagate arguments
2127 of loop exit phi nodes. */
2128 if (current_loops((cfun + 0)->x_current_loops)
2129 && loops_state_satisfies_p (LOOP_CLOSED_SSA)
2130 && !virtual_operand_p (def)
2131 && TREE_CODE (use)((enum tree_code) (use)->base.code) == SSA_NAME
2132 && a->loop_father != b->loop_father)
2133 may_replace_uses = false;
2134
2135 if (!may_replace_uses)
2136 {
2137 gcc_assert (!virtual_operand_p (def))((void)(!(!virtual_operand_p (def)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2137, __FUNCTION__), 0 : 0))
;
2138
2139 /* Note that just emitting the copies is fine -- there is no problem
2140 with ordering of phi nodes. This is because A is the single
2141 predecessor of B, therefore results of the phi nodes cannot
2142 appear as arguments of the phi nodes. */
2143 copy = gimple_build_assign (def, use);
2144 gsi_insert_after (&gsi, copy, GSI_NEW_STMT);
2145 remove_phi_node (&psi, false);
2146 }
2147 else
2148 {
2149 /* If we deal with a PHI for virtual operands, we can simply
2150 propagate these without fussing with folding or updating
2151 the stmt. */
2152 if (virtual_operand_p (def))
2153 {
2154 imm_use_iterator iter;
2155 use_operand_p use_p;
2156 gimple *stmt;
2157
2158 FOR_EACH_IMM_USE_STMT (stmt, iter, def)for (struct auto_end_imm_use_stmt_traverse auto_end_imm_use_stmt_traverse
((((stmt) = first_imm_use_stmt (&(iter), (def))), &(
iter))); !end_imm_use_stmt_p (&(iter)); (void) ((stmt) = next_imm_use_stmt
(&(iter))))
2159 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)for ((use_p) = first_imm_use_on_stmt (&(iter)); !end_imm_use_on_stmt_p
(&(iter)); (void) ((use_p) = next_imm_use_on_stmt (&
(iter))))
2160 SET_USE (use_p, use)set_ssa_use_from_ptr (use_p, use);
2161
2162 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)(tree_check ((def), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2162, __FUNCTION__, (SSA_NAME)))->base.asm_written_flag
)
2163 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use)(tree_check ((use), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2163, __FUNCTION__, (SSA_NAME)))->base.asm_written_flag
= 1;
2164 }
2165 else
2166 replace_uses_by (def, use);
2167
2168 remove_phi_node (&psi, true);
2169 }
2170 }
2171
2172 /* Ensure that B follows A. */
2173 move_block_after (b, a);
2174
2175 gcc_assert (single_succ_edge (a)->flags & EDGE_FALLTHRU)((void)(!(single_succ_edge (a)->flags & EDGE_FALLTHRU)
? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2175, __FUNCTION__), 0 : 0))
;
2176 gcc_assert (!last_stmt (a) || !stmt_ends_bb_p (last_stmt (a)))((void)(!(!last_stmt (a) || !stmt_ends_bb_p (last_stmt (a))) ?
fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2176, __FUNCTION__), 0 : 0))
;
2177
2178 /* Remove labels from B and set gimple_bb to A for other statements. */
2179 for (gsi = gsi_start_bb (b); !gsi_end_p (gsi);)
2180 {
2181 gimple *stmt = gsi_stmt (gsi);
2182 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
2183 {
2184 tree label = gimple_label_label (label_stmt);
2185 int lp_nr;
2186
2187 gsi_remove (&gsi, false);
2188
2189 /* Now that we can thread computed gotos, we might have
2190 a situation where we have a forced label in block B
2191 However, the label at the start of block B might still be
2192 used in other ways (think about the runtime checking for
2193 Fortran assigned gotos). So we cannot just delete the
2194 label. Instead we move the label to the start of block A. */
2195 if (FORCED_LABEL (label)((tree_check ((label), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2195, __FUNCTION__, (LABEL_DECL)))->base.side_effects_flag
)
)
2196 {
2197 gimple_stmt_iterator dest_gsi = gsi_start_bb (a);
2198 tree first_label = NULL_TREE(tree) nullptr;
2199 if (!gsi_end_p (dest_gsi))
2200 if (glabel *first_label_stmt
2201 = dyn_cast <glabel *> (gsi_stmt (dest_gsi)))
2202 first_label = gimple_label_label (first_label_stmt);
2203 if (first_label
2204 && (DECL_NONLOCAL (first_label)((contains_struct_check ((first_label), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2204, __FUNCTION__))->decl_common.nonlocal_flag)
2205 || EH_LANDING_PAD_NR (first_label)((tree_check ((first_label), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2205, __FUNCTION__, (LABEL_DECL)))->label_decl.eh_landing_pad_nr
)
!= 0))
2206 gsi_insert_after (&dest_gsi, stmt, GSI_NEW_STMT);
2207 else
2208 gsi_insert_before (&dest_gsi, stmt, GSI_NEW_STMT);
2209 }
2210 /* Other user labels keep around in a form of a debug stmt. */
2211 else if (!DECL_ARTIFICIAL (label)((contains_struct_check ((label), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2211, __FUNCTION__))->decl_common.artificial_flag)
&& MAY_HAVE_DEBUG_BIND_STMTSglobal_options.x_flag_var_tracking_assignments)
2212 {
2213 gimple *dbg = gimple_build_debug_bind (label,
2214 integer_zero_nodeglobal_trees[TI_INTEGER_ZERO],
2215 stmt);
2216 gimple_debug_bind_reset_value (dbg);
2217 gsi_insert_before (&gsi, dbg, GSI_SAME_STMT);
2218 }
2219
2220 lp_nr = EH_LANDING_PAD_NR (label)((tree_check ((label), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2220, __FUNCTION__, (LABEL_DECL)))->label_decl.eh_landing_pad_nr
)
;
2221 if (lp_nr)
2222 {
2223 eh_landing_pad lp = get_eh_landing_pad_from_number (lp_nr);
2224 lp->post_landing_pad = NULLnullptr;
2225 }
2226 }
2227 else
2228 {
2229 gimple_set_bb (stmt, a);
2230 gsi_next (&gsi);
2231 }
2232 }
2233
2234 /* When merging two BBs, if their counts are different, the larger count
2235 is selected as the new bb count. This is to handle inconsistent
2236 profiles. */
2237 if (a->loop_father == b->loop_father)
2238 {
2239 a->count = a->count.merge (b->count);
2240 }
2241
2242 /* Merge the sequences. */
2243 last = gsi_last_bb (a);
2244 gsi_insert_seq_after (&last, bb_seq (b), GSI_NEW_STMT);
2245 set_bb_seq (b, NULLnullptr);
2246
2247 if (cfgcleanup_altered_bbs)
2248 bitmap_set_bit (cfgcleanup_altered_bbs, a->index);
2249}
2250
2251
2252/* Return the one of two successors of BB that is not reachable by a
2253 complex edge, if there is one. Else, return BB. We use
2254 this in optimizations that use post-dominators for their heuristics,
2255 to catch the cases in C++ where function calls are involved. */
2256
2257basic_block
2258single_noncomplex_succ (basic_block bb)
2259{
2260 edge e0, e1;
2261 if (EDGE_COUNT (bb->succs)vec_safe_length (bb->succs) != 2)
2262 return bb;
2263
2264 e0 = EDGE_SUCC (bb, 0)(*(bb)->succs)[(0)];
2265 e1 = EDGE_SUCC (bb, 1)(*(bb)->succs)[(1)];
2266 if (e0->flags & EDGE_COMPLEX(EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_PRESERVE
)
)
2267 return e1->dest;
2268 if (e1->flags & EDGE_COMPLEX(EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_PRESERVE
)
)
2269 return e0->dest;
2270
2271 return bb;
2272}
2273
2274/* T is CALL_EXPR. Set current_function_calls_* flags. */
2275
2276void
2277notice_special_calls (gcall *call)
2278{
2279 int flags = gimple_call_flags (call);
2280
2281 if (flags & ECF_MAY_BE_ALLOCA(1 << 5))
2282 cfun(cfun + 0)->calls_alloca = true;
2283 if (flags & ECF_RETURNS_TWICE(1 << 7))
2284 cfun(cfun + 0)->calls_setjmp = true;
2285}
2286
2287
2288/* Clear flags set by notice_special_calls. Used by dead code removal
2289 to update the flags. */
2290
2291void
2292clear_special_calls (void)
2293{
2294 cfun(cfun + 0)->calls_alloca = false;
2295 cfun(cfun + 0)->calls_setjmp = false;
2296}
2297
2298/* Remove PHI nodes associated with basic block BB and all edges out of BB. */
2299
2300static void
2301remove_phi_nodes_and_edges_for_unreachable_block (basic_block bb)
2302{
2303 /* Since this block is no longer reachable, we can just delete all
2304 of its PHI nodes. */
2305 remove_phi_nodes (bb);
2306
2307 /* Remove edges to BB's successors. */
2308 while (EDGE_COUNT (bb->succs)vec_safe_length (bb->succs) > 0)
2309 remove_edge (EDGE_SUCC (bb, 0)(*(bb)->succs)[(0)]);
2310}
2311
2312
2313/* Remove statements of basic block BB. */
2314
2315static void
2316remove_bb (basic_block bb)
2317{
2318 gimple_stmt_iterator i;
2319
2320 if (dump_file)
2321 {
2322 fprintf (dump_file, "Removing basic block %d\n", bb->index);
2323 if (dump_flags & TDF_DETAILS)
2324 {
2325 dump_bb (dump_file, bb, 0, TDF_BLOCKS);
2326 fprintf (dump_file, "\n");
2327 }
2328 }
2329
2330 if (current_loops((cfun + 0)->x_current_loops))
2331 {
2332 class loop *loop = bb->loop_father;
2333
2334 /* If a loop gets removed, clean up the information associated
2335 with it. */
2336 if (loop->latch == bb
2337 || loop->header == bb)
2338 free_numbers_of_iterations_estimates (loop);
2339 }
2340
2341 /* Remove all the instructions in the block. */
2342 if (bb_seq (bb) != NULLnullptr)
2343 {
2344 /* Walk backwards so as to get a chance to substitute all
2345 released DEFs into debug stmts. See
2346 eliminate_unnecessary_stmts() in tree-ssa-dce.cc for more
2347 details. */
2348 for (i = gsi_last_bb (bb); !gsi_end_p (i);)
2349 {
2350 gimple *stmt = gsi_stmt (i);
2351 glabel *label_stmt = dyn_cast <glabel *> (stmt);
2352 if (label_stmt
2353 && (FORCED_LABEL (gimple_label_label (label_stmt))((tree_check ((gimple_label_label (label_stmt)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2353, __FUNCTION__, (LABEL_DECL)))->base.side_effects_flag
)
2354 || DECL_NONLOCAL (gimple_label_label (label_stmt))((contains_struct_check ((gimple_label_label (label_stmt)), (
TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2354, __FUNCTION__))->decl_common.nonlocal_flag)
))
2355 {
2356 basic_block new_bb;
2357 gimple_stmt_iterator new_gsi;
2358
2359 /* A non-reachable non-local label may still be referenced.
2360 But it no longer needs to carry the extra semantics of
2361 non-locality. */
2362 if (DECL_NONLOCAL (gimple_label_label (label_stmt))((contains_struct_check ((gimple_label_label (label_stmt)), (
TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2362, __FUNCTION__))->decl_common.nonlocal_flag)
)
2363 {
2364 DECL_NONLOCAL (gimple_label_label (label_stmt))((contains_struct_check ((gimple_label_label (label_stmt)), (
TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2364, __FUNCTION__))->decl_common.nonlocal_flag)
= 0;
2365 FORCED_LABEL (gimple_label_label (label_stmt))((tree_check ((gimple_label_label (label_stmt)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2365, __FUNCTION__, (LABEL_DECL)))->base.side_effects_flag
)
= 1;
2366 }
2367
2368 new_bb = bb->prev_bb;
2369 /* Don't move any labels into ENTRY block. */
2370 if (new_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)(((cfun + 0))->cfg->x_entry_block_ptr))
2371 {
2372 new_bb = single_succ (new_bb);
2373 gcc_assert (new_bb != bb)((void)(!(new_bb != bb) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2373, __FUNCTION__), 0 : 0))
;
2374 }
2375 if ((unsigned) bb->index < bb_to_omp_idx.length ()
2376 && ((unsigned) new_bb->index >= bb_to_omp_idx.length ()
2377 || (bb_to_omp_idx[bb->index]
2378 != bb_to_omp_idx[new_bb->index])))
2379 {
2380 /* During cfg pass make sure to put orphaned labels
2381 into the right OMP region. */
2382 unsigned int i;
2383 int idx;
2384 new_bb = NULLnullptr;
2385 FOR_EACH_VEC_ELT (bb_to_omp_idx, i, idx)for (i = 0; (bb_to_omp_idx).iterate ((i), &(idx)); ++(i))
2386 if (i >= NUM_FIXED_BLOCKS(2)
2387 && idx == bb_to_omp_idx[bb->index]
2388 && i != (unsigned) bb->index)
2389 {
2390 new_bb = BASIC_BLOCK_FOR_FN (cfun, i)((*(((cfun + 0))->cfg->x_basic_block_info))[(i)]);
2391 break;
2392 }
2393 if (new_bb == NULLnullptr)
2394 {
2395 new_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)(((cfun + 0))->cfg->x_entry_block_ptr));
2396 gcc_assert (new_bb != bb)((void)(!(new_bb != bb) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2396, __FUNCTION__), 0 : 0))
;
2397 }
2398 }
2399 new_gsi = gsi_after_labels (new_bb);
2400 gsi_remove (&i, false);
2401 gsi_insert_before (&new_gsi, stmt, GSI_NEW_STMT);
2402 }
2403 else
2404 {
2405 /* Release SSA definitions. */
2406 release_defs (stmt);
2407 gsi_remove (&i, true);
2408 }
2409
2410 if (gsi_end_p (i))
2411 i = gsi_last_bb (bb);
2412 else
2413 gsi_prev (&i);
2414 }
2415 }
2416
2417 if ((unsigned) bb->index < bb_to_omp_idx.length ())
2418 bb_to_omp_idx[bb->index] = -1;
2419 remove_phi_nodes_and_edges_for_unreachable_block (bb);
2420 bb->il.gimple.seq = NULLnullptr;
2421 bb->il.gimple.phi_nodes = NULLnullptr;
2422}
2423
2424
2425/* Given a basic block BB and a value VAL for use in the final statement
2426 of the block (if a GIMPLE_COND, GIMPLE_SWITCH, or computed goto), return
2427 the edge that will be taken out of the block.
2428 If VAL is NULL_TREE, then the current value of the final statement's
2429 predicate or index is used.
2430 If the value does not match a unique edge, NULL is returned. */
2431
2432edge
2433find_taken_edge (basic_block bb, tree val)
2434{
2435 gimple *stmt;
2436
2437 stmt = last_stmt (bb);
2438
2439 /* Handle ENTRY and EXIT. */
2440 if (!stmt)
2441 return NULLnullptr;
2442
2443 if (gimple_code (stmt) == GIMPLE_COND)
2444 return find_taken_edge_cond_expr (as_a <gcond *> (stmt), val);
2445
2446 if (gimple_code (stmt) == GIMPLE_SWITCH)
2447 return find_taken_edge_switch_expr (as_a <gswitch *> (stmt), val);
2448
2449 if (computed_goto_p (stmt))
2450 {
2451 /* Only optimize if the argument is a label, if the argument is
2452 not a label then we cannot construct a proper CFG.
2453
2454 It may be the case that we only need to allow the LABEL_REF to
2455 appear inside an ADDR_EXPR, but we also allow the LABEL_REF to
2456 appear inside a LABEL_EXPR just to be safe. */
2457 if (val
2458 && (TREE_CODE (val)((enum tree_code) (val)->base.code) == ADDR_EXPR || TREE_CODE (val)((enum tree_code) (val)->base.code) == LABEL_EXPR)
2459 && TREE_CODE (TREE_OPERAND (val, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check
((val), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2459, __FUNCTION__))))))->base.code)
== LABEL_DECL)
2460 return find_taken_edge_computed_goto (bb, TREE_OPERAND (val, 0)(*((const_cast<tree*> (tree_operand_check ((val), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2460, __FUNCTION__)))))
);
2461 }
2462
2463 /* Otherwise we only know the taken successor edge if it's unique. */
2464 return single_succ_p (bb) ? single_succ_edge (bb) : NULLnullptr;
2465}
2466
2467/* Given a constant value VAL and the entry block BB to a GOTO_EXPR
2468 statement, determine which of the outgoing edges will be taken out of the
2469 block. Return NULL if either edge may be taken. */
2470
2471static edge
2472find_taken_edge_computed_goto (basic_block bb, tree val)
2473{
2474 basic_block dest;
2475 edge e = NULLnullptr;
2476
2477 dest = label_to_block (cfun(cfun + 0), val);
2478 if (dest)
2479 e = find_edge (bb, dest);
2480
2481 /* It's possible for find_edge to return NULL here on invalid code
2482 that abuses the labels-as-values extension (e.g. code that attempts to
2483 jump *between* functions via stored labels-as-values; PR 84136).
2484 If so, then we simply return that NULL for the edge.
2485 We don't currently have a way of detecting such invalid code, so we
2486 can't assert that it was the case when a NULL edge occurs here. */
2487
2488 return e;
2489}
2490
2491/* Given COND_STMT and a constant value VAL for use as the predicate,
2492 determine which of the two edges will be taken out of
2493 the statement's block. Return NULL if either edge may be taken.
2494 If VAL is NULL_TREE, then the current value of COND_STMT's predicate
2495 is used. */
2496
2497static edge
2498find_taken_edge_cond_expr (const gcond *cond_stmt, tree val)
2499{
2500 edge true_edge, false_edge;
2501
2502 if (val == NULL_TREE(tree) nullptr)
2503 {
2504 /* Use the current value of the predicate. */
2505 if (gimple_cond_true_p (cond_stmt))
2506 val = integer_one_nodeglobal_trees[TI_INTEGER_ONE];
2507 else if (gimple_cond_false_p (cond_stmt))
2508 val = integer_zero_nodeglobal_trees[TI_INTEGER_ZERO];
2509 else
2510 return NULLnullptr;
2511 }
2512 else if (TREE_CODE (val)((enum tree_code) (val)->base.code) != INTEGER_CST)
2513 return NULLnullptr;
2514
2515 extract_true_false_edges_from_block (gimple_bb (cond_stmt),
2516 &true_edge, &false_edge);
2517
2518 return (integer_zerop (val) ? false_edge : true_edge);
2519}
2520
2521/* Given SWITCH_STMT and an INTEGER_CST VAL for use as the index, determine
2522 which edge will be taken out of the statement's block. Return NULL if any
2523 edge may be taken.
2524 If VAL is NULL_TREE, then the current value of SWITCH_STMT's index
2525 is used. */
2526
2527edge
2528find_taken_edge_switch_expr (const gswitch *switch_stmt, tree val)
2529{
2530 basic_block dest_bb;
2531 edge e;
2532 tree taken_case;
2533
2534 if (gimple_switch_num_labels (switch_stmt) == 1)
2535 taken_case = gimple_switch_default_label (switch_stmt);
2536 else
2537 {
2538 if (val == NULL_TREE(tree) nullptr)
2539 val = gimple_switch_index (switch_stmt);
2540 if (TREE_CODE (val)((enum tree_code) (val)->base.code) != INTEGER_CST)
2541 return NULLnullptr;
2542 else
2543 taken_case = find_case_label_for_value (switch_stmt, val);
2544 }
2545 dest_bb = label_to_block (cfun(cfun + 0), CASE_LABEL (taken_case)(*((const_cast<tree*> (tree_operand_check (((tree_check
((taken_case), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2545, __FUNCTION__, (CASE_LABEL_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2545, __FUNCTION__)))))
);
2546
2547 e = find_edge (gimple_bb (switch_stmt), dest_bb);
2548 gcc_assert (e)((void)(!(e) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2548, __FUNCTION__), 0 : 0))
;
2549 return e;
2550}
2551
2552
2553/* Return the CASE_LABEL_EXPR that SWITCH_STMT will take for VAL.
2554 We can make optimal use here of the fact that the case labels are
2555 sorted: We can do a binary search for a case matching VAL. */
2556
2557tree
2558find_case_label_for_value (const gswitch *switch_stmt, tree val)
2559{
2560 size_t low, high, n = gimple_switch_num_labels (switch_stmt);
2561 tree default_case = gimple_switch_default_label (switch_stmt);
2562
2563 for (low = 0, high = n; high - low > 1; )
2564 {
2565 size_t i = (high + low) / 2;
2566 tree t = gimple_switch_label (switch_stmt, i);
2567 int cmp;
2568
2569 /* Cache the result of comparing CASE_LOW and val. */
2570 cmp = tree_int_cst_compare (CASE_LOW (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2570, __FUNCTION__, (CASE_LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2570, __FUNCTION__)))))
, val);
2571
2572 if (cmp > 0)
2573 high = i;
2574 else
2575 low = i;
2576
2577 if (CASE_HIGH (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2577, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2577, __FUNCTION__)))))
== NULLnullptr)
2578 {
2579 /* A singe-valued case label. */
2580 if (cmp == 0)
2581 return t;
2582 }
2583 else
2584 {
2585 /* A case range. We can only handle integer ranges. */
2586 if (cmp <= 0 && tree_int_cst_compare (CASE_HIGH (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2586, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2586, __FUNCTION__)))))
, val) >= 0)
2587 return t;
2588 }
2589 }
2590
2591 return default_case;
2592}
2593
2594
2595/* Dump a basic block on stderr. */
2596
2597void
2598gimple_debug_bb (basic_block bb)
2599{
2600 dump_bb (stderrstderr, bb, 0, TDF_VOPS|TDF_MEMSYMS|TDF_BLOCKS);
2601}
2602
2603
2604/* Dump basic block with index N on stderr. */
2605
2606basic_block
2607gimple_debug_bb_n (int n)
2608{
2609 gimple_debug_bb (BASIC_BLOCK_FOR_FN (cfun, n)((*(((cfun + 0))->cfg->x_basic_block_info))[(n)]));
2610 return BASIC_BLOCK_FOR_FN (cfun, n)((*(((cfun + 0))->cfg->x_basic_block_info))[(n)]);
2611}
2612
2613
2614/* Dump the CFG on stderr.
2615
2616 FLAGS are the same used by the tree dumping functions
2617 (see TDF_* in dumpfile.h). */
2618
2619void
2620gimple_debug_cfg (dump_flags_t flags)
2621{
2622 gimple_dump_cfg (stderrstderr, flags);
2623}
2624
2625
2626/* Dump the program showing basic block boundaries on the given FILE.
2627
2628 FLAGS are the same used by the tree dumping functions (see TDF_* in
2629 tree.h). */
2630
2631void
2632gimple_dump_cfg (FILE *file, dump_flags_t flags)
2633{
2634 if (flags & TDF_DETAILS)
2635 {
2636 dump_function_header (file, current_function_decl, flags);
2637 fprintf (file, ";; \n%d basic blocks, %d edges, last basic block %d.\n\n",
2638 n_basic_blocks_for_fn (cfun)(((cfun + 0))->cfg->x_n_basic_blocks), n_edges_for_fn (cfun)(((cfun + 0))->cfg->x_n_edges),
2639 last_basic_block_for_fn (cfun)(((cfun + 0))->cfg->x_last_basic_block));
2640
2641 brief_dump_cfg (file, flags);
2642 fprintf (file, "\n");
2643 }
2644
2645 if (flags & TDF_STATS)
2646 dump_cfg_stats (file);
2647
2648 dump_function_to_file (current_function_decl, file, flags | TDF_BLOCKS);
2649}
2650
2651
2652/* Dump CFG statistics on FILE. */
2653
2654void
2655dump_cfg_stats (FILE *file)
2656{
2657 static long max_num_merged_labels = 0;
2658 unsigned long size, total = 0;
2659 long num_edges;
2660 basic_block bb;
2661 const char * const fmt_str = "%-30s%-13s%12s\n";
2662 const char * const fmt_str_1 = "%-30s%13d" PRsa (11)"%" "11" "l" "u" "%c" "\n";
2663 const char * const fmt_str_2 = "%-30s%13ld" PRsa (11)"%" "11" "l" "u" "%c" "\n";
2664 const char * const fmt_str_3 = "%-43s" PRsa (11)"%" "11" "l" "u" "%c" "\n";
2665 const char *funcname = current_function_name ();
2666
2667 fprintf (file, "\nCFG Statistics for %s\n\n", funcname);
2668
2669 fprintf (file, "---------------------------------------------------------\n");
2670 fprintf (file, fmt_str, "", " Number of ", "Memory");
2671 fprintf (file, fmt_str, "", " instances ", "used ");
2672 fprintf (file, "---------------------------------------------------------\n");
2673
2674 size = n_basic_blocks_for_fn (cfun)(((cfun + 0))->cfg->x_n_basic_blocks) * sizeof (struct basic_block_def);
2675 total += size;
2676 fprintf (file, fmt_str_1, "Basic blocks", n_basic_blocks_for_fn (cfun)(((cfun + 0))->cfg->x_n_basic_blocks),
2677 SIZE_AMOUNT (size)(uint64_t)(((size) < 10 * 1024 ? (size) : ((size) < 10 *
(1024 * 1024) ? (size) / 1024 : (size) / (1024 * 1024)))), (
(size) < 10 * 1024 ? ' ' : ((size) < 10 * (1024 * 1024)
? 'k' : 'M'))
);
2678
2679 num_edges = 0;
2680 FOR_EACH_BB_FN (bb, cfun)for (bb = ((cfun + 0))->cfg->x_entry_block_ptr->next_bb
; bb != ((cfun + 0))->cfg->x_exit_block_ptr; bb = bb->
next_bb)
2681 num_edges += EDGE_COUNT (bb->succs)vec_safe_length (bb->succs);
2682 size = num_edges * sizeof (class edge_def);
2683 total += size;
2684 fprintf (file, fmt_str_2, "Edges", num_edges, SIZE_AMOUNT (size)(uint64_t)(((size) < 10 * 1024 ? (size) : ((size) < 10 *
(1024 * 1024) ? (size) / 1024 : (size) / (1024 * 1024)))), (
(size) < 10 * 1024 ? ' ' : ((size) < 10 * (1024 * 1024)
? 'k' : 'M'))
);
2685
2686 fprintf (file, "---------------------------------------------------------\n");
2687 fprintf (file, fmt_str_3, "Total memory used by CFG data",
2688 SIZE_AMOUNT (total)(uint64_t)(((total) < 10 * 1024 ? (total) : ((total) < 10
* (1024 * 1024) ? (total) / 1024 : (total) / (1024 * 1024)))
), ((total) < 10 * 1024 ? ' ' : ((total) < 10 * (1024 *
1024) ? 'k' : 'M'))
);
2689 fprintf (file, "---------------------------------------------------------\n");
2690 fprintf (file, "\n");
2691
2692 if (cfg_stats.num_merged_labels > max_num_merged_labels)
2693 max_num_merged_labels = cfg_stats.num_merged_labels;
2694
2695 fprintf (file, "Coalesced label blocks: %ld (Max so far: %ld)\n",
2696 cfg_stats.num_merged_labels, max_num_merged_labels);
2697
2698 fprintf (file, "\n");
2699}
2700
2701
2702/* Dump CFG statistics on stderr. Keep extern so that it's always
2703 linked in the final executable. */
2704
2705DEBUG_FUNCTION__attribute__ ((__used__)) void
2706debug_cfg_stats (void)
2707{
2708 dump_cfg_stats (stderrstderr);
2709}
2710
2711/*---------------------------------------------------------------------------
2712 Miscellaneous helpers
2713---------------------------------------------------------------------------*/
2714
2715/* Return true if T, a GIMPLE_CALL, can make an abnormal transfer of control
2716 flow. Transfers of control flow associated with EH are excluded. */
2717
2718static bool
2719call_can_make_abnormal_goto (gimple *t)
2720{
2721 /* If the function has no non-local labels, then a call cannot make an
2722 abnormal transfer of control. */
2723 if (!cfun(cfun + 0)->has_nonlocal_label
2724 && !cfun(cfun + 0)->calls_setjmp)
2725 return false;
2726
2727 /* Likewise if the call has no side effects. */
2728 if (!gimple_has_side_effects (t))
2729 return false;
2730
2731 /* Likewise if the called function is leaf. */
2732 if (gimple_call_flags (t) & ECF_LEAF(1 << 10))
2733 return false;
2734
2735 return true;
2736}
2737
2738
2739/* Return true if T can make an abnormal transfer of control flow.
2740 Transfers of control flow associated with EH are excluded. */
2741
2742bool
2743stmt_can_make_abnormal_goto (gimple *t)
2744{
2745 if (computed_goto_p (t))
2746 return true;
2747 if (is_gimple_call (t))
2748 return call_can_make_abnormal_goto (t);
2749 return false;
2750}
2751
2752
2753/* Return true if T represents a stmt that always transfers control. */
2754
2755bool
2756is_ctrl_stmt (gimple *t)
2757{
2758 switch (gimple_code (t))
2759 {
2760 case GIMPLE_COND:
2761 case GIMPLE_SWITCH:
2762 case GIMPLE_GOTO:
2763 case GIMPLE_RETURN:
2764 case GIMPLE_RESX:
2765 return true;
2766 default:
2767 return false;
2768 }
2769}
2770
2771
2772/* Return true if T is a statement that may alter the flow of control
2773 (e.g., a call to a non-returning function). */
2774
2775bool
2776is_ctrl_altering_stmt (gimple *t)
2777{
2778 gcc_assert (t)((void)(!(t) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2778, __FUNCTION__), 0 : 0))
;
2779
2780 switch (gimple_code (t))
2781 {
2782 case GIMPLE_CALL:
2783 /* Per stmt call flag indicates whether the call could alter
2784 controlflow. */
2785 if (gimple_call_ctrl_altering_p (t))
2786 return true;
2787 break;
2788
2789 case GIMPLE_EH_DISPATCH:
2790 /* EH_DISPATCH branches to the individual catch handlers at
2791 this level of a try or allowed-exceptions region. It can
2792 fallthru to the next statement as well. */
2793 return true;
2794
2795 case GIMPLE_ASM:
2796 if (gimple_asm_nlabels (as_a <gasm *> (t)) > 0)
2797 return true;
2798 break;
2799
2800 CASE_GIMPLE_OMPcase GIMPLE_OMP_PARALLEL: case GIMPLE_OMP_TASK: case GIMPLE_OMP_FOR
: case GIMPLE_OMP_SECTIONS: case GIMPLE_OMP_SECTIONS_SWITCH: case
GIMPLE_OMP_SINGLE: case GIMPLE_OMP_TARGET: case GIMPLE_OMP_TEAMS
: case GIMPLE_OMP_SCOPE: case GIMPLE_OMP_SECTION: case GIMPLE_OMP_MASTER
: case GIMPLE_OMP_MASKED: case GIMPLE_OMP_TASKGROUP: case GIMPLE_OMP_ORDERED
: case GIMPLE_OMP_CRITICAL: case GIMPLE_OMP_SCAN: case GIMPLE_OMP_RETURN
: case GIMPLE_OMP_ATOMIC_LOAD: case GIMPLE_OMP_ATOMIC_STORE: case
GIMPLE_OMP_CONTINUE
:
2801 /* OpenMP directives alter control flow. */
2802 return true;
2803
2804 case GIMPLE_TRANSACTION:
2805 /* A transaction start alters control flow. */
2806 return true;
2807
2808 default:
2809 break;
2810 }
2811
2812 /* If a statement can throw, it alters control flow. */
2813 return stmt_can_throw_internal (cfun(cfun + 0), t);
2814}
2815
2816
2817/* Return true if T is a simple local goto. */
2818
2819bool
2820simple_goto_p (gimple *t)
2821{
2822 return (gimple_code (t) == GIMPLE_GOTO
2823 && TREE_CODE (gimple_goto_dest (t))((enum tree_code) (gimple_goto_dest (t))->base.code) == LABEL_DECL);
2824}
2825
2826
2827/* Return true if STMT should start a new basic block. PREV_STMT is
2828 the statement preceding STMT. It is used when STMT is a label or a
2829 case label. Labels should only start a new basic block if their
2830 previous statement wasn't a label. Otherwise, sequence of labels
2831 would generate unnecessary basic blocks that only contain a single
2832 label. */
2833
2834static inline bool
2835stmt_starts_bb_p (gimple *stmt, gimple *prev_stmt)
2836{
2837 if (stmt == NULLnullptr)
2838 return false;
2839
2840 /* PREV_STMT is only set to a debug stmt if the debug stmt is before
2841 any nondebug stmts in the block. We don't want to start another
2842 block in this case: the debug stmt will already have started the
2843 one STMT would start if we weren't outputting debug stmts. */
2844 if (prev_stmt && is_gimple_debug (prev_stmt))
2845 return false;
2846
2847 /* Labels start a new basic block only if the preceding statement
2848 wasn't a label of the same type. This prevents the creation of
2849 consecutive blocks that have nothing but a single label. */
2850 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
2851 {
2852 /* Nonlocal and computed GOTO targets always start a new block. */
2853 if (DECL_NONLOCAL (gimple_label_label (label_stmt))((contains_struct_check ((gimple_label_label (label_stmt)), (
TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2853, __FUNCTION__))->decl_common.nonlocal_flag)
2854 || FORCED_LABEL (gimple_label_label (label_stmt))((tree_check ((gimple_label_label (label_stmt)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2854, __FUNCTION__, (LABEL_DECL)))->base.side_effects_flag
)
)
2855 return true;
2856
2857 if (glabel *plabel = safe_dyn_cast <glabel *> (prev_stmt))
2858 {
2859 if (DECL_NONLOCAL (gimple_label_label (plabel))((contains_struct_check ((gimple_label_label (plabel)), (TS_DECL_COMMON
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2859, __FUNCTION__))->decl_common.nonlocal_flag)
2860 || !DECL_ARTIFICIAL (gimple_label_label (plabel))((contains_struct_check ((gimple_label_label (plabel)), (TS_DECL_COMMON
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 2860, __FUNCTION__))->decl_common.artificial_flag)
)
2861 return true;
2862
2863 cfg_stats.num_merged_labels++;
2864 return false;
2865 }
2866 else
2867 return true;
2868 }
2869 else if (gimple_code (stmt) == GIMPLE_CALL)
2870 {
2871 if (gimple_call_flags (stmt) & ECF_RETURNS_TWICE(1 << 7))
2872 /* setjmp acts similar to a nonlocal GOTO target and thus should
2873 start a new block. */
2874 return true;
2875 if (gimple_call_internal_p (stmt, IFN_PHI)
2876 && prev_stmt
2877 && gimple_code (prev_stmt) != GIMPLE_LABEL
2878 && (gimple_code (prev_stmt) != GIMPLE_CALL
2879 || ! gimple_call_internal_p (prev_stmt, IFN_PHI)))
2880 /* PHI nodes start a new block unless preceeded by a label
2881 or another PHI. */
2882 return true;
2883 }
2884
2885 return false;
2886}
2887
2888
2889/* Return true if T should end a basic block. */
2890
2891bool
2892stmt_ends_bb_p (gimple *t)
2893{
2894 return is_ctrl_stmt (t) || is_ctrl_altering_stmt (t);
2895}
2896
2897/* Remove block annotations and other data structures. */
2898
2899void
2900delete_tree_cfg_annotations (struct function *fn)
2901{
2902 vec_free (label_to_block_map_for_fn (fn)((fn)->cfg->x_label_to_block_map));
2903}
2904
2905/* Return the virtual phi in BB. */
2906
2907gphi *
2908get_virtual_phi (basic_block bb)
2909{
2910 for (gphi_iterator gsi = gsi_start_phis (bb);
2911 !gsi_end_p (gsi);
2912 gsi_next (&gsi))
2913 {
2914 gphi *phi = gsi.phi ();
2915
2916 if (virtual_operand_p (PHI_RESULT (phi)get_def_from_ptr (gimple_phi_result_ptr (phi))))
2917 return phi;
2918 }
2919
2920 return NULLnullptr;
2921}
2922
2923/* Return the first statement in basic block BB. */
2924
2925gimple *
2926first_stmt (basic_block bb)
2927{
2928 gimple_stmt_iterator i = gsi_start_bb (bb);
2929 gimple *stmt = NULLnullptr;
2930
2931 while (!gsi_end_p (i) && is_gimple_debug ((stmt = gsi_stmt (i))))
2932 {
2933 gsi_next (&i);
2934 stmt = NULLnullptr;
2935 }
2936 return stmt;
2937}
2938
2939/* Return the first non-label statement in basic block BB. */
2940
2941static gimple *
2942first_non_label_stmt (basic_block bb)
2943{
2944 gimple_stmt_iterator i = gsi_start_bb (bb);
2945 while (!gsi_end_p (i) && gimple_code (gsi_stmt (i)) == GIMPLE_LABEL)
2946 gsi_next (&i);
2947 return !gsi_end_p (i) ? gsi_stmt (i) : NULLnullptr;
2948}
2949
2950/* Return the last statement in basic block BB. */
2951
2952gimple *
2953last_stmt (basic_block bb)
2954{
2955 gimple_stmt_iterator i = gsi_last_bb (bb);
2956 gimple *stmt = NULLnullptr;
2957
2958 while (!gsi_end_p (i) && is_gimple_debug ((stmt = gsi_stmt (i))))
2959 {
2960 gsi_prev (&i);
2961 stmt = NULLnullptr;
2962 }
2963 return stmt;
2964}
2965
2966/* Return the last statement of an otherwise empty block. Return NULL
2967 if the block is totally empty, or if it contains more than one
2968 statement. */
2969
2970gimple *
2971last_and_only_stmt (basic_block bb)
2972{
2973 gimple_stmt_iterator i = gsi_last_nondebug_bb (bb);
2974 gimple *last, *prev;
2975
2976 if (gsi_end_p (i))
2977 return NULLnullptr;
2978
2979 last = gsi_stmt (i);
2980 gsi_prev_nondebug (&i);
2981 if (gsi_end_p (i))
2982 return last;
2983
2984 /* Empty statements should no longer appear in the instruction stream.
2985 Everything that might have appeared before should be deleted by
2986 remove_useless_stmts, and the optimizers should just gsi_remove
2987 instead of smashing with build_empty_stmt.
2988
2989 Thus the only thing that should appear here in a block containing
2990 one executable statement is a label. */
2991 prev = gsi_stmt (i);
2992 if (gimple_code (prev) == GIMPLE_LABEL)
2993 return last;
2994 else
2995 return NULLnullptr;
2996}
2997
2998/* Returns the basic block after which the new basic block created
2999 by splitting edge EDGE_IN should be placed. Tries to keep the new block
3000 near its "logical" location. This is of most help to humans looking
3001 at debugging dumps. */
3002
3003basic_block
3004split_edge_bb_loc (edge edge_in)
3005{
3006 basic_block dest = edge_in->dest;
3007 basic_block dest_prev = dest->prev_bb;
3008
3009 if (dest_prev)
3010 {
3011 edge e = find_edge (dest_prev, dest);
3012 if (e && !(e->flags & EDGE_COMPLEX(EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_PRESERVE
)
))
3013 return edge_in->src;
3014 }
3015 return dest_prev;
3016}
3017
3018/* Split a (typically critical) edge EDGE_IN. Return the new block.
3019 Abort on abnormal edges. */
3020
3021static basic_block
3022gimple_split_edge (edge edge_in)
3023{
3024 basic_block new_bb, after_bb, dest;
3025 edge new_edge, e;
3026
3027 /* Abnormal edges cannot be split. */
3028 gcc_assert (!(edge_in->flags & EDGE_ABNORMAL))((void)(!(!(edge_in->flags & EDGE_ABNORMAL)) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3028, __FUNCTION__), 0 : 0))
;
3029
3030 dest = edge_in->dest;
3031
3032 after_bb = split_edge_bb_loc (edge_in);
3033
3034 new_bb = create_empty_bb (after_bb);
3035 new_bb->count = edge_in->count ();
3036
3037 /* We want to avoid re-allocating PHIs when we first
3038 add the fallthru edge from new_bb to dest but we also
3039 want to avoid changing PHI argument order when
3040 first redirecting edge_in away from dest. The former
3041 avoids changing PHI argument order by adding them
3042 last and then the redirection swapping it back into
3043 place by means of unordered remove.
3044 So hack around things by temporarily removing all PHIs
3045 from the destination during the edge redirection and then
3046 making sure the edges stay in order. */
3047 gimple_seq saved_phis = phi_nodes (dest);
3048 unsigned old_dest_idx = edge_in->dest_idx;
3049 set_phi_nodes (dest, NULLnullptr);
3050 new_edge = make_single_succ_edge (new_bb, dest, EDGE_FALLTHRU);
3051 e = redirect_edge_and_branch (edge_in, new_bb);
3052 gcc_assert (e == edge_in && new_edge->dest_idx == old_dest_idx)((void)(!(e == edge_in && new_edge->dest_idx == old_dest_idx
) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3052, __FUNCTION__), 0 : 0))
;
3053 /* set_phi_nodes sets the BB of the PHI nodes, so do it manually here. */
3054 dest->il.gimple.phi_nodes = saved_phis;
3055
3056 return new_bb;
3057}
3058
3059
3060/* Verify properties of the address expression T whose base should be
3061 TREE_ADDRESSABLE if VERIFY_ADDRESSABLE is true. */
3062
3063static bool
3064verify_address (tree t, bool verify_addressable)
3065{
3066 bool old_constant;
3067 bool old_side_effects;
3068 bool new_constant;
3069 bool new_side_effects;
3070
3071 old_constant = TREE_CONSTANT (t)((non_type_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3071, __FUNCTION__))->base.constant_flag)
;
3072 old_side_effects = TREE_SIDE_EFFECTS (t)((non_type_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3072, __FUNCTION__))->base.side_effects_flag)
;
3073
3074 recompute_tree_invariant_for_addr_expr (t);
3075 new_side_effects = TREE_SIDE_EFFECTS (t)((non_type_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3075, __FUNCTION__))->base.side_effects_flag)
;
3076 new_constant = TREE_CONSTANT (t)((non_type_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3076, __FUNCTION__))->base.constant_flag)
;
3077
3078 if (old_constant != new_constant)
3079 {
3080 error ("constant not recomputed when %<ADDR_EXPR%> changed");
3081 return true;
3082 }
3083 if (old_side_effects != new_side_effects)
3084 {
3085 error ("side effects not recomputed when %<ADDR_EXPR%> changed");
3086 return true;
3087 }
3088
3089 tree base = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3089, __FUNCTION__)))))
;
3090 while (handled_component_p (base))
3091 base = TREE_OPERAND (base, 0)(*((const_cast<tree*> (tree_operand_check ((base), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3091, __FUNCTION__)))))
;
3092
3093 if (!(VAR_P (base)(((enum tree_code) (base)->base.code) == VAR_DECL)
3094 || TREE_CODE (base)((enum tree_code) (base)->base.code) == PARM_DECL
3095 || TREE_CODE (base)((enum tree_code) (base)->base.code) == RESULT_DECL))
3096 return false;
3097
3098 if (verify_addressable && !TREE_ADDRESSABLE (base)((base)->base.addressable_flag))
3099 {
3100 error ("address taken but %<TREE_ADDRESSABLE%> bit not set");
3101 return true;
3102 }
3103
3104 return false;
3105}
3106
3107
3108/* Verify if EXPR is a valid GIMPLE reference expression. If
3109 REQUIRE_LVALUE is true verifies it is an lvalue. Returns true
3110 if there is an error, otherwise false. */
3111
3112static bool
3113verify_types_in_gimple_reference (tree expr, bool require_lvalue)
3114{
3115 const char *code_name = get_tree_code_name (TREE_CODE (expr)((enum tree_code) (expr)->base.code));
3116
3117 if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == REALPART_EXPR
3118 || TREE_CODE (expr)((enum tree_code) (expr)->base.code) == IMAGPART_EXPR
3119 || TREE_CODE (expr)((enum tree_code) (expr)->base.code) == BIT_FIELD_REF)
3120 {
3121 tree op = TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3121, __FUNCTION__)))))
;
3122 if (!is_gimple_reg_type (TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3122, __FUNCTION__))->typed.type)
))
3123 {
3124 error ("non-scalar %qs", code_name);
3125 return true;
3126 }
3127
3128 if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == BIT_FIELD_REF)
3129 {
3130 tree t1 = TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3130, __FUNCTION__)))))
;
3131 tree t2 = TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3131, __FUNCTION__)))))
;
3132 poly_uint64 size, bitpos;
3133 if (!poly_int_tree_p (t1, &size)
3134 || !poly_int_tree_p (t2, &bitpos)
3135 || !types_compatible_p (bitsizetypesizetype_tab[(int) stk_bitsizetype], TREE_TYPE (t1)((contains_struct_check ((t1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3135, __FUNCTION__))->typed.type)
)
3136 || !types_compatible_p (bitsizetypesizetype_tab[(int) stk_bitsizetype], TREE_TYPE (t2)((contains_struct_check ((t2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3136, __FUNCTION__))->typed.type)
))
3137 {
3138 error ("invalid position or size operand to %qs", code_name);
3139 return true;
3140 }
3141 if (INTEGRAL_TYPE_P (TREE_TYPE (expr))(((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3141, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3141, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3141, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
3142 && maybe_ne (TYPE_PRECISION (TREE_TYPE (expr))((tree_class_check ((((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3142, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3142, __FUNCTION__))->type_common.precision)
, size))
3143 {
3144 error ("integral result type precision does not match "
3145 "field size of %qs", code_name);
3146 return true;
3147 }
3148 else if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))(((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3148, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3148, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3148, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
3149 && TYPE_MODE (TREE_TYPE (expr))((((enum tree_code) ((tree_class_check ((((contains_struct_check
((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3149, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3149, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3149, __FUNCTION__))->typed.type)) : (((contains_struct_check
((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3149, __FUNCTION__))->typed.type))->type_common.mode)
!= BLKmode((void) 0, E_BLKmode)
3150 && maybe_ne (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr))((((enum tree_code) ((tree_class_check ((((contains_struct_check
((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3150, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3150, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3150, __FUNCTION__))->typed.type)) : (((contains_struct_check
((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3150, __FUNCTION__))->typed.type))->type_common.mode)
),
3151 size))
3152 {
3153 error ("mode size of non-integral result does not "
3154 "match field size of %qs",
3155 code_name);
3156 return true;
3157 }
3158 if (INTEGRAL_TYPE_P (TREE_TYPE (op))(((enum tree_code) (((contains_struct_check ((op), (TS_TYPED)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3158, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((op), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3158, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((op), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3158, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
3159 && !type_has_mode_precision_p (TREE_TYPE (op)((contains_struct_check ((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3159, __FUNCTION__))->typed.type)
))
3160 {
3161 error ("%qs of non-mode-precision operand", code_name);
3162 return true;
3163 }
3164 if (!AGGREGATE_TYPE_P (TREE_TYPE (op))(((enum tree_code) (((contains_struct_check ((op), (TS_TYPED)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3164, __FUNCTION__))->typed.type))->base.code) == ARRAY_TYPE
|| (((enum tree_code) (((contains_struct_check ((op), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3164, __FUNCTION__))->typed.type))->base.code) == RECORD_TYPE
|| ((enum tree_code) (((contains_struct_check ((op), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3164, __FUNCTION__))->typed.type))->base.code) == UNION_TYPE
|| ((enum tree_code) (((contains_struct_check ((op), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3164, __FUNCTION__))->typed.type))->base.code) == QUAL_UNION_TYPE
))
3165 && maybe_gt (size + bitpos,maybe_lt (tree_to_poly_uint64 (((tree_class_check ((((contains_struct_check
((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3166, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3166, __FUNCTION__))->type_common.size)), size + bitpos)
3166 tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (op))))maybe_lt (tree_to_poly_uint64 (((tree_class_check ((((contains_struct_check
((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3166, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3166, __FUNCTION__))->type_common.size)), size + bitpos)
)
3167 {
3168 error ("position plus size exceeds size of referenced object in "
3169 "%qs", code_name);
3170 return true;
3171 }
3172 }
3173
3174 if ((TREE_CODE (expr)((enum tree_code) (expr)->base.code) == REALPART_EXPR
3175 || TREE_CODE (expr)((enum tree_code) (expr)->base.code) == IMAGPART_EXPR)
3176 && !useless_type_conversion_p (TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3176, __FUNCTION__))->typed.type)
,
3177 TREE_TYPE (TREE_TYPE (op))((contains_struct_check ((((contains_struct_check ((op), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3177, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3177, __FUNCTION__))->typed.type)
))
3178 {
3179 error ("type mismatch in %qs reference", code_name);
3180 debug_generic_stmt (TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3180, __FUNCTION__))->typed.type)
);
3181 debug_generic_stmt (TREE_TYPE (TREE_TYPE (op))((contains_struct_check ((((contains_struct_check ((op), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3181, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3181, __FUNCTION__))->typed.type)
);
3182 return true;
3183 }
3184 expr = op;
3185 }
3186
3187 while (handled_component_p (expr))
3188 {
3189 code_name = get_tree_code_name (TREE_CODE (expr)((enum tree_code) (expr)->base.code));
3190
3191 if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == REALPART_EXPR
3192 || TREE_CODE (expr)((enum tree_code) (expr)->base.code) == IMAGPART_EXPR
3193 || TREE_CODE (expr)((enum tree_code) (expr)->base.code) == BIT_FIELD_REF)
3194 {
3195 error ("non-top-level %qs", code_name);
3196 return true;
3197 }
3198
3199 tree op = TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3199, __FUNCTION__)))))
;
3200
3201 if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == ARRAY_REF
3202 || TREE_CODE (expr)((enum tree_code) (expr)->base.code) == ARRAY_RANGE_REF)
3203 {
3204 if (!is_gimple_val (TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3204, __FUNCTION__)))))
)
3205 || (TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3205, __FUNCTION__)))))
3206 && !is_gimple_val (TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3206, __FUNCTION__)))))
))
3207 || (TREE_OPERAND (expr, 3)(*((const_cast<tree*> (tree_operand_check ((expr), (3),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3207, __FUNCTION__)))))
3208 && !is_gimple_val (TREE_OPERAND (expr, 3)(*((const_cast<tree*> (tree_operand_check ((expr), (3),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3208, __FUNCTION__)))))
)))
3209 {
3210 error ("invalid operands to %qs", code_name);
3211 debug_generic_stmt (expr);
3212 return true;
3213 }
3214 }
3215
3216 /* Verify if the reference array element types are compatible. */
3217 if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == ARRAY_REF
3218 && !useless_type_conversion_p (TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3218, __FUNCTION__))->typed.type)
,
3219 TREE_TYPE (TREE_TYPE (op))((contains_struct_check ((((contains_struct_check ((op), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3219, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3219, __FUNCTION__))->typed.type)
))
3220 {
3221 error ("type mismatch in %qs", code_name);
3222 debug_generic_stmt (TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3222, __FUNCTION__))->typed.type)
);
3223 debug_generic_stmt (TREE_TYPE (TREE_TYPE (op))((contains_struct_check ((((contains_struct_check ((op), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3223, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3223, __FUNCTION__))->typed.type)
);
3224 return true;
3225 }
3226 if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == ARRAY_RANGE_REF
3227 && !useless_type_conversion_p (TREE_TYPE (TREE_TYPE (expr))((contains_struct_check ((((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3227, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3227, __FUNCTION__))->typed.type)
,
3228 TREE_TYPE (TREE_TYPE (op))((contains_struct_check ((((contains_struct_check ((op), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3228, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3228, __FUNCTION__))->typed.type)
))
3229 {
3230 error ("type mismatch in %qs", code_name);
3231 debug_generic_stmt (TREE_TYPE (TREE_TYPE (expr))((contains_struct_check ((((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3231, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3231, __FUNCTION__))->typed.type)
);
3232 debug_generic_stmt (TREE_TYPE (TREE_TYPE (op))((contains_struct_check ((((contains_struct_check ((op), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3232, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3232, __FUNCTION__))->typed.type)
);
3233 return true;
3234 }
3235
3236 if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == COMPONENT_REF)
3237 {
3238 if (TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3238, __FUNCTION__)))))
3239 && !is_gimple_val (TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3239, __FUNCTION__)))))
))
3240 {
3241 error ("invalid %qs offset operator", code_name);
3242 return true;
3243 }
3244 if (!useless_type_conversion_p (TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3244, __FUNCTION__))->typed.type)
,
3245 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/tree-cfg.cc"
, 3245, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3245, __FUNCTION__))->typed.type)
))
3246 {
3247 error ("type mismatch in %qs", code_name);
3248 debug_generic_stmt (TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3248, __FUNCTION__))->typed.type)
);
3249 debug_generic_stmt (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/tree-cfg.cc"
, 3249, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3249, __FUNCTION__))->typed.type)
);
3250 return true;
3251 }
3252 }
3253
3254 if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == VIEW_CONVERT_EXPR)
3255 {
3256 /* For VIEW_CONVERT_EXPRs which are allowed here too, we only check
3257 that their operand is not an SSA name or an invariant when
3258 requiring an lvalue (this usually means there is a SRA or IPA-SRA
3259 bug). Otherwise there is nothing to verify, gross mismatches at
3260 most invoke undefined behavior. */
3261 if (require_lvalue
3262 && (TREE_CODE (op)((enum tree_code) (op)->base.code) == SSA_NAME
3263 || is_gimple_min_invariant (op)))
3264 {
3265 error ("conversion of %qs on the left hand side of %qs",
3266 get_tree_code_name (TREE_CODE (op)((enum tree_code) (op)->base.code)), code_name);
3267 debug_generic_stmt (expr);
3268 return true;
3269 }
3270 else if (TREE_CODE (op)((enum tree_code) (op)->base.code) == SSA_NAME
3271 && TYPE_SIZE (TREE_TYPE (expr))((tree_class_check ((((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3271, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3271, __FUNCTION__))->type_common.size)
!= TYPE_SIZE (TREE_TYPE (op))((tree_class_check ((((contains_struct_check ((op), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3271, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3271, __FUNCTION__))->type_common.size)
)
3272 {
3273 error ("conversion of register to a different size in %qs",
3274 code_name);
3275 debug_generic_stmt (expr);
3276 return true;
3277 }
3278 else if (!handled_component_p (op))
3279 return false;
3280 }
3281
3282 expr = op;
3283 }
3284
3285 code_name = get_tree_code_name (TREE_CODE (expr)((enum tree_code) (expr)->base.code));
3286
3287 if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == MEM_REF)
3288 {
3289 if (!is_gimple_mem_ref_addr (TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3289, __FUNCTION__)))))
)
3290 || (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/tree-cfg.cc"
, 3290, __FUNCTION__))))))->base.code)
== ADDR_EXPR
3291 && verify_address (TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3291, __FUNCTION__)))))
, false)))
3292 {
3293 error ("invalid address operand in %qs", code_name);
3294 debug_generic_stmt (expr);
3295 return true;
3296 }
3297 if (!poly_int_tree_p (TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3297, __FUNCTION__)))))
)
3298 || !POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1)))(((enum tree_code) (((contains_struct_check (((*((const_cast<
tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3298, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3298, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check (((*((const_cast
<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3298, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3298, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
)
3299 {
3300 error ("invalid offset operand in %qs", code_name);
3301 debug_generic_stmt (expr);
3302 return true;
3303 }
3304 if (MR_DEPENDENCE_CLIQUE (expr)((tree_check2 ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3304, __FUNCTION__, (MEM_REF), (TARGET_MEM_REF)))->base.
u.dependence_info.clique)
!= 0
3305 && MR_DEPENDENCE_CLIQUE (expr)((tree_check2 ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3305, __FUNCTION__, (MEM_REF), (TARGET_MEM_REF)))->base.
u.dependence_info.clique)
> cfun(cfun + 0)->last_clique)
3306 {
3307 error ("invalid clique in %qs", code_name);
3308 debug_generic_stmt (expr);
3309 return true;
3310 }
3311 }
3312 else if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == TARGET_MEM_REF)
3313 {
3314 if (!TMR_BASE (expr)((*((const_cast<tree*> (tree_operand_check (((tree_check
((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3314, __FUNCTION__, (TARGET_MEM_REF)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3314, __FUNCTION__))))))
3315 || !is_gimple_mem_ref_addr (TMR_BASE (expr)((*((const_cast<tree*> (tree_operand_check (((tree_check
((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3315, __FUNCTION__, (TARGET_MEM_REF)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3315, __FUNCTION__))))))
)
3316 || (TREE_CODE (TMR_BASE (expr))((enum tree_code) (((*((const_cast<tree*> (tree_operand_check
(((tree_check ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3316, __FUNCTION__, (TARGET_MEM_REF)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3316, __FUNCTION__)))))))->base.code)
== ADDR_EXPR
3317 && verify_address (TMR_BASE (expr)((*((const_cast<tree*> (tree_operand_check (((tree_check
((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3317, __FUNCTION__, (TARGET_MEM_REF)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3317, __FUNCTION__))))))
, false)))
3318 {
3319 error ("invalid address operand in %qs", code_name);
3320 return true;
3321 }
3322 if (!TMR_OFFSET (expr)((*((const_cast<tree*> (tree_operand_check (((tree_check
((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3322, __FUNCTION__, (TARGET_MEM_REF)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3322, __FUNCTION__))))))
3323 || !poly_int_tree_p (TMR_OFFSET (expr)((*((const_cast<tree*> (tree_operand_check (((tree_check
((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3323, __FUNCTION__, (TARGET_MEM_REF)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3323, __FUNCTION__))))))
)
3324 || !POINTER_TYPE_P (TREE_TYPE (TMR_OFFSET (expr)))(((enum tree_code) (((contains_struct_check ((((*((const_cast
<tree*> (tree_operand_check (((tree_check ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3324, __FUNCTION__, (TARGET_MEM_REF)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3324, __FUNCTION__))))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3324, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((((*((const_cast
<tree*> (tree_operand_check (((tree_check ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3324, __FUNCTION__, (TARGET_MEM_REF)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3324, __FUNCTION__))))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3324, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
)
3325 {
3326 error ("invalid offset operand in %qs", code_name);
3327 debug_generic_stmt (expr);
3328 return true;
3329 }
3330 if (MR_DEPENDENCE_CLIQUE (expr)((tree_check2 ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3330, __FUNCTION__, (MEM_REF), (TARGET_MEM_REF)))->base.
u.dependence_info.clique)
!= 0
3331 && MR_DEPENDENCE_CLIQUE (expr)((tree_check2 ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3331, __FUNCTION__, (MEM_REF), (TARGET_MEM_REF)))->base.
u.dependence_info.clique)
> cfun(cfun + 0)->last_clique)
3332 {
3333 error ("invalid clique in %qs", code_name);
3334 debug_generic_stmt (expr);
3335 return true;
3336 }
3337 }
3338 else if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == INDIRECT_REF)
3339 {
3340 error ("%qs in gimple IL", code_name);
3341 debug_generic_stmt (expr);
3342 return true;
3343 }
3344
3345 if (!require_lvalue
3346 && (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == SSA_NAME || is_gimple_min_invariant (expr)))
3347 return false;
3348
3349 if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) != SSA_NAME && is_gimple_id (expr))
3350 return false;
3351
3352 if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) != TARGET_MEM_REF
3353 && TREE_CODE (expr)((enum tree_code) (expr)->base.code) != MEM_REF)
3354 {
3355 error ("invalid expression for min lvalue");
3356 return true;
3357 }
3358
3359 return false;
3360}
3361
3362/* Returns true if there is one pointer type in TYPE_POINTER_TO (SRC_OBJ)
3363 list of pointer-to types that is trivially convertible to DEST. */
3364
3365static bool
3366one_pointer_to_useless_type_conversion_p (tree dest, tree src_obj)
3367{
3368 tree src;
3369
3370 if (!TYPE_POINTER_TO (src_obj)((tree_class_check ((src_obj), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3370, __FUNCTION__))->type_common.pointer_to)
)
3371 return true;
3372
3373 for (src = TYPE_POINTER_TO (src_obj)((tree_class_check ((src_obj), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3373, __FUNCTION__))->type_common.pointer_to)
; src; src = TYPE_NEXT_PTR_TO (src)((tree_check ((src), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3373, __FUNCTION__, (POINTER_TYPE)))->type_non_common.minval
)
)
3374 if (useless_type_conversion_p (dest, src))
3375 return true;
3376
3377 return false;
3378}
3379
3380/* Return true if TYPE1 is a fixed-point type and if conversions to and
3381 from TYPE2 can be handled by FIXED_CONVERT_EXPR. */
3382
3383static bool
3384valid_fixed_convert_types_p (tree type1, tree type2)
3385{
3386 return (FIXED_POINT_TYPE_P (type1)(((enum tree_code) (type1)->base.code) == FIXED_POINT_TYPE
)
3387 && (INTEGRAL_TYPE_P (type2)(((enum tree_code) (type2)->base.code) == ENUMERAL_TYPE ||
((enum tree_code) (type2)->base.code) == BOOLEAN_TYPE || (
(enum tree_code) (type2)->base.code) == INTEGER_TYPE)
3388 || SCALAR_FLOAT_TYPE_P (type2)(((enum tree_code) (type2)->base.code) == REAL_TYPE)
3389 || FIXED_POINT_TYPE_P (type2)(((enum tree_code) (type2)->base.code) == FIXED_POINT_TYPE
)
));
3390}
3391
3392/* Verify the contents of a GIMPLE_CALL STMT. Returns true when there
3393 is a problem, otherwise false. */
3394
3395static bool
3396verify_gimple_call (gcall *stmt)
3397{
3398 tree fn = gimple_call_fn (stmt);
3399 tree fntype, fndecl;
3400 unsigned i;
3401
3402 if (gimple_call_internal_p (stmt))
3403 {
3404 if (fn)
3405 {
3406 error ("gimple call has two targets");
3407 debug_generic_stmt (fn);
3408 return true;
3409 }
3410 }
3411 else
3412 {
3413 if (!fn)
3414 {
3415 error ("gimple call has no target");
3416 return true;
3417 }
3418 }
3419
3420 if (fn && !is_gimple_call_addr (fn))
3421 {
3422 error ("invalid function in gimple call");
3423 debug_generic_stmt (fn);
3424 return true;
3425 }
3426
3427 if (fn
3428 && (!POINTER_TYPE_P (TREE_TYPE (fn))(((enum tree_code) (((contains_struct_check ((fn), (TS_TYPED)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3428, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((fn), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3428, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
3429 || (TREE_CODE (TREE_TYPE (TREE_TYPE (fn)))((enum tree_code) (((contains_struct_check ((((contains_struct_check
((fn), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3429, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3429, __FUNCTION__))->typed.type))->base.code)
!= FUNCTION_TYPE
3430 && TREE_CODE (TREE_TYPE (TREE_TYPE (fn)))((enum tree_code) (((contains_struct_check ((((contains_struct_check
((fn), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3430, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3430, __FUNCTION__))->typed.type))->base.code)
!= METHOD_TYPE)))
3431 {
3432 error ("non-function in gimple call");
3433 return true;
3434 }
3435
3436 fndecl = gimple_call_fndecl (stmt);
3437 if (fndecl
3438 && TREE_CODE (fndecl)((enum tree_code) (fndecl)->base.code) == FUNCTION_DECL
3439 && DECL_LOOPING_CONST_OR_PURE_P (fndecl)((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3439, __FUNCTION__, (FUNCTION_DECL)))->function_decl.looping_const_or_pure_flag
)
3440 && !DECL_PURE_P (fndecl)((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3440, __FUNCTION__, (FUNCTION_DECL)))->function_decl.pure_flag
)
3441 && !TREE_READONLY (fndecl)((non_type_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3441, __FUNCTION__))->base.readonly_flag)
)
3442 {
3443 error ("invalid pure const state for function");
3444 return true;
3445 }
3446
3447 tree lhs = gimple_call_lhs (stmt);
3448 if (lhs
3449 && (!is_gimple_reg (lhs)
3450 && (!is_gimple_lvalue (lhs)
3451 || verify_types_in_gimple_reference
3452 (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == WITH_SIZE_EXPR
3453 ? TREE_OPERAND (lhs, 0)(*((const_cast<tree*> (tree_operand_check ((lhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3453, __FUNCTION__)))))
: lhs, true))))
3454 {
3455 error ("invalid LHS in gimple call");
3456 return true;
3457 }
3458
3459 if (gimple_call_ctrl_altering_p (stmt)
3460 && gimple_call_noreturn_p (stmt)
3461 && should_remove_lhs_p (lhs))
3462 {
3463 error ("LHS in %<noreturn%> call");
3464 return true;
3465 }
3466
3467 fntype = gimple_call_fntype (stmt);
3468 if (fntype
3469 && lhs
3470 && !useless_type_conversion_p (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3470, __FUNCTION__))->typed.type)
, TREE_TYPE (fntype)((contains_struct_check ((fntype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3470, __FUNCTION__))->typed.type)
)
3471 /* ??? At least C++ misses conversions at assignments from
3472 void * call results.
3473 For now simply allow arbitrary pointer type conversions. */
3474 && !(POINTER_TYPE_P (TREE_TYPE (lhs))(((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3474, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3474, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
3475 && POINTER_TYPE_P (TREE_TYPE (fntype))(((enum tree_code) (((contains_struct_check ((fntype), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3475, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((fntype), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3475, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
))
3476 {
3477 error ("invalid conversion in gimple call");
3478 debug_generic_stmt (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3478, __FUNCTION__))->typed.type)
);
3479 debug_generic_stmt (TREE_TYPE (fntype)((contains_struct_check ((fntype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3479, __FUNCTION__))->typed.type)
);
3480 return true;
3481 }
3482
3483 if (gimple_call_chain (stmt)
3484 && !is_gimple_val (gimple_call_chain (stmt)))
3485 {
3486 error ("invalid static chain in gimple call");
3487 debug_generic_stmt (gimple_call_chain (stmt));
3488 return true;
3489 }
3490
3491 /* If there is a static chain argument, the call should either be
3492 indirect, or the decl should have DECL_STATIC_CHAIN set. */
3493 if (gimple_call_chain (stmt)
3494 && fndecl
3495 && !DECL_STATIC_CHAIN (fndecl)((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3495, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.regdecl_flag
)
)
3496 {
3497 error ("static chain with function that doesn%'t use one");
3498 return true;
3499 }
3500
3501 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3502 {
3503 switch (DECL_FUNCTION_CODE (fndecl))
3504 {
3505 case BUILT_IN_UNREACHABLE:
3506 case BUILT_IN_UNREACHABLE_TRAP:
3507 case BUILT_IN_TRAP:
3508 if (gimple_call_num_args (stmt) > 0)
3509 {
3510 /* Built-in unreachable with parameters might not be caught by
3511 undefined behavior sanitizer. Front-ends do check users do not
3512 call them that way but we also produce calls to
3513 __builtin_unreachable internally, for example when IPA figures
3514 out a call cannot happen in a legal program. In such cases,
3515 we must make sure arguments are stripped off. */
3516 error ("%<__builtin_unreachable%> or %<__builtin_trap%> call "
3517 "with arguments");
3518 return true;
3519 }
3520 break;
3521 default:
3522 break;
3523 }
3524 }
3525
3526 /* For a call to .DEFERRED_INIT,
3527 LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL)
3528 we should guarantee that when the 1st argument is a constant, it should
3529 be the same as the size of the LHS. */
3530
3531 if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
3532 {
3533 tree size_of_arg0 = gimple_call_arg (stmt, 0);
3534 tree size_of_lhs = TYPE_SIZE_UNIT (TREE_TYPE (lhs))((tree_class_check ((((contains_struct_check ((lhs), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3534, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3534, __FUNCTION__))->type_common.size_unit)
;
3535
3536 if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == SSA_NAME)
3537 lhs = SSA_NAME_VAR (lhs)((tree_check ((lhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3537, __FUNCTION__, (SSA_NAME)))->ssa_name.var == (tree)
nullptr || ((enum tree_code) ((lhs)->ssa_name.var)->base
.code) == IDENTIFIER_NODE ? (tree) nullptr : (lhs)->ssa_name
.var)
;
Value stored to 'lhs' is never read
3538
3539 poly_uint64 size_from_arg0, size_from_lhs;
3540 bool is_constant_size_arg0 = poly_int_tree_p (size_of_arg0,
3541 &size_from_arg0);
3542 bool is_constant_size_lhs = poly_int_tree_p (size_of_lhs,
3543 &size_from_lhs);
3544 if (is_constant_size_arg0 && is_constant_size_lhs)
3545 if (maybe_ne (size_from_arg0, size_from_lhs))
3546 {
3547 error ("%<DEFERRED_INIT%> calls should have same "
3548 "constant size for the first argument and LHS");
3549 return true;
3550 }
3551 }
3552
3553 /* ??? The C frontend passes unpromoted arguments in case it
3554 didn't see a function declaration before the call. So for now
3555 leave the call arguments mostly unverified. Once we gimplify
3556 unit-at-a-time we have a chance to fix this. */
3557 for (i = 0; i < gimple_call_num_args (stmt); ++i)
3558 {
3559 tree arg = gimple_call_arg (stmt, i);
3560 if ((is_gimple_reg_type (TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3560, __FUNCTION__))->typed.type)
)
3561 && !is_gimple_val (arg))
3562 || (!is_gimple_reg_type (TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3562, __FUNCTION__))->typed.type)
)
3563 && !is_gimple_lvalue (arg)))
3564 {
3565 error ("invalid argument to gimple call");
3566 debug_generic_expr (arg);
3567 return true;
3568 }
3569 if (!is_gimple_reg (arg))
3570 {
3571 if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == WITH_SIZE_EXPR)
3572 arg = TREE_OPERAND (arg, 0)(*((const_cast<tree*> (tree_operand_check ((arg), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3572, __FUNCTION__)))))
;
3573 if (verify_types_in_gimple_reference (arg, false))
3574 return true;
3575 }
3576 }
3577
3578 return false;
3579}
3580
3581/* Verifies the gimple comparison with the result type TYPE and
3582 the operands OP0 and OP1, comparison code is CODE. */
3583
3584static bool
3585verify_gimple_comparison (tree type, tree op0, tree op1, enum tree_code code)
3586{
3587 tree op0_type = TREE_TYPE (op0)((contains_struct_check ((op0), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3587, __FUNCTION__))->typed.type)
;
3588 tree op1_type = TREE_TYPE (op1)((contains_struct_check ((op1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3588, __FUNCTION__))->typed.type)
;
3589
3590 if (!is_gimple_val (op0) || !is_gimple_val (op1))
3591 {
3592 error ("invalid operands in gimple comparison");
3593 return true;
3594 }
3595
3596 /* For comparisons we do not have the operations type as the
3597 effective type the comparison is carried out in. Instead
3598 we require that either the first operand is trivially
3599 convertible into the second, or the other way around. */
3600 if (!useless_type_conversion_p (op0_type, op1_type)
3601 && !useless_type_conversion_p (op1_type, op0_type))
3602 {
3603 error ("mismatching comparison operand types");
3604 debug_generic_expr (op0_type);
3605 debug_generic_expr (op1_type);
3606 return true;
3607 }
3608
3609 /* The resulting type of a comparison may be an effective boolean type. */
3610 if (INTEGRAL_TYPE_P (type)(((enum tree_code) (type)->base.code) == ENUMERAL_TYPE || (
(enum tree_code) (type)->base.code) == BOOLEAN_TYPE || ((enum
tree_code) (type)->base.code) == INTEGER_TYPE)
3611 && (TREE_CODE (type)((enum tree_code) (type)->base.code) == BOOLEAN_TYPE
3612 || TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3612, __FUNCTION__))->type_common.precision)
== 1))
3613 {
3614 if ((TREE_CODE (op0_type)((enum tree_code) (op0_type)->base.code) == VECTOR_TYPE
3615 || TREE_CODE (op1_type)((enum tree_code) (op1_type)->base.code) == VECTOR_TYPE)
3616 && code != EQ_EXPR && code != NE_EXPR
3617 && !VECTOR_BOOLEAN_TYPE_P (op0_type)(((enum tree_code) (op0_type)->base.code) == VECTOR_TYPE &&
((enum tree_code) (((contains_struct_check ((op0_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3617, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
)
3618 && !VECTOR_INTEGER_TYPE_P (op0_type)((((enum tree_code) (op0_type)->base.code) == VECTOR_TYPE)
&& ((enum tree_code) (((contains_struct_check ((op0_type
), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3618, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
)
3619 {
3620 error ("unsupported operation or type for vector comparison"
3621 " returning a boolean");
3622 debug_generic_expr (op0_type);
3623 debug_generic_expr (op1_type);
3624 return true;
3625 }
3626 }
3627 /* Or a boolean vector type with the same element count
3628 as the comparison operand types. */
3629 else if (TREE_CODE (type)((enum tree_code) (type)->base.code) == VECTOR_TYPE
3630 && TREE_CODE (TREE_TYPE (type))((enum tree_code) (((contains_struct_check ((type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3630, __FUNCTION__))->typed.type))->base.code)
== BOOLEAN_TYPE)
3631 {
3632 if (TREE_CODE (op0_type)((enum tree_code) (op0_type)->base.code) != VECTOR_TYPE
3633 || TREE_CODE (op1_type)((enum tree_code) (op1_type)->base.code) != VECTOR_TYPE)
3634 {
3635 error ("non-vector operands in vector comparison");
3636 debug_generic_expr (op0_type);
3637 debug_generic_expr (op1_type);
3638 return true;
3639 }
3640
3641 if (maybe_ne (TYPE_VECTOR_SUBPARTS (type),
3642 TYPE_VECTOR_SUBPARTS (op0_type)))
3643 {
3644 error ("invalid vector comparison resulting type");
3645 debug_generic_expr (type);
3646 return true;
3647 }
3648 }
3649 else
3650 {
3651 error ("bogus comparison result type");
3652 debug_generic_expr (type);
3653 return true;
3654 }
3655
3656 return false;
3657}
3658
3659/* Verify a gimple assignment statement STMT with an unary rhs.
3660 Returns true if anything is wrong. */
3661
3662static bool
3663verify_gimple_assign_unary (gassign *stmt)
3664{
3665 enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
3666 tree lhs = gimple_assign_lhs (stmt);
3667 tree lhs_type = TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3667, __FUNCTION__))->typed.type)
;
3668 tree rhs1 = gimple_assign_rhs1 (stmt);
3669 tree rhs1_type = TREE_TYPE (rhs1)((contains_struct_check ((rhs1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3669, __FUNCTION__))->typed.type)
;
3670
3671 if (!is_gimple_reg (lhs))
3672 {
3673 error ("non-register as LHS of unary operation");
3674 return true;
3675 }
3676
3677 if (!is_gimple_val (rhs1))
3678 {
3679 error ("invalid operand in unary operation");
3680 return true;
3681 }
3682
3683 const char* const code_name = get_tree_code_name (rhs_code);
3684
3685 /* First handle conversions. */
3686 switch (rhs_code)
3687 {
3688 CASE_CONVERTcase NOP_EXPR: case CONVERT_EXPR:
3689 {
3690 /* Allow conversions between vectors with the same number of elements,
3691 provided that the conversion is OK for the element types too. */
3692 if (VECTOR_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == VECTOR_TYPE)
3693 && VECTOR_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE)
3694 && known_eq (TYPE_VECTOR_SUBPARTS (lhs_type),(!maybe_ne (TYPE_VECTOR_SUBPARTS (lhs_type), TYPE_VECTOR_SUBPARTS
(rhs1_type)))
3695 TYPE_VECTOR_SUBPARTS (rhs1_type))(!maybe_ne (TYPE_VECTOR_SUBPARTS (lhs_type), TYPE_VECTOR_SUBPARTS
(rhs1_type)))
)
3696 {
3697 lhs_type = TREE_TYPE (lhs_type)((contains_struct_check ((lhs_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3697, __FUNCTION__))->typed.type)
;
3698 rhs1_type = TREE_TYPE (rhs1_type)((contains_struct_check ((rhs1_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3698, __FUNCTION__))->typed.type)
;
3699 }
3700 else if (VECTOR_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == VECTOR_TYPE) || VECTOR_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE))
3701 {
3702 error ("invalid vector types in nop conversion");
3703 debug_generic_expr (lhs_type);
3704 debug_generic_expr (rhs1_type);
3705 return true;
3706 }
3707
3708 /* Allow conversions from pointer type to integral type only if
3709 there is no sign or zero extension involved.
3710 For targets were the precision of ptrofftype doesn't match that
3711 of pointers we allow conversions to types where
3712 POINTERS_EXTEND_UNSIGNED specifies how that works. */
3713 if ((POINTER_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == POINTER_TYPE ||
((enum tree_code) (lhs_type)->base.code) == REFERENCE_TYPE
)
3714 && INTEGRAL_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
)
)
3715 || (POINTER_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == POINTER_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == REFERENCE_TYPE
)
3716 && INTEGRAL_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == INTEGER_TYPE
)
3717 && (TYPE_PRECISION (rhs1_type)((tree_class_check ((rhs1_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3717, __FUNCTION__))->type_common.precision)
>= TYPE_PRECISION (lhs_type)((tree_class_check ((lhs_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3717, __FUNCTION__))->type_common.precision)
3718#if defined(POINTERS_EXTEND_UNSIGNED1)
3719 || (TYPE_MODE (rhs1_type)((((enum tree_code) ((tree_class_check ((rhs1_type), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3719, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(rhs1_type) : (rhs1_type)->type_common.mode)
== ptr_mode
3720 && (TYPE_PRECISION (lhs_type)((tree_class_check ((lhs_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3720, __FUNCTION__))->type_common.precision)
3721 == BITS_PER_WORD((8) * (((global_options.x_ix86_isa_flags & (1UL <<
1)) != 0) ? 8 : 4))
/* word_mode */
3722 || (TYPE_PRECISION (lhs_type)((tree_class_check ((lhs_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3722, __FUNCTION__))->type_common.precision)
3723 == GET_MODE_PRECISION (Pmode(global_options.x_ix86_pmode == PMODE_DI ? (scalar_int_mode (
(scalar_int_mode::from_int) E_DImode)) : (scalar_int_mode ((scalar_int_mode
::from_int) E_SImode)))
))))
3724#endif
3725 )))
3726 return false;
3727
3728 /* Allow conversion from integral to offset type and vice versa. */
3729 if ((TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) == OFFSET_TYPE
3730 && INTEGRAL_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
)
)
3731 || (INTEGRAL_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == INTEGER_TYPE
)
3732 && TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) == OFFSET_TYPE))
3733 return false;
3734
3735 /* Otherwise assert we are converting between types of the
3736 same kind. */
3737 if (INTEGRAL_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == INTEGER_TYPE
)
!= INTEGRAL_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
)
)
3738 {
3739 error ("invalid types in nop conversion");
3740 debug_generic_expr (lhs_type);
3741 debug_generic_expr (rhs1_type);
3742 return true;
3743 }
3744
3745 return false;
3746 }
3747
3748 case ADDR_SPACE_CONVERT_EXPR:
3749 {
3750 if (!POINTER_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == POINTER_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == REFERENCE_TYPE
)
|| !POINTER_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == POINTER_TYPE ||
((enum tree_code) (lhs_type)->base.code) == REFERENCE_TYPE
)
3751 || (TYPE_ADDR_SPACE (TREE_TYPE (rhs1_type))((tree_class_check ((((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3751, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3751, __FUNCTION__))->base.u.bits.address_space)
3752 == TYPE_ADDR_SPACE (TREE_TYPE (lhs_type))((tree_class_check ((((contains_struct_check ((lhs_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3752, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3752, __FUNCTION__))->base.u.bits.address_space)
))
3753 {
3754 error ("invalid types in address space conversion");
3755 debug_generic_expr (lhs_type);
3756 debug_generic_expr (rhs1_type);
3757 return true;
3758 }
3759
3760 return false;
3761 }
3762
3763 case FIXED_CONVERT_EXPR:
3764 {
3765 if (!valid_fixed_convert_types_p (lhs_type, rhs1_type)
3766 && !valid_fixed_convert_types_p (rhs1_type, lhs_type))
3767 {
3768 error ("invalid types in fixed-point conversion");
3769 debug_generic_expr (lhs_type);
3770 debug_generic_expr (rhs1_type);
3771 return true;
3772 }
3773
3774 return false;
3775 }
3776
3777 case FLOAT_EXPR:
3778 {
3779 if ((!INTEGRAL_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
)
|| !SCALAR_FLOAT_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == REAL_TYPE))
3780 && (!VECTOR_INTEGER_TYPE_P (rhs1_type)((((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE
) && ((enum tree_code) (((contains_struct_check ((rhs1_type
), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3780, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
3781 || !VECTOR_FLOAT_TYPE_P (lhs_type)((((enum tree_code) (lhs_type)->base.code) == VECTOR_TYPE)
&& ((enum tree_code) (((contains_struct_check ((lhs_type
), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3781, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE
)
))
3782 {
3783 error ("invalid types in conversion to floating-point");
3784 debug_generic_expr (lhs_type);
3785 debug_generic_expr (rhs1_type);
3786 return true;
3787 }
3788
3789 return false;
3790 }
3791
3792 case FIX_TRUNC_EXPR:
3793 {
3794 if ((!INTEGRAL_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == INTEGER_TYPE
)
|| !SCALAR_FLOAT_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == REAL_TYPE))
3795 && (!VECTOR_INTEGER_TYPE_P (lhs_type)((((enum tree_code) (lhs_type)->base.code) == VECTOR_TYPE)
&& ((enum tree_code) (((contains_struct_check ((lhs_type
), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3795, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
3796 || !VECTOR_FLOAT_TYPE_P (rhs1_type)((((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE
) && ((enum tree_code) (((contains_struct_check ((rhs1_type
), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3796, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE
)
))
3797 {
3798 error ("invalid types in conversion to integer");
3799 debug_generic_expr (lhs_type);
3800 debug_generic_expr (rhs1_type);
3801 return true;
3802 }
3803
3804 return false;
3805 }
3806
3807 case VEC_UNPACK_HI_EXPR:
3808 case VEC_UNPACK_LO_EXPR:
3809 case VEC_UNPACK_FLOAT_HI_EXPR:
3810 case VEC_UNPACK_FLOAT_LO_EXPR:
3811 case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
3812 case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
3813 if (TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) != VECTOR_TYPE
3814 || TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) != VECTOR_TYPE
3815 || (!INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))(((enum tree_code) (((contains_struct_check ((lhs_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3815, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3815, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3815, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
3816 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type))(((enum tree_code) (((contains_struct_check ((lhs_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3816, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE
)
)
3817 || (!INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))(((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3817, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3817, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3817, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
3818 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type))(((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3818, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE
)
)
3819 || ((rhs_code == VEC_UNPACK_HI_EXPR
3820 || rhs_code == VEC_UNPACK_LO_EXPR)
3821 && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))(((enum tree_code) (((contains_struct_check ((lhs_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3821, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3821, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3821, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
3822 != INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))(((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3822, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3822, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3822, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
))
3823 || ((rhs_code == VEC_UNPACK_FLOAT_HI_EXPR
3824 || rhs_code == VEC_UNPACK_FLOAT_LO_EXPR)
3825 && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))(((enum tree_code) (((contains_struct_check ((lhs_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3825, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3825, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3825, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
3826 || SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type))(((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3826, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE
)
))
3827 || ((rhs_code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
3828 || rhs_code == VEC_UNPACK_FIX_TRUNC_LO_EXPR)
3829 && (INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))(((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3829, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3829, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3829, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
3830 || SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type))(((enum tree_code) (((contains_struct_check ((lhs_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3830, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE
)
))
3831 || (maybe_ne (GET_MODE_SIZE (element_mode (lhs_type)),
3832 2 * GET_MODE_SIZE (element_mode (rhs1_type)))
3833 && (!VECTOR_BOOLEAN_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == VECTOR_TYPE &&
((enum tree_code) (((contains_struct_check ((lhs_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3833, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
)
3834 || !VECTOR_BOOLEAN_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE &&
((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3834, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
)
))
3835 || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (lhs_type),
3836 TYPE_VECTOR_SUBPARTS (rhs1_type)))
3837 {
3838 error ("type mismatch in %qs expression", code_name);
3839 debug_generic_expr (lhs_type);
3840 debug_generic_expr (rhs1_type);
3841 return true;
3842 }
3843
3844 return false;
3845
3846 case NEGATE_EXPR:
3847 case ABS_EXPR:
3848 case BIT_NOT_EXPR:
3849 case PAREN_EXPR:
3850 case CONJ_EXPR:
3851 /* Disallow pointer and offset types for many of the unary gimple. */
3852 if (POINTER_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == POINTER_TYPE ||
((enum tree_code) (lhs_type)->base.code) == REFERENCE_TYPE
)
3853 || TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) == OFFSET_TYPE)
3854 {
3855 error ("invalid types for %qs", code_name);
3856 debug_generic_expr (lhs_type);
3857 debug_generic_expr (rhs1_type);
3858 return true;
3859 }
3860 break;
3861
3862 case ABSU_EXPR:
3863 if (!ANY_INTEGRAL_TYPE_P (lhs_type)((((enum tree_code) (lhs_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == INTEGER_TYPE
) || ((((enum tree_code) (lhs_type)->base.code) == COMPLEX_TYPE
|| (((enum tree_code) (lhs_type)->base.code) == VECTOR_TYPE
)) && (((enum tree_code) (((contains_struct_check ((lhs_type
), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3863, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3863, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3863, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)))
3864 || !TYPE_UNSIGNED (lhs_type)((tree_class_check ((lhs_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3864, __FUNCTION__))->base.u.bits.unsigned_flag)
3865 || !ANY_INTEGRAL_TYPE_P (rhs1_type)((((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
) || ((((enum tree_code) (rhs1_type)->base.code) == COMPLEX_TYPE
|| (((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE
)) && (((enum tree_code) (((contains_struct_check ((rhs1_type
), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3865, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3865, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3865, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)))
3866 || TYPE_UNSIGNED (rhs1_type)((tree_class_check ((rhs1_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3866, __FUNCTION__))->base.u.bits.unsigned_flag)
3867 || element_precision (lhs_type) != element_precision (rhs1_type))
3868 {
3869 error ("invalid types for %qs", code_name);
3870 debug_generic_expr (lhs_type);
3871 debug_generic_expr (rhs1_type);
3872 return true;
3873 }
3874 return false;
3875
3876 case VEC_DUPLICATE_EXPR:
3877 if (TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) != VECTOR_TYPE
3878 || !useless_type_conversion_p (TREE_TYPE (lhs_type)((contains_struct_check ((lhs_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3878, __FUNCTION__))->typed.type)
, rhs1_type))
3879 {
3880 error ("%qs should be from a scalar to a like vector", code_name);
3881 debug_generic_expr (lhs_type);
3882 debug_generic_expr (rhs1_type);
3883 return true;
3884 }
3885 return false;
3886
3887 default:
3888 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3888, __FUNCTION__))
;
3889 }
3890
3891 /* For the remaining codes assert there is no conversion involved. */
3892 if (!useless_type_conversion_p (lhs_type, rhs1_type))
3893 {
3894 error ("non-trivial conversion in unary operation");
3895 debug_generic_expr (lhs_type);
3896 debug_generic_expr (rhs1_type);
3897 return true;
3898 }
3899
3900 return false;
3901}
3902
3903/* Verify a gimple assignment statement STMT with a binary rhs.
3904 Returns true if anything is wrong. */
3905
3906static bool
3907verify_gimple_assign_binary (gassign *stmt)
3908{
3909 enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
3910 tree lhs = gimple_assign_lhs (stmt);
3911 tree lhs_type = TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3911, __FUNCTION__))->typed.type)
;
3912 tree rhs1 = gimple_assign_rhs1 (stmt);
3913 tree rhs1_type = TREE_TYPE (rhs1)((contains_struct_check ((rhs1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3913, __FUNCTION__))->typed.type)
;
3914 tree rhs2 = gimple_assign_rhs2 (stmt);
3915 tree rhs2_type = TREE_TYPE (rhs2)((contains_struct_check ((rhs2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3915, __FUNCTION__))->typed.type)
;
3916
3917 if (!is_gimple_reg (lhs))
3918 {
3919 error ("non-register as LHS of binary operation");
3920 return true;
3921 }
3922
3923 if (!is_gimple_val (rhs1)
3924 || !is_gimple_val (rhs2))
3925 {
3926 error ("invalid operands in binary operation");
3927 return true;
3928 }
3929
3930 const char* const code_name = get_tree_code_name (rhs_code);
3931
3932 /* First handle operations that involve different types. */
3933 switch (rhs_code)
3934 {
3935 case COMPLEX_EXPR:
3936 {
3937 if (TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) != COMPLEX_TYPE
3938 || !(INTEGRAL_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
)
3939 || SCALAR_FLOAT_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == REAL_TYPE))
3940 || !(INTEGRAL_TYPE_P (rhs2_type)(((enum tree_code) (rhs2_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs2_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs2_type)->base.code) == INTEGER_TYPE
)
3941 || SCALAR_FLOAT_TYPE_P (rhs2_type)(((enum tree_code) (rhs2_type)->base.code) == REAL_TYPE)))
3942 {
3943 error ("type mismatch in %qs", code_name);
3944 debug_generic_expr (lhs_type);
3945 debug_generic_expr (rhs1_type);
3946 debug_generic_expr (rhs2_type);
3947 return true;
3948 }
3949
3950 return false;
3951 }
3952
3953 case LSHIFT_EXPR:
3954 case RSHIFT_EXPR:
3955 case LROTATE_EXPR:
3956 case RROTATE_EXPR:
3957 {
3958 /* Shifts and rotates are ok on integral types, fixed point
3959 types and integer vector types. */
3960 if ((!INTEGRAL_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
)
3961 && !FIXED_POINT_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == FIXED_POINT_TYPE
)
3962 && !(TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE
3963 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))(((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3963, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3963, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3963, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
))
3964 || (!INTEGRAL_TYPE_P (rhs2_type)(((enum tree_code) (rhs2_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs2_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs2_type)->base.code) == INTEGER_TYPE
)
3965 /* Vector shifts of vectors are also ok. */
3966 && !(TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE
3967 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))(((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3967, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3967, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3967, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
3968 && TREE_CODE (rhs2_type)((enum tree_code) (rhs2_type)->base.code) == VECTOR_TYPE
3969 && INTEGRAL_TYPE_P (TREE_TYPE (rhs2_type))(((enum tree_code) (((contains_struct_check ((rhs2_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3969, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs2_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3969, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs2_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3969, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
))
3970 || !useless_type_conversion_p (lhs_type, rhs1_type))
3971 {
3972 error ("type mismatch in %qs", code_name);
3973 debug_generic_expr (lhs_type);
3974 debug_generic_expr (rhs1_type);
3975 debug_generic_expr (rhs2_type);
3976 return true;
3977 }
3978
3979 return false;
3980 }
3981
3982 case WIDEN_LSHIFT_EXPR:
3983 {
3984 if (!INTEGRAL_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == INTEGER_TYPE
)
3985 || !INTEGRAL_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
)
3986 || TREE_CODE (rhs2)((enum tree_code) (rhs2)->base.code) != INTEGER_CST
3987 || (2 * TYPE_PRECISION (rhs1_type)((tree_class_check ((rhs1_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3987, __FUNCTION__))->type_common.precision)
> TYPE_PRECISION (lhs_type)((tree_class_check ((lhs_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 3987, __FUNCTION__))->type_common.precision)
))
3988 {
3989 error ("type mismatch in %qs", code_name);
3990 debug_generic_expr (lhs_type);
3991 debug_generic_expr (rhs1_type);
3992 debug_generic_expr (rhs2_type);
3993 return true;
3994 }
3995
3996 return false;
3997 }
3998
3999 case VEC_WIDEN_LSHIFT_HI_EXPR:
4000 case VEC_WIDEN_LSHIFT_LO_EXPR:
4001 {
4002 if (TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) != VECTOR_TYPE
4003 || TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) != VECTOR_TYPE
4004 || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))(((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4004, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4004, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4004, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
4005 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))(((enum tree_code) (((contains_struct_check ((lhs_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4005, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4005, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4005, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
4006 || TREE_CODE (rhs2)((enum tree_code) (rhs2)->base.code) != INTEGER_CST
4007 || (2 * TYPE_PRECISION (TREE_TYPE (rhs1_type))((tree_class_check ((((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4007, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4007, __FUNCTION__))->type_common.precision)
4008 > TYPE_PRECISION (TREE_TYPE (lhs_type))((tree_class_check ((((contains_struct_check ((lhs_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4008, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4008, __FUNCTION__))->type_common.precision)
))
4009 {
4010 error ("type mismatch in %qs", code_name);
4011 debug_generic_expr (lhs_type);
4012 debug_generic_expr (rhs1_type);
4013 debug_generic_expr (rhs2_type);
4014 return true;
4015 }
4016
4017 return false;
4018 }
4019
4020 case WIDEN_PLUS_EXPR:
4021 case WIDEN_MINUS_EXPR:
4022 case PLUS_EXPR:
4023 case MINUS_EXPR:
4024 {
4025 tree lhs_etype = lhs_type;
4026 tree rhs1_etype = rhs1_type;
4027 tree rhs2_etype = rhs2_type;
4028 if (TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) == VECTOR_TYPE)
4029 {
4030 if (TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) != VECTOR_TYPE
4031 || TREE_CODE (rhs2_type)((enum tree_code) (rhs2_type)->base.code) != VECTOR_TYPE)
4032 {
4033 error ("invalid non-vector operands to %qs", code_name);
4034 return true;
4035 }
4036 lhs_etype = TREE_TYPE (lhs_type)((contains_struct_check ((lhs_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4036, __FUNCTION__))->typed.type)
;
4037 rhs1_etype = TREE_TYPE (rhs1_type)((contains_struct_check ((rhs1_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4037, __FUNCTION__))->typed.type)
;
4038 rhs2_etype = TREE_TYPE (rhs2_type)((contains_struct_check ((rhs2_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4038, __FUNCTION__))->typed.type)
;
4039 }
4040 if (POINTER_TYPE_P (lhs_etype)(((enum tree_code) (lhs_etype)->base.code) == POINTER_TYPE
|| ((enum tree_code) (lhs_etype)->base.code) == REFERENCE_TYPE
)
4041 || POINTER_TYPE_P (rhs1_etype)(((enum tree_code) (rhs1_etype)->base.code) == POINTER_TYPE
|| ((enum tree_code) (rhs1_etype)->base.code) == REFERENCE_TYPE
)
4042 || POINTER_TYPE_P (rhs2_etype)(((enum tree_code) (rhs2_etype)->base.code) == POINTER_TYPE
|| ((enum tree_code) (rhs2_etype)->base.code) == REFERENCE_TYPE
)
)
4043 {
4044 error ("invalid (pointer) operands %qs", code_name);
4045 return true;
4046 }
4047
4048 /* Continue with generic binary expression handling. */
4049 break;
4050 }
4051
4052 case POINTER_PLUS_EXPR:
4053 {
4054 if (!POINTER_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == POINTER_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == REFERENCE_TYPE
)
4055 || !useless_type_conversion_p (lhs_type, rhs1_type)
4056 || !ptrofftype_p (rhs2_type))
4057 {
4058 error ("type mismatch in %qs", code_name);
4059 debug_generic_stmt (lhs_type);
4060 debug_generic_stmt (rhs1_type);
4061 debug_generic_stmt (rhs2_type);
4062 return true;
4063 }
4064
4065 return false;
4066 }
4067
4068 case POINTER_DIFF_EXPR:
4069 {
4070 if (!POINTER_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == POINTER_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == REFERENCE_TYPE
)
4071 || !POINTER_TYPE_P (rhs2_type)(((enum tree_code) (rhs2_type)->base.code) == POINTER_TYPE
|| ((enum tree_code) (rhs2_type)->base.code) == REFERENCE_TYPE
)
4072 /* Because we special-case pointers to void we allow difference
4073 of arbitrary pointers with the same mode. */
4074 || TYPE_MODE (rhs1_type)((((enum tree_code) ((tree_class_check ((rhs1_type), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4074, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(rhs1_type) : (rhs1_type)->type_common.mode)
!= TYPE_MODE (rhs2_type)((((enum tree_code) ((tree_class_check ((rhs2_type), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4074, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(rhs2_type) : (rhs2_type)->type_common.mode)
4075 || !INTEGRAL_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == INTEGER_TYPE
)
4076 || TYPE_UNSIGNED (lhs_type)((tree_class_check ((lhs_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4076, __FUNCTION__))->base.u.bits.unsigned_flag)
4077 || TYPE_PRECISION (lhs_type)((tree_class_check ((lhs_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4077, __FUNCTION__))->type_common.precision)
!= TYPE_PRECISION (rhs1_type)((tree_class_check ((rhs1_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4077, __FUNCTION__))->type_common.precision)
)
4078 {
4079 error ("type mismatch in %qs", code_name);
4080 debug_generic_stmt (lhs_type);
4081 debug_generic_stmt (rhs1_type);
4082 debug_generic_stmt (rhs2_type);
4083 return true;
4084 }
4085
4086 return false;
4087 }
4088
4089 case TRUTH_ANDIF_EXPR:
4090 case TRUTH_ORIF_EXPR:
4091 case TRUTH_AND_EXPR:
4092 case TRUTH_OR_EXPR:
4093 case TRUTH_XOR_EXPR:
4094
4095 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4095, __FUNCTION__))
;
4096
4097 case LT_EXPR:
4098 case LE_EXPR:
4099 case GT_EXPR:
4100 case GE_EXPR:
4101 case EQ_EXPR:
4102 case NE_EXPR:
4103 case UNORDERED_EXPR:
4104 case ORDERED_EXPR:
4105 case UNLT_EXPR:
4106 case UNLE_EXPR:
4107 case UNGT_EXPR:
4108 case UNGE_EXPR:
4109 case UNEQ_EXPR:
4110 case LTGT_EXPR:
4111 /* Comparisons are also binary, but the result type is not
4112 connected to the operand types. */
4113 return verify_gimple_comparison (lhs_type, rhs1, rhs2, rhs_code);
4114
4115 case WIDEN_MULT_EXPR:
4116 if (TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) != INTEGER_TYPE)
4117 return true;
4118 return ((2 * TYPE_PRECISION (rhs1_type)((tree_class_check ((rhs1_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4118, __FUNCTION__))->type_common.precision)
> TYPE_PRECISION (lhs_type)((tree_class_check ((lhs_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4118, __FUNCTION__))->type_common.precision)
)
4119 || (TYPE_PRECISION (rhs1_type)((tree_class_check ((rhs1_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4119, __FUNCTION__))->type_common.precision)
!= TYPE_PRECISION (rhs2_type)((tree_class_check ((rhs2_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4119, __FUNCTION__))->type_common.precision)
));
4120
4121 case WIDEN_SUM_EXPR:
4122 {
4123 if (((TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) != VECTOR_TYPE
4124 || TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) != VECTOR_TYPE)
4125 && ((!INTEGRAL_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
)
4126 && !SCALAR_FLOAT_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == REAL_TYPE))
4127 || (!INTEGRAL_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == INTEGER_TYPE
)
4128 && !SCALAR_FLOAT_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == REAL_TYPE))))
4129 || !useless_type_conversion_p (lhs_type, rhs2_type)
4130 || maybe_lt (GET_MODE_SIZE (element_mode (rhs2_type)),
4131 2 * GET_MODE_SIZE (element_mode (rhs1_type))))
4132 {
4133 error ("type mismatch in %qs", code_name);
4134 debug_generic_expr (lhs_type);
4135 debug_generic_expr (rhs1_type);
4136 debug_generic_expr (rhs2_type);
4137 return true;
4138 }
4139 return false;
4140 }
4141
4142 case VEC_WIDEN_MINUS_HI_EXPR:
4143 case VEC_WIDEN_MINUS_LO_EXPR:
4144 case VEC_WIDEN_PLUS_HI_EXPR:
4145 case VEC_WIDEN_PLUS_LO_EXPR:
4146 case VEC_WIDEN_MULT_HI_EXPR:
4147 case VEC_WIDEN_MULT_LO_EXPR:
4148 case VEC_WIDEN_MULT_EVEN_EXPR:
4149 case VEC_WIDEN_MULT_ODD_EXPR:
4150 {
4151 if (TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) != VECTOR_TYPE
4152 || TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) != VECTOR_TYPE
4153 || !types_compatible_p (rhs1_type, rhs2_type)
4154 || maybe_ne (GET_MODE_SIZE (element_mode (lhs_type)),
4155 2 * GET_MODE_SIZE (element_mode (rhs1_type))))
4156 {
4157 error ("type mismatch in %qs", code_name);
4158 debug_generic_expr (lhs_type);
4159 debug_generic_expr (rhs1_type);
4160 debug_generic_expr (rhs2_type);
4161 return true;
4162 }
4163 return false;
4164 }
4165
4166 case VEC_PACK_TRUNC_EXPR:
4167 /* ??? We currently use VEC_PACK_TRUNC_EXPR to simply concat
4168 vector boolean types. */
4169 if (VECTOR_BOOLEAN_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == VECTOR_TYPE &&
((enum tree_code) (((contains_struct_check ((lhs_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4169, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
)
4170 && VECTOR_BOOLEAN_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE &&
((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4170, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
)
4171 && types_compatible_p (rhs1_type, rhs2_type)
4172 && known_eq (TYPE_VECTOR_SUBPARTS (lhs_type),(!maybe_ne (TYPE_VECTOR_SUBPARTS (lhs_type), 2 * TYPE_VECTOR_SUBPARTS
(rhs1_type)))
4173 2 * TYPE_VECTOR_SUBPARTS (rhs1_type))(!maybe_ne (TYPE_VECTOR_SUBPARTS (lhs_type), 2 * TYPE_VECTOR_SUBPARTS
(rhs1_type)))
)
4174 return false;
4175
4176 /* Fallthru. */
4177 case VEC_PACK_SAT_EXPR:
4178 case VEC_PACK_FIX_TRUNC_EXPR:
4179 {
4180 if (TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) != VECTOR_TYPE
4181 || TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) != VECTOR_TYPE
4182 || !((rhs_code == VEC_PACK_FIX_TRUNC_EXPR
4183 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type))(((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4183, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE
)
4184 && INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))(((enum tree_code) (((contains_struct_check ((lhs_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4184, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4184, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4184, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
)
4185 || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))(((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4185, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4185, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4185, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
4186 == INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))(((enum tree_code) (((contains_struct_check ((lhs_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4186, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4186, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((lhs_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4186, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
))
4187 || !types_compatible_p (rhs1_type, rhs2_type)
4188 || maybe_ne (GET_MODE_SIZE (element_mode (rhs1_type)),
4189 2 * GET_MODE_SIZE (element_mode (lhs_type)))
4190 || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (rhs1_type),
4191 TYPE_VECTOR_SUBPARTS (lhs_type)))
4192 {
4193 error ("type mismatch in %qs", code_name);
4194 debug_generic_expr (lhs_type);
4195 debug_generic_expr (rhs1_type);
4196 debug_generic_expr (rhs2_type);
4197 return true;
4198 }
4199
4200 return false;
4201 }
4202
4203 case VEC_PACK_FLOAT_EXPR:
4204 if (TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) != VECTOR_TYPE
4205 || TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) != VECTOR_TYPE
4206 || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))(((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4206, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4206, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((rhs1_type), (
TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4206, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
4207 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type))(((enum tree_code) (((contains_struct_check ((lhs_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4207, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE
)
4208 || !types_compatible_p (rhs1_type, rhs2_type)
4209 || maybe_ne (GET_MODE_SIZE (element_mode (rhs1_type)),
4210 2 * GET_MODE_SIZE (element_mode (lhs_type)))
4211 || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (rhs1_type),
4212 TYPE_VECTOR_SUBPARTS (lhs_type)))
4213 {
4214 error ("type mismatch in %qs", code_name);
4215 debug_generic_expr (lhs_type);
4216 debug_generic_expr (rhs1_type);
4217 debug_generic_expr (rhs2_type);
4218 return true;
4219 }
4220
4221 return false;
4222
4223 case MULT_EXPR:
4224 case MULT_HIGHPART_EXPR:
4225 case TRUNC_DIV_EXPR:
4226 case CEIL_DIV_EXPR:
4227 case FLOOR_DIV_EXPR:
4228 case ROUND_DIV_EXPR:
4229 case TRUNC_MOD_EXPR:
4230 case CEIL_MOD_EXPR:
4231 case FLOOR_MOD_EXPR:
4232 case ROUND_MOD_EXPR:
4233 case RDIV_EXPR:
4234 case EXACT_DIV_EXPR:
4235 case BIT_IOR_EXPR:
4236 case BIT_XOR_EXPR:
4237 /* Disallow pointer and offset types for many of the binary gimple. */
4238 if (POINTER_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == POINTER_TYPE ||
((enum tree_code) (lhs_type)->base.code) == REFERENCE_TYPE
)
4239 || TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) == OFFSET_TYPE)
4240 {
4241 error ("invalid types for %qs", code_name);
4242 debug_generic_expr (lhs_type);
4243 debug_generic_expr (rhs1_type);
4244 debug_generic_expr (rhs2_type);
4245 return true;
4246 }
4247 /* Continue with generic binary expression handling. */
4248 break;
4249
4250 case MIN_EXPR:
4251 case MAX_EXPR:
4252 /* Continue with generic binary expression handling. */
4253 break;
4254
4255 case BIT_AND_EXPR:
4256 if (POINTER_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == POINTER_TYPE ||
((enum tree_code) (lhs_type)->base.code) == REFERENCE_TYPE
)
4257 && TREE_CODE (rhs2)((enum tree_code) (rhs2)->base.code) == INTEGER_CST)
4258 break;
4259 /* Disallow pointer and offset types for many of the binary gimple. */
4260 if (POINTER_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == POINTER_TYPE ||
((enum tree_code) (lhs_type)->base.code) == REFERENCE_TYPE
)
4261 || TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) == OFFSET_TYPE)
4262 {
4263 error ("invalid types for %qs", code_name);
4264 debug_generic_expr (lhs_type);
4265 debug_generic_expr (rhs1_type);
4266 debug_generic_expr (rhs2_type);
4267 return true;
4268 }
4269 /* Continue with generic binary expression handling. */
4270 break;
4271
4272 case VEC_SERIES_EXPR:
4273 if (!useless_type_conversion_p (rhs1_type, rhs2_type))
4274 {
4275 error ("type mismatch in %qs", code_name);
4276 debug_generic_expr (rhs1_type);
4277 debug_generic_expr (rhs2_type);
4278 return true;
4279 }
4280 if (TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) != VECTOR_TYPE
4281 || !useless_type_conversion_p (TREE_TYPE (lhs_type)((contains_struct_check ((lhs_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4281, __FUNCTION__))->typed.type)
, rhs1_type))
4282 {
4283 error ("vector type expected in %qs", code_name);
4284 debug_generic_expr (lhs_type);
4285 return true;
4286 }
4287 return false;
4288
4289 default:
4290 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4290, __FUNCTION__))
;
4291 }
4292
4293 if (!useless_type_conversion_p (lhs_type, rhs1_type)
4294 || !useless_type_conversion_p (lhs_type, rhs2_type))
4295 {
4296 error ("type mismatch in binary expression");
4297 debug_generic_stmt (lhs_type);
4298 debug_generic_stmt (rhs1_type);
4299 debug_generic_stmt (rhs2_type);
4300 return true;
4301 }
4302
4303 return false;
4304}
4305
4306/* Verify a gimple assignment statement STMT with a ternary rhs.
4307 Returns true if anything is wrong. */
4308
4309static bool
4310verify_gimple_assign_ternary (gassign *stmt)
4311{
4312 enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
4313 tree lhs = gimple_assign_lhs (stmt);
4314 tree lhs_type = TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4314, __FUNCTION__))->typed.type)
;
4315 tree rhs1 = gimple_assign_rhs1 (stmt);
4316 tree rhs1_type = TREE_TYPE (rhs1)((contains_struct_check ((rhs1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4316, __FUNCTION__))->typed.type)
;
4317 tree rhs2 = gimple_assign_rhs2 (stmt);
4318 tree rhs2_type = TREE_TYPE (rhs2)((contains_struct_check ((rhs2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4318, __FUNCTION__))->typed.type)
;
4319 tree rhs3 = gimple_assign_rhs3 (stmt);
4320 tree rhs3_type = TREE_TYPE (rhs3)((contains_struct_check ((rhs3), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4320, __FUNCTION__))->typed.type)
;
4321
4322 if (!is_gimple_reg (lhs))
4323 {
4324 error ("non-register as LHS of ternary operation");
4325 return true;
4326 }
4327
4328 if (!is_gimple_val (rhs1)
4329 || !is_gimple_val (rhs2)
4330 || !is_gimple_val (rhs3))
4331 {
4332 error ("invalid operands in ternary operation");
4333 return true;
4334 }
4335
4336 const char* const code_name = get_tree_code_name (rhs_code);
4337
4338 /* First handle operations that involve different types. */
4339 switch (rhs_code)
4340 {
4341 case WIDEN_MULT_PLUS_EXPR:
4342 case WIDEN_MULT_MINUS_EXPR:
4343 if ((!INTEGRAL_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
)
4344 && !FIXED_POINT_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == FIXED_POINT_TYPE
)
)
4345 || !useless_type_conversion_p (rhs1_type, rhs2_type)
4346 || !useless_type_conversion_p (lhs_type, rhs3_type)
4347 || 2 * TYPE_PRECISION (rhs1_type)((tree_class_check ((rhs1_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4347, __FUNCTION__))->type_common.precision)
> TYPE_PRECISION (lhs_type)((tree_class_check ((lhs_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4347, __FUNCTION__))->type_common.precision)
4348 || TYPE_PRECISION (rhs1_type)((tree_class_check ((rhs1_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4348, __FUNCTION__))->type_common.precision)
!= TYPE_PRECISION (rhs2_type)((tree_class_check ((rhs2_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4348, __FUNCTION__))->type_common.precision)
)
4349 {
4350 error ("type mismatch in %qs", code_name);
4351 debug_generic_expr (lhs_type);
4352 debug_generic_expr (rhs1_type);
4353 debug_generic_expr (rhs2_type);
4354 debug_generic_expr (rhs3_type);
4355 return true;
4356 }
4357 break;
4358
4359 case VEC_COND_EXPR:
4360 if (!VECTOR_BOOLEAN_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE &&
((enum tree_code) (((contains_struct_check ((rhs1_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4360, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
)
4361 || maybe_ne (TYPE_VECTOR_SUBPARTS (rhs1_type),
4362 TYPE_VECTOR_SUBPARTS (lhs_type)))
4363 {
4364 error ("the first argument of a %qs must be of a "
4365 "boolean vector type of the same number of elements "
4366 "as the result", code_name);
4367 debug_generic_expr (lhs_type);
4368 debug_generic_expr (rhs1_type);
4369 return true;
4370 }
4371 /* Fallthrough. */
4372 case COND_EXPR:
4373 if (!useless_type_conversion_p (lhs_type, rhs2_type)
4374 || !useless_type_conversion_p (lhs_type, rhs3_type))
4375 {
4376 error ("type mismatch in %qs", code_name);
4377 debug_generic_expr (lhs_type);
4378 debug_generic_expr (rhs2_type);
4379 debug_generic_expr (rhs3_type);
4380 return true;
4381 }
4382 break;
4383
4384 case VEC_PERM_EXPR:
4385 /* If permute is constant, then we allow for lhs and rhs
4386 to have different vector types, provided:
4387 (1) lhs, rhs1, rhs2 have same element type.
4388 (2) rhs3 vector is constant and has integer element type.
4389 (3) len(lhs) == len(rhs3) && len(rhs1) == len(rhs2). */
4390
4391 if (TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) != VECTOR_TYPE
4392 || TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) != VECTOR_TYPE
4393 || TREE_CODE (rhs2_type)((enum tree_code) (rhs2_type)->base.code) != VECTOR_TYPE
4394 || TREE_CODE (rhs3_type)((enum tree_code) (rhs3_type)->base.code) != VECTOR_TYPE)
4395 {
4396 error ("vector types expected in %qs", code_name);
4397 debug_generic_expr (lhs_type);
4398 debug_generic_expr (rhs1_type);
4399 debug_generic_expr (rhs2_type);
4400 debug_generic_expr (rhs3_type);
4401 return true;
4402 }
4403
4404 /* If rhs3 is constant, we allow lhs, rhs1 and rhs2 to be different vector types,
4405 as long as lhs, rhs1 and rhs2 have same element type. */
4406 if (TREE_CONSTANT (rhs3)((non_type_check ((rhs3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4406, __FUNCTION__))->base.constant_flag)
4407 ? (!useless_type_conversion_p (TREE_TYPE (lhs_type)((contains_struct_check ((lhs_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4407, __FUNCTION__))->typed.type)
, TREE_TYPE (rhs1_type)((contains_struct_check ((rhs1_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4407, __FUNCTION__))->typed.type)
)
4408 || !useless_type_conversion_p (TREE_TYPE (lhs_type)((contains_struct_check ((lhs_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4408, __FUNCTION__))->typed.type)
, TREE_TYPE (rhs2_type)((contains_struct_check ((rhs2_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4408, __FUNCTION__))->typed.type)
))
4409 : (!useless_type_conversion_p (lhs_type, rhs1_type)
4410 || !useless_type_conversion_p (lhs_type, rhs2_type)))
4411 {
4412 error ("type mismatch in %qs", code_name);
4413 debug_generic_expr (lhs_type);
4414 debug_generic_expr (rhs1_type);
4415 debug_generic_expr (rhs2_type);
4416 debug_generic_expr (rhs3_type);
4417 return true;
4418 }
4419
4420 /* If rhs3 is constant, relax the check len(rhs2) == len(rhs3). */
4421 if (maybe_ne (TYPE_VECTOR_SUBPARTS (rhs1_type),
4422 TYPE_VECTOR_SUBPARTS (rhs2_type))
4423 || (!TREE_CONSTANT(rhs3)((non_type_check ((rhs3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4423, __FUNCTION__))->base.constant_flag)
4424 && maybe_ne (TYPE_VECTOR_SUBPARTS (rhs2_type),
4425 TYPE_VECTOR_SUBPARTS (rhs3_type)))
4426 || maybe_ne (TYPE_VECTOR_SUBPARTS (rhs3_type),
4427 TYPE_VECTOR_SUBPARTS (lhs_type)))
4428 {
4429 error ("vectors with different element number found in %qs",
4430 code_name);
4431 debug_generic_expr (lhs_type);
4432 debug_generic_expr (rhs1_type);
4433 debug_generic_expr (rhs2_type);
4434 debug_generic_expr (rhs3_type);
4435 return true;
4436 }
4437
4438 if (TREE_CODE (TREE_TYPE (rhs3_type))((enum tree_code) (((contains_struct_check ((rhs3_type), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4438, __FUNCTION__))->typed.type))->base.code)
!= INTEGER_TYPE
4439 || (TREE_CODE (rhs3)((enum tree_code) (rhs3)->base.code) != VECTOR_CST
4440 && (GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE(as_a <scalar_int_mode> ((tree_class_check ((((contains_struct_check
((rhs3_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4441, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4441, __FUNCTION__))->type_common.mode))
4441 (TREE_TYPE (rhs3_type))(as_a <scalar_int_mode> ((tree_class_check ((((contains_struct_check
((rhs3_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4441, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4441, __FUNCTION__))->type_common.mode))
)
4442 != GET_MODE_BITSIZE (SCALAR_TYPE_MODE(as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((rhs1_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4443, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4443, __FUNCTION__))->type_common.mode))
4443 (TREE_TYPE (rhs1_type))(as_a <scalar_mode> ((tree_class_check ((((contains_struct_check
((rhs1_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4443, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4443, __FUNCTION__))->type_common.mode))
))))
4444 {
4445 error ("invalid mask type in %qs", code_name);
4446 debug_generic_expr (lhs_type);
4447 debug_generic_expr (rhs1_type);
4448 debug_generic_expr (rhs2_type);
4449 debug_generic_expr (rhs3_type);
4450 return true;
4451 }
4452
4453 return false;
4454
4455 case SAD_EXPR:
4456 if (!useless_type_conversion_p (rhs1_type, rhs2_type)
4457 || !useless_type_conversion_p (lhs_type, rhs3_type)
4458 || 2 * GET_MODE_UNIT_BITSIZE (TYPE_MODE (TREE_TYPE (rhs1_type)))((unsigned short) (mode_to_unit_size (((((enum tree_code) ((tree_class_check
((((contains_struct_check ((rhs1_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4458, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4458, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((rhs1_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4458, __FUNCTION__))->typed.type)) : (((contains_struct_check
((rhs1_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4458, __FUNCTION__))->typed.type))->type_common.mode)
) * (8)))
4459 > GET_MODE_UNIT_BITSIZE (TYPE_MODE (TREE_TYPE (lhs_type)))((unsigned short) (mode_to_unit_size (((((enum tree_code) ((tree_class_check
((((contains_struct_check ((lhs_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4459, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4459, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((lhs_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4459, __FUNCTION__))->typed.type)) : (((contains_struct_check
((lhs_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4459, __FUNCTION__))->typed.type))->type_common.mode)
) * (8)))
)
4460 {
4461 error ("type mismatch in %qs", code_name);
4462 debug_generic_expr (lhs_type);
4463 debug_generic_expr (rhs1_type);
4464 debug_generic_expr (rhs2_type);
4465 debug_generic_expr (rhs3_type);
4466 return true;
4467 }
4468
4469 if (TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) != VECTOR_TYPE
4470 || TREE_CODE (rhs2_type)((enum tree_code) (rhs2_type)->base.code) != VECTOR_TYPE
4471 || TREE_CODE (rhs3_type)((enum tree_code) (rhs3_type)->base.code) != VECTOR_TYPE)
4472 {
4473 error ("vector types expected in %qs", code_name);
4474 debug_generic_expr (lhs_type);
4475 debug_generic_expr (rhs1_type);
4476 debug_generic_expr (rhs2_type);
4477 debug_generic_expr (rhs3_type);
4478 return true;
4479 }
4480
4481 return false;
4482
4483 case BIT_INSERT_EXPR:
4484 if (! useless_type_conversion_p (lhs_type, rhs1_type))
4485 {
4486 error ("type mismatch in %qs", code_name);
4487 debug_generic_expr (lhs_type);
4488 debug_generic_expr (rhs1_type);
4489 return true;
4490 }
4491 if (! ((INTEGRAL_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
)
4492 && INTEGRAL_TYPE_P (rhs2_type)(((enum tree_code) (rhs2_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs2_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs2_type)->base.code) == INTEGER_TYPE
)
)
4493 /* Vector element insert. */
4494 || (VECTOR_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE)
4495 && types_compatible_p (TREE_TYPE (rhs1_type)((contains_struct_check ((rhs1_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4495, __FUNCTION__))->typed.type)
, rhs2_type))
4496 /* Aligned sub-vector insert. */
4497 || (VECTOR_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE)
4498 && VECTOR_TYPE_P (rhs2_type)(((enum tree_code) (rhs2_type)->base.code) == VECTOR_TYPE)
4499 && types_compatible_p (TREE_TYPE (rhs1_type)((contains_struct_check ((rhs1_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4499, __FUNCTION__))->typed.type)
,
4500 TREE_TYPE (rhs2_type)((contains_struct_check ((rhs2_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4500, __FUNCTION__))->typed.type)
)
4501 && multiple_p (TYPE_VECTOR_SUBPARTS (rhs1_type),
4502 TYPE_VECTOR_SUBPARTS (rhs2_type))
4503 && multiple_p (wi::to_poly_offset (rhs3),
4504 wi::to_poly_offset (TYPE_SIZE (rhs2_type)((tree_class_check ((rhs2_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4504, __FUNCTION__))->type_common.size)
)))))
4505 {
4506 error ("not allowed type combination in %qs", code_name);
4507 debug_generic_expr (rhs1_type);
4508 debug_generic_expr (rhs2_type);
4509 return true;
4510 }
4511 if (! tree_fits_uhwi_p (rhs3)
4512 || ! types_compatible_p (bitsizetypesizetype_tab[(int) stk_bitsizetype], TREE_TYPE (rhs3)((contains_struct_check ((rhs3), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4512, __FUNCTION__))->typed.type)
)
4513 || ! tree_fits_uhwi_p (TYPE_SIZE (rhs2_type)((tree_class_check ((rhs2_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4513, __FUNCTION__))->type_common.size)
))
4514 {
4515 error ("invalid position or size in %qs", code_name);
4516 return true;
4517 }
4518 if (INTEGRAL_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
)
4519 && !type_has_mode_precision_p (rhs1_type))
4520 {
4521 error ("%qs into non-mode-precision operand", code_name);
4522 return true;
4523 }
4524 if (INTEGRAL_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
)
)
4525 {
4526 unsigned HOST_WIDE_INTlong bitpos = tree_to_uhwi (rhs3);
4527 if (bitpos >= TYPE_PRECISION (rhs1_type)((tree_class_check ((rhs1_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4527, __FUNCTION__))->type_common.precision)
4528 || (bitpos + TYPE_PRECISION (rhs2_type)((tree_class_check ((rhs2_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4528, __FUNCTION__))->type_common.precision)
4529 > TYPE_PRECISION (rhs1_type)((tree_class_check ((rhs1_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4529, __FUNCTION__))->type_common.precision)
))
4530 {
4531 error ("insertion out of range in %qs", code_name);
4532 return true;
4533 }
4534 }
4535 else if (VECTOR_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE))
4536 {
4537 unsigned HOST_WIDE_INTlong bitpos = tree_to_uhwi (rhs3);
4538 unsigned HOST_WIDE_INTlong bitsize = tree_to_uhwi (TYPE_SIZE (rhs2_type)((tree_class_check ((rhs2_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4538, __FUNCTION__))->type_common.size)
);
4539 if (bitpos % bitsize != 0)
4540 {
4541 error ("%qs not at element boundary", code_name);
4542 return true;
4543 }
4544 }
4545 return false;
4546
4547 case DOT_PROD_EXPR:
4548 {
4549 if (((TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) != VECTOR_TYPE
4550 || TREE_CODE (lhs_type)((enum tree_code) (lhs_type)->base.code) != VECTOR_TYPE)
4551 && ((!INTEGRAL_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (rhs1_type)->base.code) == INTEGER_TYPE
)
4552 && !SCALAR_FLOAT_TYPE_P (rhs1_type)(((enum tree_code) (rhs1_type)->base.code) == REAL_TYPE))
4553 || (!INTEGRAL_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (lhs_type)->base.code) == INTEGER_TYPE
)
4554 && !SCALAR_FLOAT_TYPE_P (lhs_type)(((enum tree_code) (lhs_type)->base.code) == REAL_TYPE))))
4555 /* rhs1_type and rhs2_type may differ in sign. */
4556 || !tree_nop_conversion_p (rhs1_type, rhs2_type)
4557 || !useless_type_conversion_p (lhs_type, rhs3_type)
4558 || maybe_lt (GET_MODE_SIZE (element_mode (rhs3_type)),
4559 2 * GET_MODE_SIZE (element_mode (rhs1_type))))
4560 {
4561 error ("type mismatch in %qs", code_name);
4562 debug_generic_expr (lhs_type);
4563 debug_generic_expr (rhs1_type);
4564 debug_generic_expr (rhs2_type);
4565 return true;
4566 }
4567 return false;
4568 }
4569
4570 case REALIGN_LOAD_EXPR:
4571 /* FIXME. */
4572 return false;
4573
4574 default:
4575 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4575, __FUNCTION__))
;
4576 }
4577 return false;
4578}
4579
4580/* Verify a gimple assignment statement STMT with a single rhs.
4581 Returns true if anything is wrong. */
4582
4583static bool
4584verify_gimple_assign_single (gassign *stmt)
4585{
4586 enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
4587 tree lhs = gimple_assign_lhs (stmt);
4588 tree lhs_type = TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4588, __FUNCTION__))->typed.type)
;
4589 tree rhs1 = gimple_assign_rhs1 (stmt);
4590 tree rhs1_type = TREE_TYPE (rhs1)((contains_struct_check ((rhs1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4590, __FUNCTION__))->typed.type)
;
4591 bool res = false;
4592
4593 const char* const code_name = get_tree_code_name (rhs_code);
4594
4595 if (!useless_type_conversion_p (lhs_type, rhs1_type))
4596 {
4597 error ("non-trivial conversion in %qs", code_name);
4598 debug_generic_expr (lhs_type);
4599 debug_generic_expr (rhs1_type);
4600 return true;
4601 }
4602
4603 if (gimple_clobber_p (stmt)
4604 && !(DECL_P (lhs)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code
) (lhs)->base.code))] == tcc_declaration)
|| TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == MEM_REF))
4605 {
4606 error ("%qs LHS in clobber statement",
4607 get_tree_code_name (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code)));
4608 debug_generic_expr (lhs);
4609 return true;
4610 }
4611
4612 if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == WITH_SIZE_EXPR)
4613 {
4614 error ("%qs LHS in assignment statement",
4615 get_tree_code_name (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code)));
4616 debug_generic_expr (lhs);
4617 return true;
4618 }
4619
4620 if (handled_component_p (lhs)
4621 || TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == MEM_REF
4622 || TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == TARGET_MEM_REF)
4623 res |= verify_types_in_gimple_reference (lhs, true);
4624
4625 /* Special codes we cannot handle via their class. */
4626 switch (rhs_code)
4627 {
4628 case ADDR_EXPR:
4629 {
4630 tree op = TREE_OPERAND (rhs1, 0)(*((const_cast<tree*> (tree_operand_check ((rhs1), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4630, __FUNCTION__)))))
;
4631 if (!is_gimple_addressable (op))
4632 {
4633 error ("invalid operand in %qs", code_name);
4634 return true;
4635 }
4636
4637 /* Technically there is no longer a need for matching types, but
4638 gimple hygiene asks for this check. In LTO we can end up
4639 combining incompatible units and thus end up with addresses
4640 of globals that change their type to a common one. */
4641 if (!in_lto_pglobal_options.x_in_lto_p
4642 && !types_compatible_p (TREE_TYPE (op)((contains_struct_check ((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4642, __FUNCTION__))->typed.type)
,
4643 TREE_TYPE (TREE_TYPE (rhs1))((contains_struct_check ((((contains_struct_check ((rhs1), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4643, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4643, __FUNCTION__))->typed.type)
)
4644 && !one_pointer_to_useless_type_conversion_p (TREE_TYPE (rhs1)((contains_struct_check ((rhs1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4644, __FUNCTION__))->typed.type)
,
4645 TREE_TYPE (op)((contains_struct_check ((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4645, __FUNCTION__))->typed.type)
))
4646 {
4647 error ("type mismatch in %qs", code_name);
4648 debug_generic_stmt (TREE_TYPE (rhs1)((contains_struct_check ((rhs1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4648, __FUNCTION__))->typed.type)
);
4649 debug_generic_stmt (TREE_TYPE (op)((contains_struct_check ((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4649, __FUNCTION__))->typed.type)
);
4650 return true;
4651 }
4652
4653 return (verify_address (rhs1, true)
4654 || verify_types_in_gimple_reference (op, true));
4655 }
4656
4657 /* tcc_reference */
4658 case INDIRECT_REF:
4659 error ("%qs in gimple IL", code_name);
4660 return true;
4661
4662 case COMPONENT_REF:
4663 case BIT_FIELD_REF:
4664 case ARRAY_REF:
4665 case ARRAY_RANGE_REF:
4666 case VIEW_CONVERT_EXPR:
4667 case REALPART_EXPR:
4668 case IMAGPART_EXPR:
4669 case TARGET_MEM_REF:
4670 case MEM_REF:
4671 if (!is_gimple_reg (lhs)
4672 && is_gimple_reg_type (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4672, __FUNCTION__))->typed.type)
))
4673 {
4674 error ("invalid RHS for gimple memory store: %qs", code_name);
4675 debug_generic_stmt (lhs);
4676 debug_generic_stmt (rhs1);
4677 return true;
4678 }
4679 return res || verify_types_in_gimple_reference (rhs1, false);
4680
4681 /* tcc_constant */
4682 case SSA_NAME:
4683 case INTEGER_CST:
4684 case REAL_CST:
4685 case FIXED_CST:
4686 case COMPLEX_CST:
4687 case VECTOR_CST:
4688 case STRING_CST:
4689 return res;
4690
4691 /* tcc_declaration */
4692 case CONST_DECL:
4693 return res;
4694 case VAR_DECL:
4695 case PARM_DECL:
4696 if (!is_gimple_reg (lhs)
4697 && !is_gimple_reg (rhs1)
4698 && is_gimple_reg_type (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4698, __FUNCTION__))->typed.type)
))
4699 {
4700 error ("invalid RHS for gimple memory store: %qs", code_name);
4701 debug_generic_stmt (lhs);
4702 debug_generic_stmt (rhs1);
4703 return true;
4704 }
4705 return res;
4706
4707 case CONSTRUCTOR:
4708 if (TREE_CODE (rhs1_type)((enum tree_code) (rhs1_type)->base.code) == VECTOR_TYPE)
4709 {
4710 unsigned int i;
4711 tree elt_i, elt_v, elt_t = NULL_TREE(tree) nullptr;
4712
4713 if (CONSTRUCTOR_NELTS (rhs1)(vec_safe_length (((tree_check ((rhs1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4713, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)))
== 0)
4714 return res;
4715 /* For vector CONSTRUCTORs we require that either it is empty
4716 CONSTRUCTOR, or it is a CONSTRUCTOR of smaller vector elements
4717 (then the element count must be correct to cover the whole
4718 outer vector and index must be NULL on all elements, or it is
4719 a CONSTRUCTOR of scalar elements, where we as an exception allow
4720 smaller number of elements (assuming zero filling) and
4721 consecutive indexes as compared to NULL indexes (such
4722 CONSTRUCTORs can appear in the IL from FEs). */
4723 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (rhs1), i, elt_i, elt_v)for (i = 0; (i >= vec_safe_length (((tree_check ((rhs1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4723, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)))
? false : (((void) (elt_v = (*((tree_check ((rhs1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4723, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[
i].value)), (elt_i = (*((tree_check ((rhs1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4723, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[
i].index), true); (i)++)
4724 {
4725 if (elt_t == NULL_TREE(tree) nullptr)
4726 {
4727 elt_t = TREE_TYPE (elt_v)((contains_struct_check ((elt_v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4727, __FUNCTION__))->typed.type)
;
4728 if (TREE_CODE (elt_t)((enum tree_code) (elt_t)->base.code) == VECTOR_TYPE)
4729 {
4730 tree elt_t = TREE_TYPE (elt_v)((contains_struct_check ((elt_v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4730, __FUNCTION__))->typed.type)
;
4731 if (!useless_type_conversion_p (TREE_TYPE (rhs1_type)((contains_struct_check ((rhs1_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4731, __FUNCTION__))->typed.type)
,
4732 TREE_TYPE (elt_t)((contains_struct_check ((elt_t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4732, __FUNCTION__))->typed.type)
))
4733 {
4734 error ("incorrect type of vector %qs elements",
4735 code_name);
4736 debug_generic_stmt (rhs1);
4737 return true;
4738 }
4739 else if (maybe_ne (CONSTRUCTOR_NELTS (rhs1)(vec_safe_length (((tree_check ((rhs1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4739, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)))
4740 * TYPE_VECTOR_SUBPARTS (elt_t),
4741 TYPE_VECTOR_SUBPARTS (rhs1_type)))
4742 {
4743 error ("incorrect number of vector %qs elements",
4744 code_name);
4745 debug_generic_stmt (rhs1);
4746 return true;
4747 }
4748 }
4749 else if (!useless_type_conversion_p (TREE_TYPE (rhs1_type)((contains_struct_check ((rhs1_type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4749, __FUNCTION__))->typed.type)
,
4750 elt_t))
4751 {
4752 error ("incorrect type of vector %qs elements",
4753 code_name);
4754 debug_generic_stmt (rhs1);
4755 return true;
4756 }
4757 else if (maybe_gt (CONSTRUCTOR_NELTS (rhs1),maybe_lt (TYPE_VECTOR_SUBPARTS (rhs1_type), (vec_safe_length (
((tree_check ((rhs1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4757, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)))
)
4758 TYPE_VECTOR_SUBPARTS (rhs1_type))maybe_lt (TYPE_VECTOR_SUBPARTS (rhs1_type), (vec_safe_length (
((tree_check ((rhs1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4757, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)))
)
)
4759 {
4760 error ("incorrect number of vector %qs elements",
4761 code_name);
4762 debug_generic_stmt (rhs1);
4763 return true;
4764 }
4765 }
4766 else if (!useless_type_conversion_p (elt_t, TREE_TYPE (elt_v)((contains_struct_check ((elt_v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4766, __FUNCTION__))->typed.type)
))
4767 {
4768 error ("incorrect type of vector CONSTRUCTOR elements");
4769 debug_generic_stmt (rhs1);
4770 return true;
4771 }
4772 if (elt_i != NULL_TREE(tree) nullptr
4773 && (TREE_CODE (elt_t)((enum tree_code) (elt_t)->base.code) == VECTOR_TYPE
4774 || TREE_CODE (elt_i)((enum tree_code) (elt_i)->base.code) != INTEGER_CST
4775 || compare_tree_int (elt_i, i) != 0))
4776 {
4777 error ("vector %qs with non-NULL element index",
4778 code_name);
4779 debug_generic_stmt (rhs1);
4780 return true;
4781 }
4782 if (!is_gimple_val (elt_v))
4783 {
4784 error ("vector %qs element is not a GIMPLE value",
4785 code_name);
4786 debug_generic_stmt (rhs1);
4787 return true;
4788 }
4789 }
4790 }
4791 else if (CONSTRUCTOR_NELTS (rhs1)(vec_safe_length (((tree_check ((rhs1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4791, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)))
!= 0)
4792 {
4793 error ("non-vector %qs with elements", code_name);
4794 debug_generic_stmt (rhs1);
4795 return true;
4796 }
4797 return res;
4798
4799 case WITH_SIZE_EXPR:
4800 error ("%qs RHS in assignment statement",
4801 get_tree_code_name (rhs_code));
4802 debug_generic_expr (rhs1);
4803 return true;
4804
4805 case OBJ_TYPE_REF:
4806 /* FIXME. */
4807 return res;
4808
4809 default:;
4810 }
4811
4812 return res;
4813}
4814
4815/* Verify the contents of a GIMPLE_ASSIGN STMT. Returns true when there
4816 is a problem, otherwise false. */
4817
4818static bool
4819verify_gimple_assign (gassign *stmt)
4820{
4821 switch (gimple_assign_rhs_class (stmt))
4822 {
4823 case GIMPLE_SINGLE_RHS:
4824 return verify_gimple_assign_single (stmt);
4825
4826 case GIMPLE_UNARY_RHS:
4827 return verify_gimple_assign_unary (stmt);
4828
4829 case GIMPLE_BINARY_RHS:
4830 return verify_gimple_assign_binary (stmt);
4831
4832 case GIMPLE_TERNARY_RHS:
4833 return verify_gimple_assign_ternary (stmt);
4834
4835 default:
4836 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4836, __FUNCTION__))
;
4837 }
4838}
4839
4840/* Verify the contents of a GIMPLE_RETURN STMT. Returns true when there
4841 is a problem, otherwise false. */
4842
4843static bool
4844verify_gimple_return (greturn *stmt)
4845{
4846 tree op = gimple_return_retval (stmt);
4847 tree restype = TREE_TYPE (TREE_TYPE (cfun->decl))((contains_struct_check ((((contains_struct_check (((cfun + 0
)->decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4847, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4847, __FUNCTION__))->typed.type)
;
4848
4849 /* We cannot test for present return values as we do not fix up missing
4850 return values from the original source. */
4851 if (op == NULLnullptr)
4852 return false;
4853
4854 if (!is_gimple_val (op)
4855 && TREE_CODE (op)((enum tree_code) (op)->base.code) != RESULT_DECL)
4856 {
4857 error ("invalid operand in return statement");
4858 debug_generic_stmt (op);
4859 return true;
4860 }
4861
4862 if ((TREE_CODE (op)((enum tree_code) (op)->base.code) == RESULT_DECL
4863 && DECL_BY_REFERENCE (op)((tree_check3 ((op), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4863, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL))
)->decl_common.decl_by_reference_flag)
)
4864 || (TREE_CODE (op)((enum tree_code) (op)->base.code) == SSA_NAME
4865 && SSA_NAME_VAR (op)((tree_check ((op), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4865, __FUNCTION__, (SSA_NAME)))->ssa_name.var == (tree)
nullptr || ((enum tree_code) ((op)->ssa_name.var)->base
.code) == IDENTIFIER_NODE ? (tree) nullptr : (op)->ssa_name
.var)
4866 && TREE_CODE (SSA_NAME_VAR (op))((enum tree_code) (((tree_check ((op), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4866, __FUNCTION__, (SSA_NAME)))->ssa_name.var == (tree)
nullptr || ((enum tree_code) ((op)->ssa_name.var)->base
.code) == IDENTIFIER_NODE ? (tree) nullptr : (op)->ssa_name
.var))->base.code)
== RESULT_DECL
4867 && DECL_BY_REFERENCE (SSA_NAME_VAR (op))((tree_check3 ((((tree_check ((op), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4867, __FUNCTION__, (SSA_NAME)))->ssa_name.var == (tree)
nullptr || ((enum tree_code) ((op)->ssa_name.var)->base
.code) == IDENTIFIER_NODE ? (tree) nullptr : (op)->ssa_name
.var)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4867, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL))
)->decl_common.decl_by_reference_flag)
))
4868 op = TREE_TYPE (op)((contains_struct_check ((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4868, __FUNCTION__))->typed.type)
;
4869
4870 if (!useless_type_conversion_p (restype, TREE_TYPE (op)((contains_struct_check ((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4870, __FUNCTION__))->typed.type)
))
4871 {
4872 error ("invalid conversion in return statement");
4873 debug_generic_stmt (restype);
4874 debug_generic_stmt (TREE_TYPE (op)((contains_struct_check ((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4874, __FUNCTION__))->typed.type)
);
4875 return true;
4876 }
4877
4878 return false;
4879}
4880
4881
4882/* Verify the contents of a GIMPLE_GOTO STMT. Returns true when there
4883 is a problem, otherwise false. */
4884
4885static bool
4886verify_gimple_goto (ggoto *stmt)
4887{
4888 tree dest = gimple_goto_dest (stmt);
4889
4890 /* ??? We have two canonical forms of direct goto destinations, a
4891 bare LABEL_DECL and an ADDR_EXPR of a LABEL_DECL. */
4892 if (TREE_CODE (dest)((enum tree_code) (dest)->base.code) != LABEL_DECL
4893 && (!is_gimple_val (dest)
4894 || !POINTER_TYPE_P (TREE_TYPE (dest))(((enum tree_code) (((contains_struct_check ((dest), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4894, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((dest), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4894, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
))
4895 {
4896 error ("goto destination is neither a label nor a pointer");
4897 return true;
4898 }
4899
4900 return false;
4901}
4902
4903/* Verify the contents of a GIMPLE_SWITCH STMT. Returns true when there
4904 is a problem, otherwise false. */
4905
4906static bool
4907verify_gimple_switch (gswitch *stmt)
4908{
4909 unsigned int i, n;
4910 tree elt, prev_upper_bound = NULL_TREE(tree) nullptr;
4911 tree index_type, elt_type = NULL_TREE(tree) nullptr;
4912
4913 if (!is_gimple_val (gimple_switch_index (stmt)))
4914 {
4915 error ("invalid operand to switch statement");
4916 debug_generic_stmt (gimple_switch_index (stmt));
4917 return true;
4918 }
4919
4920 index_type = TREE_TYPE (gimple_switch_index (stmt))((contains_struct_check ((gimple_switch_index (stmt)), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4920, __FUNCTION__))->typed.type)
;
4921 if (! INTEGRAL_TYPE_P (index_type)(((enum tree_code) (index_type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (index_type)->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (index_type)->base.code) == INTEGER_TYPE
)
)
4922 {
4923 error ("non-integral type switch statement");
4924 debug_generic_expr (index_type);
4925 return true;
4926 }
4927
4928 elt = gimple_switch_label (stmt, 0);
4929 if (CASE_LOW (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4929, __FUNCTION__, (CASE_LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4929, __FUNCTION__)))))
!= NULL_TREE(tree) nullptr
4930 || CASE_HIGH (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4930, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4930, __FUNCTION__)))))
!= NULL_TREE(tree) nullptr
4931 || CASE_CHAIN (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4931, __FUNCTION__, (CASE_LABEL_EXPR)))), (3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4931, __FUNCTION__)))))
!= NULL_TREE(tree) nullptr)
4932 {
4933 error ("invalid default case label in switch statement");
4934 debug_generic_expr (elt);
4935 return true;
4936 }
4937
4938 n = gimple_switch_num_labels (stmt);
4939 for (i = 1; i < n; i++)
4940 {
4941 elt = gimple_switch_label (stmt, i);
4942
4943 if (CASE_CHAIN (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4943, __FUNCTION__, (CASE_LABEL_EXPR)))), (3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4943, __FUNCTION__)))))
)
4944 {
4945 error ("invalid %<CASE_CHAIN%>");
4946 debug_generic_expr (elt);
4947 return true;
4948 }
4949 if (! CASE_LOW (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4949, __FUNCTION__, (CASE_LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4949, __FUNCTION__)))))
)
4950 {
4951 error ("invalid case label in switch statement");
4952 debug_generic_expr (elt);
4953 return true;
4954 }
4955 if (CASE_HIGH (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4955, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4955, __FUNCTION__)))))
4956 && ! tree_int_cst_lt (CASE_LOW (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4956, __FUNCTION__, (CASE_LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4956, __FUNCTION__)))))
, CASE_HIGH (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4956, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4956, __FUNCTION__)))))
))
4957 {
4958 error ("invalid case range in switch statement");
4959 debug_generic_expr (elt);
4960 return true;
4961 }
4962
4963 if (! elt_type)
4964 {
4965 elt_type = TREE_TYPE (CASE_LOW (elt))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check
(((tree_check ((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4965, __FUNCTION__, (CASE_LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4965, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4965, __FUNCTION__))->typed.type)
;
4966 if (TYPE_PRECISION (index_type)((tree_class_check ((index_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4966, __FUNCTION__))->type_common.precision)
< TYPE_PRECISION (elt_type)((tree_class_check ((elt_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4966, __FUNCTION__))->type_common.precision)
)
4967 {
4968 error ("type precision mismatch in switch statement");
4969 return true;
4970 }
4971 }
4972 if (TREE_TYPE (CASE_LOW (elt))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check
(((tree_check ((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4972, __FUNCTION__, (CASE_LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4972, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4972, __FUNCTION__))->typed.type)
!= elt_type
4973 || (CASE_HIGH (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4973, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4973, __FUNCTION__)))))
&& TREE_TYPE (CASE_HIGH (elt))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check
(((tree_check ((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4973, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4973, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4973, __FUNCTION__))->typed.type)
!= elt_type))
4974 {
4975 error ("type mismatch for case label in switch statement");
4976 debug_generic_expr (elt);
4977 return true;
4978 }
4979
4980 if (prev_upper_bound)
4981 {
4982 if (! tree_int_cst_lt (prev_upper_bound, CASE_LOW (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4982, __FUNCTION__, (CASE_LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4982, __FUNCTION__)))))
))
4983 {
4984 error ("case labels not sorted in switch statement");
4985 return true;
4986 }
4987 }
4988
4989 prev_upper_bound = CASE_HIGH (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4989, __FUNCTION__, (CASE_LABEL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4989, __FUNCTION__)))))
;
4990 if (! prev_upper_bound)
4991 prev_upper_bound = CASE_LOW (elt)(*((const_cast<tree*> (tree_operand_check (((tree_check
((elt), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4991, __FUNCTION__, (CASE_LABEL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 4991, __FUNCTION__)))))
;
4992 }
4993
4994 return false;
4995}
4996
4997/* Verify a gimple debug statement STMT.
4998 Returns true if anything is wrong. */
4999
5000static bool
5001verify_gimple_debug (gimple *stmt ATTRIBUTE_UNUSED__attribute__ ((__unused__)))
5002{
5003 /* There isn't much that could be wrong in a gimple debug stmt. A
5004 gimple debug bind stmt, for example, maps a tree, that's usually
5005 a VAR_DECL or a PARM_DECL, but that could also be some scalarized
5006 component or member of an aggregate type, to another tree, that
5007 can be an arbitrary expression. These stmts expand into debug
5008 insns, and are converted to debug notes by var-tracking.cc. */
5009 return false;
5010}
5011
5012/* Verify a gimple label statement STMT.
5013 Returns true if anything is wrong. */
5014
5015static bool
5016verify_gimple_label (glabel *stmt)
5017{
5018 tree decl = gimple_label_label (stmt);
5019 int uid;
5020 bool err = false;
5021
5022 if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) != LABEL_DECL)
5023 return true;
5024 if (!DECL_NONLOCAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5024, __FUNCTION__))->decl_common.nonlocal_flag)
&& !FORCED_LABEL (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5024, __FUNCTION__, (LABEL_DECL)))->base.side_effects_flag
)
5025 && DECL_CONTEXT (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5025, __FUNCTION__))->decl_minimal.context)
!= current_function_decl)
5026 {
5027 error ("label context is not the current function declaration");
5028 err |= true;
5029 }
5030
5031 uid = LABEL_DECL_UID (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5031, __FUNCTION__, (LABEL_DECL)))->label_decl.label_decl_uid
)
;
5032 if (cfun(cfun + 0)->cfg
5033 && (uid == -1
5034 || (*label_to_block_map_for_fn (cfun)(((cfun + 0))->cfg->x_label_to_block_map))[uid] != gimple_bb (stmt)))
5035 {
5036 error ("incorrect entry in %<label_to_block_map%>");
5037 err |= true;
5038 }
5039
5040 uid = EH_LANDING_PAD_NR (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5040, __FUNCTION__, (LABEL_DECL)))->label_decl.eh_landing_pad_nr
)
;
5041 if (uid)
5042 {
5043 eh_landing_pad lp = get_eh_landing_pad_from_number (uid);
5044 if (decl != lp->post_landing_pad)
5045 {
5046 error ("incorrect setting of landing pad number");
5047 err |= true;
5048 }
5049 }
5050
5051 return err;
5052}
5053
5054/* Verify a gimple cond statement STMT.
5055 Returns true if anything is wrong. */
5056
5057static bool
5058verify_gimple_cond (gcond *stmt)
5059{
5060 if (TREE_CODE_CLASS (gimple_cond_code (stmt))tree_code_type_tmpl <0>::tree_code_type[(int) (gimple_cond_code
(stmt))]
!= tcc_comparison)
5061 {
5062 error ("invalid comparison code in gimple cond");
5063 return true;
5064 }
5065 if (!(!gimple_cond_true_label (stmt)
5066 || TREE_CODE (gimple_cond_true_label (stmt))((enum tree_code) (gimple_cond_true_label (stmt))->base.code
)
== LABEL_DECL)
5067 || !(!gimple_cond_false_label (stmt)
5068 || TREE_CODE (gimple_cond_false_label (stmt))((enum tree_code) (gimple_cond_false_label (stmt))->base.code
)
== LABEL_DECL))
5069 {
5070 error ("invalid labels in gimple cond");
5071 return true;
5072 }
5073
5074 return verify_gimple_comparison (boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE],
5075 gimple_cond_lhs (stmt),
5076 gimple_cond_rhs (stmt),
5077 gimple_cond_code (stmt));
5078}
5079
5080/* Verify the GIMPLE statement STMT. Returns true if there is an
5081 error, otherwise false. */
5082
5083static bool
5084verify_gimple_stmt (gimple *stmt)
5085{
5086 switch (gimple_code (stmt))
5087 {
5088 case GIMPLE_ASSIGN:
5089 return verify_gimple_assign (as_a <gassign *> (stmt));
5090
5091 case GIMPLE_LABEL:
5092 return verify_gimple_label (as_a <glabel *> (stmt));
5093
5094 case GIMPLE_CALL:
5095 return verify_gimple_call (as_a <gcall *> (stmt));
5096
5097 case GIMPLE_COND:
5098 return verify_gimple_cond (as_a <gcond *> (stmt));
5099
5100 case GIMPLE_GOTO:
5101 return verify_gimple_goto (as_a <ggoto *> (stmt));
5102
5103 case GIMPLE_SWITCH:
5104 return verify_gimple_switch (as_a <gswitch *> (stmt));
5105
5106 case GIMPLE_RETURN:
5107 return verify_gimple_return (as_a <greturn *> (stmt));
5108
5109 case GIMPLE_ASM:
5110 return false;
5111
5112 case GIMPLE_TRANSACTION:
5113 return verify_gimple_transaction (as_a <gtransaction *> (stmt));
5114
5115 /* Tuples that do not have tree operands. */
5116 case GIMPLE_NOP:
5117 case GIMPLE_PREDICT:
5118 case GIMPLE_RESX:
5119 case GIMPLE_EH_DISPATCH:
5120 case GIMPLE_EH_MUST_NOT_THROW:
5121 return false;
5122
5123 CASE_GIMPLE_OMPcase GIMPLE_OMP_PARALLEL: case GIMPLE_OMP_TASK: case GIMPLE_OMP_FOR
: case GIMPLE_OMP_SECTIONS: case GIMPLE_OMP_SECTIONS_SWITCH: case
GIMPLE_OMP_SINGLE: case GIMPLE_OMP_TARGET: case GIMPLE_OMP_TEAMS
: case GIMPLE_OMP_SCOPE: case GIMPLE_OMP_SECTION: case GIMPLE_OMP_MASTER
: case GIMPLE_OMP_MASKED: case GIMPLE_OMP_TASKGROUP: case GIMPLE_OMP_ORDERED
: case GIMPLE_OMP_CRITICAL: case GIMPLE_OMP_SCAN: case GIMPLE_OMP_RETURN
: case GIMPLE_OMP_ATOMIC_LOAD: case GIMPLE_OMP_ATOMIC_STORE: case
GIMPLE_OMP_CONTINUE
:
5124 /* OpenMP directives are validated by the FE and never operated
5125 on by the optimizers. Furthermore, GIMPLE_OMP_FOR may contain
5126 non-gimple expressions when the main index variable has had
5127 its address taken. This does not affect the loop itself
5128 because the header of an GIMPLE_OMP_FOR is merely used to determine
5129 how to setup the parallel iteration. */
5130 return false;
5131
5132 case GIMPLE_ASSUME:
5133 return false;
5134
5135 case GIMPLE_DEBUG:
5136 return verify_gimple_debug (stmt);
5137
5138 default:
5139 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5139, __FUNCTION__))
;
5140 }
5141}
5142
5143/* Verify the contents of a GIMPLE_PHI. Returns true if there is a problem,
5144 and false otherwise. */
5145
5146static bool
5147verify_gimple_phi (gphi *phi)
5148{
5149 bool err = false;
5150 unsigned i;
5151 tree phi_result = gimple_phi_result (phi);
5152 bool virtual_p;
5153
5154 if (!phi_result)
5155 {
5156 error ("invalid %<PHI%> result");
5157 return true;
5158 }
5159
5160 virtual_p = virtual_operand_p (phi_result);
5161 if (TREE_CODE (phi_result)((enum tree_code) (phi_result)->base.code) != SSA_NAME
5162 || (virtual_p
5163 && SSA_NAME_VAR (phi_result)((tree_check ((phi_result), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5163, __FUNCTION__, (SSA_NAME)))->ssa_name.var == (tree)
nullptr || ((enum tree_code) ((phi_result)->ssa_name.var)
->base.code) == IDENTIFIER_NODE ? (tree) nullptr : (phi_result
)->ssa_name.var)
!= gimple_vop (cfun(cfun + 0))))
5164 {
5165 error ("invalid %<PHI%> result");
5166 err = true;
5167 }
5168
5169 for (i = 0; i < gimple_phi_num_args (phi); i++)
5170 {
5171 tree t = gimple_phi_arg_def (phi, i);
5172
5173 if (!t)
5174 {
5175 error ("missing %<PHI%> def");
5176 err |= true;
5177 continue;
5178 }
5179 /* Addressable variables do have SSA_NAMEs but they
5180 are not considered gimple values. */
5181 else if ((TREE_CODE (t)((enum tree_code) (t)->base.code) == SSA_NAME
5182 && virtual_p != virtual_operand_p (t))
5183 || (virtual_p
5184 && (TREE_CODE (t)((enum tree_code) (t)->base.code) != SSA_NAME
5185 || SSA_NAME_VAR (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5185, __FUNCTION__, (SSA_NAME)))->ssa_name.var == (tree)
nullptr || ((enum tree_code) ((t)->ssa_name.var)->base
.code) == IDENTIFIER_NODE ? (tree) nullptr : (t)->ssa_name
.var)
!= gimple_vop (cfun(cfun + 0))))
5186 || (!virtual_p
5187 && !is_gimple_val (t)))
5188 {
5189 error ("invalid %<PHI%> argument");
5190 debug_generic_expr (t);
5191 err |= true;
5192 }
5193#ifdef ENABLE_TYPES_CHECKING1
5194 if (!useless_type_conversion_p (TREE_TYPE (phi_result)((contains_struct_check ((phi_result), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5194, __FUNCTION__))->typed.type)
, TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5194, __FUNCTION__))->typed.type)
))
5195 {
5196 error ("incompatible types in %<PHI%> argument %u", i);
5197 debug_generic_stmt (TREE_TYPE (phi_result)((contains_struct_check ((phi_result), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5197, __FUNCTION__))->typed.type)
);
5198 debug_generic_stmt (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5198, __FUNCTION__))->typed.type)
);
5199 err |= true;
5200 }
5201#endif
5202 }
5203
5204 return err;
5205}
5206
5207/* Verify the GIMPLE statements inside the sequence STMTS. */
5208
5209static bool
5210verify_gimple_in_seq_2 (gimple_seq stmts)
5211{
5212 gimple_stmt_iterator ittr;
5213 bool err = false;
5214
5215 for (ittr = gsi_start (stmts); !gsi_end_p (ittr); gsi_next (&ittr))
5216 {
5217 gimple *stmt = gsi_stmt (ittr);
5218
5219 switch (gimple_code (stmt))
5220 {
5221 case GIMPLE_BIND:
5222 err |= verify_gimple_in_seq_2 (
5223 gimple_bind_body (as_a <gbind *> (stmt)));
5224 break;
5225
5226 case GIMPLE_TRY:
5227 err |= verify_gimple_in_seq_2 (gimple_try_eval (stmt));
5228 err |= verify_gimple_in_seq_2 (gimple_try_cleanup (stmt));
5229 break;
5230
5231 case GIMPLE_EH_FILTER:
5232 err |= verify_gimple_in_seq_2 (gimple_eh_filter_failure (stmt));
5233 break;
5234
5235 case GIMPLE_EH_ELSE:
5236 {
5237 geh_else *eh_else = as_a <geh_else *> (stmt);
5238 err |= verify_gimple_in_seq_2 (gimple_eh_else_n_body (eh_else));
5239 err |= verify_gimple_in_seq_2 (gimple_eh_else_e_body (eh_else));
5240 }
5241 break;
5242
5243 case GIMPLE_CATCH:
5244 err |= verify_gimple_in_seq_2 (gimple_catch_handler (
5245 as_a <gcatch *> (stmt)));
5246 break;
5247
5248 case GIMPLE_ASSUME:
5249 err |= verify_gimple_in_seq_2 (gimple_assume_body (stmt));
5250 break;
5251
5252 case GIMPLE_TRANSACTION:
5253 err |= verify_gimple_transaction (as_a <gtransaction *> (stmt));
5254 break;
5255
5256 default:
5257 {
5258 bool err2 = verify_gimple_stmt (stmt);
5259 if (err2)
5260 debug_gimple_stmt (stmt);
5261 err |= err2;
5262 }
5263 }
5264 }
5265
5266 return err;
5267}
5268
5269/* Verify the contents of a GIMPLE_TRANSACTION. Returns true if there
5270 is a problem, otherwise false. */
5271
5272static bool
5273verify_gimple_transaction (gtransaction *stmt)
5274{
5275 tree lab;
5276
5277 lab = gimple_transaction_label_norm (stmt);
5278 if (lab != NULLnullptr && TREE_CODE (lab)((enum tree_code) (lab)->base.code) != LABEL_DECL)
5279 return true;
5280 lab = gimple_transaction_label_uninst (stmt);
5281 if (lab != NULLnullptr && TREE_CODE (lab)((enum tree_code) (lab)->base.code) != LABEL_DECL)
5282 return true;
5283 lab = gimple_transaction_label_over (stmt);
5284 if (lab != NULLnullptr && TREE_CODE (lab)((enum tree_code) (lab)->base.code) != LABEL_DECL)
5285 return true;
5286
5287 return verify_gimple_in_seq_2 (gimple_transaction_body (stmt));
5288}
5289
5290
5291/* Verify the GIMPLE statements inside the statement list STMTS. */
5292
5293DEBUG_FUNCTION__attribute__ ((__used__)) bool
5294verify_gimple_in_seq (gimple_seq stmts, bool ice)
5295{
5296 timevar_push (TV_TREE_STMT_VERIFY);
5297 bool res = verify_gimple_in_seq_2 (stmts);
5298 if (res && ice)
5299 internal_error ("%<verify_gimple%> failed");
5300 timevar_pop (TV_TREE_STMT_VERIFY);
5301 return res;
5302}
5303
5304/* Return true when the T can be shared. */
5305
5306static bool
5307tree_node_can_be_shared (tree t)
5308{
5309 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))
5310 || TREE_CODE (t)((enum tree_code) (t)->base.code) == SSA_NAME
5311 || TREE_CODE (t)((enum tree_code) (t)->base.code) == IDENTIFIER_NODE
5312 || TREE_CODE (t)((enum tree_code) (t)->base.code) == CASE_LABEL_EXPR
5313 || is_gimple_min_invariant (t))
5314 return true;
5315
5316 if (t == error_mark_nodeglobal_trees[TI_ERROR_MARK])
5317 return true;
5318
5319 return false;
5320}
5321
5322/* Called via walk_tree. Verify tree sharing. */
5323
5324static tree
5325verify_node_sharing_1 (tree *tp, int *walk_subtrees, void *data)
5326{
5327 hash_set<void *> *visited = (hash_set<void *> *) data;
5328
5329 if (tree_node_can_be_shared (*tp))
5330 {
5331 *walk_subtrees = false;
5332 return NULLnullptr;
5333 }
5334
5335 if (visited->add (*tp))
5336 return *tp;
5337
5338 return NULLnullptr;
5339}
5340
5341/* Called via walk_gimple_stmt. Verify tree sharing. */
5342
5343static tree
5344verify_node_sharing (tree *tp, int *walk_subtrees, void *data)
5345{
5346 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
5347 return verify_node_sharing_1 (tp, walk_subtrees, wi->info);
5348}
5349
5350static bool eh_error_found;
5351bool
5352verify_eh_throw_stmt_node (gimple *const &stmt, const int &,
5353 hash_set<gimple *> *visited)
5354{
5355 if (!visited->contains (stmt))
5356 {
5357 error ("dead statement in EH table");
5358 debug_gimple_stmt (stmt);
5359 eh_error_found = true;
5360 }
5361 return true;
5362}
5363
5364/* Verify if the location LOCs block is in BLOCKS. */
5365
5366static bool
5367verify_location (hash_set<tree> *blocks, location_t loc)
5368{
5369 tree block = LOCATION_BLOCK (loc)((tree) ((IS_ADHOC_LOC (loc)) ? get_data_from_adhoc_loc (line_table
, (loc)) : nullptr))
;
5370 if (block != NULL_TREE(tree) nullptr
5371 && !blocks->contains (block))
5372 {
5373 error ("location references block not in block tree");
5374 return true;
5375 }
5376 if (block != NULL_TREE(tree) nullptr)
5377 return verify_location (blocks, BLOCK_SOURCE_LOCATION (block)((tree_check ((block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5377, __FUNCTION__, (BLOCK)))->block.locus)
);
5378 return false;
5379}
5380
5381/* Called via walk_tree. Verify that expressions have no blocks. */
5382
5383static tree
5384verify_expr_no_block (tree *tp, int *walk_subtrees, void *)
5385{
5386 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)
)
5387 {
5388 *walk_subtrees = false;
5389 return NULLnullptr;
5390 }
5391
5392 location_t loc = EXPR_LOCATION (*tp)((((*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
)) ? (*tp)->exp.locus : ((location_t) 0))
;
5393 if (LOCATION_BLOCK (loc)((tree) ((IS_ADHOC_LOC (loc)) ? get_data_from_adhoc_loc (line_table
, (loc)) : nullptr))
!= NULLnullptr)
5394 return *tp;
5395
5396 return NULLnullptr;
5397}
5398
5399/* Called via walk_tree. Verify locations of expressions. */
5400
5401static tree
5402verify_expr_location_1 (tree *tp, int *walk_subtrees, void *data)
5403{
5404 hash_set<tree> *blocks = (hash_set<tree> *) data;
5405 tree t = *tp;
5406
5407 /* ??? This doesn't really belong here but there's no good place to
5408 stick this remainder of old verify_expr. */
5409 /* ??? This barfs on debug stmts which contain binds to vars with
5410 different function context. */
5411#if 0
5412 if (VAR_P (t)(((enum tree_code) (t)->base.code) == VAR_DECL)
5413 || TREE_CODE (t)((enum tree_code) (t)->base.code) == PARM_DECL
5414 || TREE_CODE (t)((enum tree_code) (t)->base.code) == RESULT_DECL)
5415 {
5416 tree context = decl_function_context (t);
5417 if (context != cfun(cfun + 0)->decl
5418 && !SCOPE_FILE_SCOPE_P (context)(! (context) || ((enum tree_code) (context)->base.code) ==
TRANSLATION_UNIT_DECL)
5419 && !TREE_STATIC (t)((t)->base.static_flag)
5420 && !DECL_EXTERNAL (t)((contains_struct_check ((t), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5420, __FUNCTION__))->decl_common.decl_flag_1)
)
5421 {
5422 error ("local declaration from a different function");
5423 return t;
5424 }
5425 }
5426#endif
5427
5428 if (VAR_P (t)(((enum tree_code) (t)->base.code) == VAR_DECL) && DECL_HAS_DEBUG_EXPR_P (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5428, __FUNCTION__, (VAR_DECL)))->decl_common.debug_expr_is_from
)
)
5429 {
5430 tree x = DECL_DEBUG_EXPR (t)(decl_debug_expr_lookup ((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5430, __FUNCTION__, (VAR_DECL)))))
;
5431 tree addr = walk_tree (&x, verify_expr_no_block, NULL, NULL)walk_tree_1 (&x, verify_expr_no_block, nullptr, nullptr, nullptr
)
;
5432 if (addr)
5433 return addr;
5434 }
5435 if ((VAR_P (t)(((enum tree_code) (t)->base.code) == VAR_DECL)
5436 || TREE_CODE (t)((enum tree_code) (t)->base.code) == PARM_DECL
5437 || TREE_CODE (t)((enum tree_code) (t)->base.code) == RESULT_DECL)
5438 && DECL_HAS_VALUE_EXPR_P (t)((tree_check3 ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5438, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL))
) ->decl_common.decl_flag_2)
)
5439 {
5440 tree x = DECL_VALUE_EXPR (t)(decl_value_expr_lookup ((contains_struct_check ((t), (TS_DECL_WRTL
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5440, __FUNCTION__))))
;
5441 tree addr = walk_tree (&x, verify_expr_no_block, NULL, NULL)walk_tree_1 (&x, verify_expr_no_block, nullptr, nullptr, nullptr
)
;
5442 if (addr)
5443 return addr;
5444 }
5445
5446 if (!EXPR_P (t)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum
tree_code) (t)->base.code))]) >= tcc_reference &&
(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum
tree_code) (t)->base.code))]) <= tcc_expression)
)
5447 {
5448 *walk_subtrees = false;
5449 return NULLnullptr;
5450 }
5451
5452 location_t loc = EXPR_LOCATION (t)((((t)) && ((tree_code_type_tmpl <0>::tree_code_type
[(int) (((enum tree_code) ((t))->base.code))]) >= tcc_reference
&& (tree_code_type_tmpl <0>::tree_code_type[(int
) (((enum tree_code) ((t))->base.code))]) <= tcc_expression
)) ? (t)->exp.locus : ((location_t) 0))
;
5453 if (verify_location (blocks, loc))
5454 return t;
5455
5456 return NULLnullptr;
5457}
5458
5459/* Called via walk_gimple_op. Verify locations of expressions. */
5460
5461static tree
5462verify_expr_location (tree *tp, int *walk_subtrees, void *data)
5463{
5464 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
5465 return verify_expr_location_1 (tp, walk_subtrees, wi->info);
5466}
5467
5468/* Insert all subblocks of BLOCK into BLOCKS and recurse. */
5469
5470static void
5471collect_subblocks (hash_set<tree> *blocks, tree block)
5472{
5473 tree t;
5474 for (t = BLOCK_SUBBLOCKS (block)((tree_check ((block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5474, __FUNCTION__, (BLOCK)))->block.subblocks)
; t; t = BLOCK_CHAIN (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5474, __FUNCTION__, (BLOCK)))->block.chain)
)
5475 {
5476 blocks->add (t);
5477 collect_subblocks (blocks, t);
5478 }
5479}
5480
5481/* Disable warnings about missing quoting in GCC diagnostics for
5482 the verification errors. Their format strings don't follow
5483 GCC diagnostic conventions and trigger an ICE in the end. */
5484#if __GNUC__4 >= 10
5485# pragma GCC diagnostic push
5486# pragma GCC diagnostic ignored "-Wformat-diag"
5487#endif
5488
5489/* Verify the GIMPLE statements in the CFG of FN. */
5490
5491DEBUG_FUNCTION__attribute__ ((__used__)) bool
5492verify_gimple_in_cfg (struct function *fn, bool verify_nothrow, bool ice)
5493{
5494 basic_block bb;
5495 bool err = false;
5496
5497 timevar_push (TV_TREE_STMT_VERIFY);
5498 hash_set<void *> visited;
5499 hash_set<gimple *> visited_throwing_stmts;
5500
5501 /* Collect all BLOCKs referenced by the BLOCK tree of FN. */
5502 hash_set<tree> blocks;
5503 if (DECL_INITIAL (fn->decl)((contains_struct_check ((fn->decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5503, __FUNCTION__))->decl_common.initial)
)
5504 {
5505 blocks.add (DECL_INITIAL (fn->decl)((contains_struct_check ((fn->decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5505, __FUNCTION__))->decl_common.initial)
);
5506 collect_subblocks (&blocks, DECL_INITIAL (fn->decl)((contains_struct_check ((fn->decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/tree-cfg.cc"
, 5506, __FUNCTION__))->decl_common.initial)
);
5507 }
5508
5509 FOR_EACH_BB_FN (bb, fn)for (bb = (fn)->cfg->x_entry_block_ptr->next_bb; bb !=
(fn)->cfg->x_exit_block_ptr; bb = bb->next_bb)
5510 {
5511 gimple_stmt_iterator gsi;
5512 edge_iterator ei;
5513 edge e;
5514
5515 for (gphi_iterator gpi = gsi_start_phis (bb);
5516 !gsi_end_p (gpi);
5517 gsi_next (&gpi))
5518 {
5519 gphi *phi = gpi.phi ();
5520 bool err2 = false;
5521 unsigned i;
5522
5523 if (gimple_bb (phi) != bb)
5524 {
5525 error ("gimple_bb (phi) is set to a wrong basic block");
5526 err2 = true;
5527 }
5528
5529 err2 |= verify_gimple_phi (phi);
5530
5531 /* Only PHI arguments have locations. */
5532 if (gimple_location (phi) != UNKNOWN_LOCATION((location_t) 0))
5533 {
5534 error ("PHI node with location");
5535 err2 = true;
5536 }
5537
5538 for (i = 0; i < gimple_phi_num_args (phi); i++)
5539 {
5540 tree arg = gimple_phi_arg_def (phi, i);
5541 tree addr = walk_tree (&arg, verify_node_sharing_1,walk_tree_1 (&arg, verify_node_sharing_1, &visited, nullptr
, nullptr)
5542 &visited, NULL)walk_tree_1 (&arg, verify_node_sharing_1, &visited, nullptr
, nullptr)
;
5543 if (addr)
5544 {
5545 error ("incorrect sharing of tree nodes");
5546 debug_generic_expr (addr);
5547 err2 |= true;
5548 }
5549 location_t loc = gimple_phi_arg_location (phi, i);
5550 if (virtual_operand_p (gimple_phi_result (phi))
5551 && loc != UNKNOWN_LOCATION((location_t) 0))
5552 {
5553 error ("virtual PHI with argument locations");
5554 err2 = true;
5555 }
5556 addr = walk_tree (&arg, verify_expr_location_1, &blocks, NULL)walk_tree_1 (&arg, verify_expr_location_1, &blocks, nullptr
, nullptr)
;
5557 if (addr)
5558 {
5559 debug_generic_expr (addr);
5560 err2 = true;
5561 }
5562 err2 |= verify_location (&blocks, loc);
5563 }
5564
5565 if (err2)
5566 debug_gimple_stmt (phi);
5567 err |= err2;
5568 }
5569
5570 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5571 {
5572 gimple *stmt = gsi_stmt (gsi);
5573 bool err2 = false;
5574 struct walk_stmt_info wi;
5575 tree addr;
5576 int lp_nr;
5577
5578 if (gimple_bb (stmt) != bb)
5579 {
5580 error ("gimple_bb (stmt) is set to a wrong basic block");
5581 err2 = true;
5582 }
5583
5584 err2 |= verify_gimple_stmt (stmt);
5585 err2 |= verify_location (&blocks, gimple_location (stmt));
5586
5587 memset (&wi, 0, sizeof (wi));
5588 wi.info = (void *) &visited;
5589 addr = walk_gimple_op (stmt, verify_node_sharing, &wi);
5590 if (addr)
5591 {
5592 error ("incorrect sharing of tree nodes");
5593 debug_generic_expr (addr);
5594 err2 |= true;
5595 }
5596
5597 memset (&wi, 0, sizeof (wi));
5598 wi.info = (void *) &blocks;
5599 addr = walk_gimple_op (stmt, verify_expr_location, &wi);
5600 if (addr)
5601 {
5602 debug_generic_expr (addr);
5603 err2 |= true;
5604 }
5605
5606 /* If the statement is marked as part of an EH region, then it is
5607 expected that the statement could throw. Verify that when we
5608 have optimizations that simplify statements such that we prove
5609 that they cannot throw, that we update other data structures
5610 to match. */
5611 lp_nr = lookup_stmt_eh_lp (stmt);
5612 if (lp_nr != 0)
5613 visited_throwing_stmts.add (stmt);
5614 if (lp_nr > 0)
5615 {
5616 if (!stmt_could_throw_p (cfun(cfun + 0), stmt))
5617 {
5618 if (verify_nothrow)
5619 {
5620 error ("statement marked for throw, but doesn%'t");
5621 err2 |= true;
5622 }
5623 }
5624 else if (!gsi_one_before_end_p (gsi))
5625 {
5626 error ("statement marked for throw in middle of block");
5627 err2 |= true;
5628 }
5629 }
5630
5631 if (err2)
5632 debug_gimple_stmt (stmt);
5633 err |= err2;
5634 }
5635
5636 FOR_EACH_EDGE (e, ei, bb->succs)for ((ei) = ei_start_1 (&((bb->succs))); ei_cond ((ei)
, &(e)); ei_next (&(ei)))
5637 if (e->goto_locus != UNKNOWN_LOCATION((location_t) 0))
5638 err |= verify_location (&blocks, e->goto_locus);
5639 }
5640
5641 hash_map<gimple *, int> *eh_table = get_eh_throw_stmt_table (cfun(cfun + 0));
5642 eh_error_found = false;
5643 if (eh_table)
5644 eh_table->traverse<hash_set<gimple *> *, verify_eh_throw_stmt_node>
5645 (&visited_throwing_stmts);
5646
5647 if (ice && (err || eh_error_found))
5648 internal_error ("verify_gimple failed");
5649
5650 verify_histograms ();
5651 timevar_pop (TV_TREE_STMT_VERIFY);