remove has_execute
[platform/upstream/gcc.git] / gcc / tree-eh.c
1 /* Exception handling semantics and decomposition for trees.
2    Copyright (C) 2003-2014 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "hash-table.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "expr.h"
27 #include "calls.h"
28 #include "flags.h"
29 #include "function.h"
30 #include "except.h"
31 #include "pointer-set.h"
32 #include "basic-block.h"
33 #include "tree-ssa-alias.h"
34 #include "internal-fn.h"
35 #include "tree-eh.h"
36 #include "gimple-expr.h"
37 #include "is-a.h"
38 #include "gimple.h"
39 #include "gimple-iterator.h"
40 #include "gimple-ssa.h"
41 #include "cgraph.h"
42 #include "tree-cfg.h"
43 #include "tree-phinodes.h"
44 #include "ssa-iterators.h"
45 #include "stringpool.h"
46 #include "tree-ssanames.h"
47 #include "tree-into-ssa.h"
48 #include "tree-ssa.h"
49 #include "tree-inline.h"
50 #include "tree-pass.h"
51 #include "langhooks.h"
52 #include "diagnostic-core.h"
53 #include "target.h"
54 #include "cfgloop.h"
55 #include "gimple-low.h"
56
57 /* In some instances a tree and a gimple need to be stored in a same table,
58    i.e. in hash tables. This is a structure to do this. */
59 typedef union {tree *tp; tree t; gimple g;} treemple;
60
61 /* Misc functions used in this file.  */
62
63 /* Remember and lookup EH landing pad data for arbitrary statements.
64    Really this means any statement that could_throw_p.  We could
65    stuff this information into the stmt_ann data structure, but:
66
67    (1) We absolutely rely on this information being kept until
68    we get to rtl.  Once we're done with lowering here, if we lose
69    the information there's no way to recover it!
70
71    (2) There are many more statements that *cannot* throw as
72    compared to those that can.  We should be saving some amount
73    of space by only allocating memory for those that can throw.  */
74
75 /* Add statement T in function IFUN to landing pad NUM.  */
76
77 static void
78 add_stmt_to_eh_lp_fn (struct function *ifun, gimple t, int num)
79 {
80   struct throw_stmt_node *n;
81   void **slot;
82
83   gcc_assert (num != 0);
84
85   n = ggc_alloc<throw_stmt_node> ();
86   n->stmt = t;
87   n->lp_nr = num;
88
89   if (!get_eh_throw_stmt_table (ifun))
90     set_eh_throw_stmt_table (ifun, htab_create_ggc (31, struct_ptr_hash,
91                                                     struct_ptr_eq,
92                                                     ggc_free));
93
94   slot = htab_find_slot (get_eh_throw_stmt_table (ifun), n, INSERT);
95   gcc_assert (!*slot);
96   *slot = n;
97 }
98
99 /* Add statement T in the current function (cfun) to EH landing pad NUM.  */
100
101 void
102 add_stmt_to_eh_lp (gimple t, int num)
103 {
104   add_stmt_to_eh_lp_fn (cfun, t, num);
105 }
106
107 /* Add statement T to the single EH landing pad in REGION.  */
108
109 static void
110 record_stmt_eh_region (eh_region region, gimple t)
111 {
112   if (region == NULL)
113     return;
114   if (region->type == ERT_MUST_NOT_THROW)
115     add_stmt_to_eh_lp_fn (cfun, t, -region->index);
116   else
117     {
118       eh_landing_pad lp = region->landing_pads;
119       if (lp == NULL)
120         lp = gen_eh_landing_pad (region);
121       else
122         gcc_assert (lp->next_lp == NULL);
123       add_stmt_to_eh_lp_fn (cfun, t, lp->index);
124     }
125 }
126
127
128 /* Remove statement T in function IFUN from its EH landing pad.  */
129
130 bool
131 remove_stmt_from_eh_lp_fn (struct function *ifun, gimple t)
132 {
133   struct throw_stmt_node dummy;
134   void **slot;
135
136   if (!get_eh_throw_stmt_table (ifun))
137     return false;
138
139   dummy.stmt = t;
140   slot = htab_find_slot (get_eh_throw_stmt_table (ifun), &dummy,
141                         NO_INSERT);
142   if (slot)
143     {
144       htab_clear_slot (get_eh_throw_stmt_table (ifun), slot);
145       return true;
146     }
147   else
148     return false;
149 }
150
151
152 /* Remove statement T in the current function (cfun) from its
153    EH landing pad.  */
154
155 bool
156 remove_stmt_from_eh_lp (gimple t)
157 {
158   return remove_stmt_from_eh_lp_fn (cfun, t);
159 }
160
161 /* Determine if statement T is inside an EH region in function IFUN.
162    Positive numbers indicate a landing pad index; negative numbers
163    indicate a MUST_NOT_THROW region index; zero indicates that the
164    statement is not recorded in the region table.  */
165
166 int
167 lookup_stmt_eh_lp_fn (struct function *ifun, gimple t)
168 {
169   struct throw_stmt_node *p, n;
170
171   if (ifun->eh->throw_stmt_table == NULL)
172     return 0;
173
174   n.stmt = t;
175   p = (struct throw_stmt_node *) htab_find (ifun->eh->throw_stmt_table, &n);
176   return p ? p->lp_nr : 0;
177 }
178
179 /* Likewise, but always use the current function.  */
180
181 int
182 lookup_stmt_eh_lp (gimple t)
183 {
184   /* We can get called from initialized data when -fnon-call-exceptions
185      is on; prevent crash.  */
186   if (!cfun)
187     return 0;
188   return lookup_stmt_eh_lp_fn (cfun, t);
189 }
190
191 /* First pass of EH node decomposition.  Build up a tree of GIMPLE_TRY_FINALLY
192    nodes and LABEL_DECL nodes.  We will use this during the second phase to
193    determine if a goto leaves the body of a TRY_FINALLY_EXPR node.  */
194
195 struct finally_tree_node
196 {
197   /* When storing a GIMPLE_TRY, we have to record a gimple.  However
198      when deciding whether a GOTO to a certain LABEL_DECL (which is a
199      tree) leaves the TRY block, its necessary to record a tree in
200      this field.  Thus a treemple is used. */
201   treemple child;
202   gimple parent;
203 };
204
205 /* Hashtable helpers.  */
206
207 struct finally_tree_hasher : typed_free_remove <finally_tree_node>
208 {
209   typedef finally_tree_node value_type;
210   typedef finally_tree_node compare_type;
211   static inline hashval_t hash (const value_type *);
212   static inline bool equal (const value_type *, const compare_type *);
213 };
214
215 inline hashval_t
216 finally_tree_hasher::hash (const value_type *v)
217 {
218   return (intptr_t)v->child.t >> 4;
219 }
220
221 inline bool
222 finally_tree_hasher::equal (const value_type *v, const compare_type *c)
223 {
224   return v->child.t == c->child.t;
225 }
226
227 /* Note that this table is *not* marked GTY.  It is short-lived.  */
228 static hash_table<finally_tree_hasher> *finally_tree;
229
230 static void
231 record_in_finally_tree (treemple child, gimple parent)
232 {
233   struct finally_tree_node *n;
234   finally_tree_node **slot;
235
236   n = XNEW (struct finally_tree_node);
237   n->child = child;
238   n->parent = parent;
239
240   slot = finally_tree->find_slot (n, INSERT);
241   gcc_assert (!*slot);
242   *slot = n;
243 }
244
245 static void
246 collect_finally_tree (gimple stmt, gimple region);
247
248 /* Go through the gimple sequence.  Works with collect_finally_tree to
249    record all GIMPLE_LABEL and GIMPLE_TRY statements. */
250
251 static void
252 collect_finally_tree_1 (gimple_seq seq, gimple region)
253 {
254   gimple_stmt_iterator gsi;
255
256   for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
257     collect_finally_tree (gsi_stmt (gsi), region);
258 }
259
260 static void
261 collect_finally_tree (gimple stmt, gimple region)
262 {
263   treemple temp;
264
265   switch (gimple_code (stmt))
266     {
267     case GIMPLE_LABEL:
268       temp.t = gimple_label_label (stmt);
269       record_in_finally_tree (temp, region);
270       break;
271
272     case GIMPLE_TRY:
273       if (gimple_try_kind (stmt) == GIMPLE_TRY_FINALLY)
274         {
275           temp.g = stmt;
276           record_in_finally_tree (temp, region);
277           collect_finally_tree_1 (gimple_try_eval (stmt), stmt);
278           collect_finally_tree_1 (gimple_try_cleanup (stmt), region);
279         }
280       else if (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH)
281         {
282           collect_finally_tree_1 (gimple_try_eval (stmt), region);
283           collect_finally_tree_1 (gimple_try_cleanup (stmt), region);
284         }
285       break;
286
287     case GIMPLE_CATCH:
288       collect_finally_tree_1 (gimple_catch_handler (stmt), region);
289       break;
290
291     case GIMPLE_EH_FILTER:
292       collect_finally_tree_1 (gimple_eh_filter_failure (stmt), region);
293       break;
294
295     case GIMPLE_EH_ELSE:
296       collect_finally_tree_1 (gimple_eh_else_n_body (stmt), region);
297       collect_finally_tree_1 (gimple_eh_else_e_body (stmt), region);
298       break;
299
300     default:
301       /* A type, a decl, or some kind of statement that we're not
302          interested in.  Don't walk them.  */
303       break;
304     }
305 }
306
307
308 /* Use the finally tree to determine if a jump from START to TARGET
309    would leave the try_finally node that START lives in.  */
310
311 static bool
312 outside_finally_tree (treemple start, gimple target)
313 {
314   struct finally_tree_node n, *p;
315
316   do
317     {
318       n.child = start;
319       p = finally_tree->find (&n);
320       if (!p)
321         return true;
322       start.g = p->parent;
323     }
324   while (start.g != target);
325
326   return false;
327 }
328
329 /* Second pass of EH node decomposition.  Actually transform the GIMPLE_TRY
330    nodes into a set of gotos, magic labels, and eh regions.
331    The eh region creation is straight-forward, but frobbing all the gotos
332    and such into shape isn't.  */
333
334 /* The sequence into which we record all EH stuff.  This will be
335    placed at the end of the function when we're all done.  */
336 static gimple_seq eh_seq;
337
338 /* Record whether an EH region contains something that can throw,
339    indexed by EH region number.  */
340 static bitmap eh_region_may_contain_throw_map;
341
342 /* The GOTO_QUEUE is is an array of GIMPLE_GOTO and GIMPLE_RETURN
343    statements that are seen to escape this GIMPLE_TRY_FINALLY node.
344    The idea is to record a gimple statement for everything except for
345    the conditionals, which get their labels recorded. Since labels are
346    of type 'tree', we need this node to store both gimple and tree
347    objects.  REPL_STMT is the sequence used to replace the goto/return
348    statement.  CONT_STMT is used to store the statement that allows
349    the return/goto to jump to the original destination. */
350
351 struct goto_queue_node
352 {
353   treemple stmt;
354   location_t location;
355   gimple_seq repl_stmt;
356   gimple cont_stmt;
357   int index;
358   /* This is used when index >= 0 to indicate that stmt is a label (as
359      opposed to a goto stmt).  */
360   int is_label;
361 };
362
363 /* State of the world while lowering.  */
364
365 struct leh_state
366 {
367   /* What's "current" while constructing the eh region tree.  These
368      correspond to variables of the same name in cfun->eh, which we
369      don't have easy access to.  */
370   eh_region cur_region;
371
372   /* What's "current" for the purposes of __builtin_eh_pointer.  For
373      a CATCH, this is the associated TRY.  For an EH_FILTER, this is
374      the associated ALLOWED_EXCEPTIONS, etc.  */
375   eh_region ehp_region;
376
377   /* Processing of TRY_FINALLY requires a bit more state.  This is
378      split out into a separate structure so that we don't have to
379      copy so much when processing other nodes.  */
380   struct leh_tf_state *tf;
381 };
382
383 struct leh_tf_state
384 {
385   /* Pointer to the GIMPLE_TRY_FINALLY node under discussion.  The
386      try_finally_expr is the original GIMPLE_TRY_FINALLY.  We need to retain
387      this so that outside_finally_tree can reliably reference the tree used
388      in the collect_finally_tree data structures.  */
389   gimple try_finally_expr;
390   gimple top_p;
391
392   /* While lowering a top_p usually it is expanded into multiple statements,
393      thus we need the following field to store them. */
394   gimple_seq top_p_seq;
395
396   /* The state outside this try_finally node.  */
397   struct leh_state *outer;
398
399   /* The exception region created for it.  */
400   eh_region region;
401
402   /* The goto queue.  */
403   struct goto_queue_node *goto_queue;
404   size_t goto_queue_size;
405   size_t goto_queue_active;
406
407   /* Pointer map to help in searching goto_queue when it is large.  */
408   struct pointer_map_t *goto_queue_map;
409
410   /* The set of unique labels seen as entries in the goto queue.  */
411   vec<tree> dest_array;
412
413   /* A label to be added at the end of the completed transformed
414      sequence.  It will be set if may_fallthru was true *at one time*,
415      though subsequent transformations may have cleared that flag.  */
416   tree fallthru_label;
417
418   /* True if it is possible to fall out the bottom of the try block.
419      Cleared if the fallthru is converted to a goto.  */
420   bool may_fallthru;
421
422   /* True if any entry in goto_queue is a GIMPLE_RETURN.  */
423   bool may_return;
424
425   /* True if the finally block can receive an exception edge.
426      Cleared if the exception case is handled by code duplication.  */
427   bool may_throw;
428 };
429
430 static gimple_seq lower_eh_must_not_throw (struct leh_state *, gimple);
431
432 /* Search for STMT in the goto queue.  Return the replacement,
433    or null if the statement isn't in the queue.  */
434
435 #define LARGE_GOTO_QUEUE 20
436
437 static void lower_eh_constructs_1 (struct leh_state *state, gimple_seq *seq);
438
439 static gimple_seq
440 find_goto_replacement (struct leh_tf_state *tf, treemple stmt)
441 {
442   unsigned int i;
443   void **slot;
444
445   if (tf->goto_queue_active < LARGE_GOTO_QUEUE)
446     {
447       for (i = 0; i < tf->goto_queue_active; i++)
448         if ( tf->goto_queue[i].stmt.g == stmt.g)
449           return tf->goto_queue[i].repl_stmt;
450       return NULL;
451     }
452
453   /* If we have a large number of entries in the goto_queue, create a
454      pointer map and use that for searching.  */
455
456   if (!tf->goto_queue_map)
457     {
458       tf->goto_queue_map = pointer_map_create ();
459       for (i = 0; i < tf->goto_queue_active; i++)
460         {
461           slot = pointer_map_insert (tf->goto_queue_map,
462                                      tf->goto_queue[i].stmt.g);
463           gcc_assert (*slot == NULL);
464           *slot = &tf->goto_queue[i];
465         }
466     }
467
468   slot = pointer_map_contains (tf->goto_queue_map, stmt.g);
469   if (slot != NULL)
470     return (((struct goto_queue_node *) *slot)->repl_stmt);
471
472   return NULL;
473 }
474
475 /* A subroutine of replace_goto_queue_1.  Handles the sub-clauses of a
476    lowered GIMPLE_COND.  If, by chance, the replacement is a simple goto,
477    then we can just splat it in, otherwise we add the new stmts immediately
478    after the GIMPLE_COND and redirect.  */
479
480 static void
481 replace_goto_queue_cond_clause (tree *tp, struct leh_tf_state *tf,
482                                 gimple_stmt_iterator *gsi)
483 {
484   tree label;
485   gimple_seq new_seq;
486   treemple temp;
487   location_t loc = gimple_location (gsi_stmt (*gsi));
488
489   temp.tp = tp;
490   new_seq = find_goto_replacement (tf, temp);
491   if (!new_seq)
492     return;
493
494   if (gimple_seq_singleton_p (new_seq)
495       && gimple_code (gimple_seq_first_stmt (new_seq)) == GIMPLE_GOTO)
496     {
497       *tp = gimple_goto_dest (gimple_seq_first_stmt (new_seq));
498       return;
499     }
500
501   label = create_artificial_label (loc);
502   /* Set the new label for the GIMPLE_COND */
503   *tp = label;
504
505   gsi_insert_after (gsi, gimple_build_label (label), GSI_CONTINUE_LINKING);
506   gsi_insert_seq_after (gsi, gimple_seq_copy (new_seq), GSI_CONTINUE_LINKING);
507 }
508
509 /* The real work of replace_goto_queue.  Returns with TSI updated to
510    point to the next statement.  */
511
512 static void replace_goto_queue_stmt_list (gimple_seq *, struct leh_tf_state *);
513
514 static void
515 replace_goto_queue_1 (gimple stmt, struct leh_tf_state *tf,
516                       gimple_stmt_iterator *gsi)
517 {
518   gimple_seq seq;
519   treemple temp;
520   temp.g = NULL;
521
522   switch (gimple_code (stmt))
523     {
524     case GIMPLE_GOTO:
525     case GIMPLE_RETURN:
526       temp.g = stmt;
527       seq = find_goto_replacement (tf, temp);
528       if (seq)
529         {
530           gsi_insert_seq_before (gsi, gimple_seq_copy (seq), GSI_SAME_STMT);
531           gsi_remove (gsi, false);
532           return;
533         }
534       break;
535
536     case GIMPLE_COND:
537       replace_goto_queue_cond_clause (gimple_op_ptr (stmt, 2), tf, gsi);
538       replace_goto_queue_cond_clause (gimple_op_ptr (stmt, 3), tf, gsi);
539       break;
540
541     case GIMPLE_TRY:
542       replace_goto_queue_stmt_list (gimple_try_eval_ptr (stmt), tf);
543       replace_goto_queue_stmt_list (gimple_try_cleanup_ptr (stmt), tf);
544       break;
545     case GIMPLE_CATCH:
546       replace_goto_queue_stmt_list (gimple_catch_handler_ptr (stmt), tf);
547       break;
548     case GIMPLE_EH_FILTER:
549       replace_goto_queue_stmt_list (gimple_eh_filter_failure_ptr (stmt), tf);
550       break;
551     case GIMPLE_EH_ELSE:
552       replace_goto_queue_stmt_list (gimple_eh_else_n_body_ptr (stmt), tf);
553       replace_goto_queue_stmt_list (gimple_eh_else_e_body_ptr (stmt), tf);
554       break;
555
556     default:
557       /* These won't have gotos in them.  */
558       break;
559     }
560
561   gsi_next (gsi);
562 }
563
564 /* A subroutine of replace_goto_queue.  Handles GIMPLE_SEQ.  */
565
566 static void
567 replace_goto_queue_stmt_list (gimple_seq *seq, struct leh_tf_state *tf)
568 {
569   gimple_stmt_iterator gsi = gsi_start (*seq);
570
571   while (!gsi_end_p (gsi))
572     replace_goto_queue_1 (gsi_stmt (gsi), tf, &gsi);
573 }
574
575 /* Replace all goto queue members.  */
576
577 static void
578 replace_goto_queue (struct leh_tf_state *tf)
579 {
580   if (tf->goto_queue_active == 0)
581     return;
582   replace_goto_queue_stmt_list (&tf->top_p_seq, tf);
583   replace_goto_queue_stmt_list (&eh_seq, tf);
584 }
585
586 /* Add a new record to the goto queue contained in TF. NEW_STMT is the
587    data to be added, IS_LABEL indicates whether NEW_STMT is a label or
588    a gimple return. */
589
590 static void
591 record_in_goto_queue (struct leh_tf_state *tf,
592                       treemple new_stmt,
593                       int index,
594                       bool is_label,
595                       location_t location)
596 {
597   size_t active, size;
598   struct goto_queue_node *q;
599
600   gcc_assert (!tf->goto_queue_map);
601
602   active = tf->goto_queue_active;
603   size = tf->goto_queue_size;
604   if (active >= size)
605     {
606       size = (size ? size * 2 : 32);
607       tf->goto_queue_size = size;
608       tf->goto_queue
609          = XRESIZEVEC (struct goto_queue_node, tf->goto_queue, size);
610     }
611
612   q = &tf->goto_queue[active];
613   tf->goto_queue_active = active + 1;
614
615   memset (q, 0, sizeof (*q));
616   q->stmt = new_stmt;
617   q->index = index;
618   q->location = location;
619   q->is_label = is_label;
620 }
621
622 /* Record the LABEL label in the goto queue contained in TF.
623    TF is not null.  */
624
625 static void
626 record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt, tree label,
627                             location_t location)
628 {
629   int index;
630   treemple temp, new_stmt;
631
632   if (!label)
633     return;
634
635   /* Computed and non-local gotos do not get processed.  Given
636      their nature we can neither tell whether we've escaped the
637      finally block nor redirect them if we knew.  */
638   if (TREE_CODE (label) != LABEL_DECL)
639     return;
640
641   /* No need to record gotos that don't leave the try block.  */
642   temp.t = label;
643   if (!outside_finally_tree (temp, tf->try_finally_expr))
644     return;
645
646   if (! tf->dest_array.exists ())
647     {
648       tf->dest_array.create (10);
649       tf->dest_array.quick_push (label);
650       index = 0;
651     }
652   else
653     {
654       int n = tf->dest_array.length ();
655       for (index = 0; index < n; ++index)
656         if (tf->dest_array[index] == label)
657           break;
658       if (index == n)
659         tf->dest_array.safe_push (label);
660     }
661
662   /* In the case of a GOTO we want to record the destination label,
663      since with a GIMPLE_COND we have an easy access to the then/else
664      labels. */
665   new_stmt = stmt;
666   record_in_goto_queue (tf, new_stmt, index, true, location);
667 }
668
669 /* For any GIMPLE_GOTO or GIMPLE_RETURN, decide whether it leaves a try_finally
670    node, and if so record that fact in the goto queue associated with that
671    try_finally node.  */
672
673 static void
674 maybe_record_in_goto_queue (struct leh_state *state, gimple stmt)
675 {
676   struct leh_tf_state *tf = state->tf;
677   treemple new_stmt;
678
679   if (!tf)
680     return;
681
682   switch (gimple_code (stmt))
683     {
684     case GIMPLE_COND:
685       new_stmt.tp = gimple_op_ptr (stmt, 2);
686       record_in_goto_queue_label (tf, new_stmt, gimple_cond_true_label (stmt),
687                                   EXPR_LOCATION (*new_stmt.tp));
688       new_stmt.tp = gimple_op_ptr (stmt, 3);
689       record_in_goto_queue_label (tf, new_stmt, gimple_cond_false_label (stmt),
690                                   EXPR_LOCATION (*new_stmt.tp));
691       break;
692     case GIMPLE_GOTO:
693       new_stmt.g = stmt;
694       record_in_goto_queue_label (tf, new_stmt, gimple_goto_dest (stmt),
695                                   gimple_location (stmt));
696       break;
697
698     case GIMPLE_RETURN:
699       tf->may_return = true;
700       new_stmt.g = stmt;
701       record_in_goto_queue (tf, new_stmt, -1, false, gimple_location (stmt));
702       break;
703
704     default:
705       gcc_unreachable ();
706     }
707 }
708
709
710 #ifdef ENABLE_CHECKING
711 /* We do not process GIMPLE_SWITCHes for now.  As long as the original source
712    was in fact structured, and we've not yet done jump threading, then none
713    of the labels will leave outer GIMPLE_TRY_FINALLY nodes. Verify this.  */
714
715 static void
716 verify_norecord_switch_expr (struct leh_state *state, gimple switch_expr)
717 {
718   struct leh_tf_state *tf = state->tf;
719   size_t i, n;
720
721   if (!tf)
722     return;
723
724   n = gimple_switch_num_labels (switch_expr);
725
726   for (i = 0; i < n; ++i)
727     {
728       treemple temp;
729       tree lab = CASE_LABEL (gimple_switch_label (switch_expr, i));
730       temp.t = lab;
731       gcc_assert (!outside_finally_tree (temp, tf->try_finally_expr));
732     }
733 }
734 #else
735 #define verify_norecord_switch_expr(state, switch_expr)
736 #endif
737
738 /* Redirect a RETURN_EXPR pointed to by Q to FINLAB.  If MOD is
739    non-null, insert it before the new branch.  */
740
741 static void
742 do_return_redirection (struct goto_queue_node *q, tree finlab, gimple_seq mod)
743 {
744   gimple x;
745
746   /* In the case of a return, the queue node must be a gimple statement.  */
747   gcc_assert (!q->is_label);
748
749   /* Note that the return value may have already been computed, e.g.,
750
751         int x;
752         int foo (void)
753         {
754           x = 0;
755           try {
756             return x;
757           } finally {
758             x++;
759           }
760         }
761
762      should return 0, not 1.  We don't have to do anything to make
763      this happens because the return value has been placed in the
764      RESULT_DECL already.  */
765
766   q->cont_stmt = q->stmt.g;
767
768   if (mod)
769     gimple_seq_add_seq (&q->repl_stmt, mod);
770
771   x = gimple_build_goto (finlab);
772   gimple_set_location (x, q->location);
773   gimple_seq_add_stmt (&q->repl_stmt, x);
774 }
775
776 /* Similar, but easier, for GIMPLE_GOTO.  */
777
778 static void
779 do_goto_redirection (struct goto_queue_node *q, tree finlab, gimple_seq mod,
780                      struct leh_tf_state *tf)
781 {
782   gimple x;
783
784   gcc_assert (q->is_label);
785
786   q->cont_stmt = gimple_build_goto (tf->dest_array[q->index]);
787
788   if (mod)
789     gimple_seq_add_seq (&q->repl_stmt, mod);
790
791   x = gimple_build_goto (finlab);
792   gimple_set_location (x, q->location);
793   gimple_seq_add_stmt (&q->repl_stmt, x);
794 }
795
796 /* Emit a standard landing pad sequence into SEQ for REGION.  */
797
798 static void
799 emit_post_landing_pad (gimple_seq *seq, eh_region region)
800 {
801   eh_landing_pad lp = region->landing_pads;
802   gimple x;
803
804   if (lp == NULL)
805     lp = gen_eh_landing_pad (region);
806
807   lp->post_landing_pad = create_artificial_label (UNKNOWN_LOCATION);
808   EH_LANDING_PAD_NR (lp->post_landing_pad) = lp->index;
809
810   x = gimple_build_label (lp->post_landing_pad);
811   gimple_seq_add_stmt (seq, x);
812 }
813
814 /* Emit a RESX statement into SEQ for REGION.  */
815
816 static void
817 emit_resx (gimple_seq *seq, eh_region region)
818 {
819   gimple x = gimple_build_resx (region->index);
820   gimple_seq_add_stmt (seq, x);
821   if (region->outer)
822     record_stmt_eh_region (region->outer, x);
823 }
824
825 /* Emit an EH_DISPATCH statement into SEQ for REGION.  */
826
827 static void
828 emit_eh_dispatch (gimple_seq *seq, eh_region region)
829 {
830   gimple x = gimple_build_eh_dispatch (region->index);
831   gimple_seq_add_stmt (seq, x);
832 }
833
834 /* Note that the current EH region may contain a throw, or a
835    call to a function which itself may contain a throw.  */
836
837 static void
838 note_eh_region_may_contain_throw (eh_region region)
839 {
840   while (bitmap_set_bit (eh_region_may_contain_throw_map, region->index))
841     {
842       if (region->type == ERT_MUST_NOT_THROW)
843         break;
844       region = region->outer;
845       if (region == NULL)
846         break;
847     }
848 }
849
850 /* Check if REGION has been marked as containing a throw.  If REGION is
851    NULL, this predicate is false.  */
852
853 static inline bool
854 eh_region_may_contain_throw (eh_region r)
855 {
856   return r && bitmap_bit_p (eh_region_may_contain_throw_map, r->index);
857 }
858
859 /* We want to transform
860         try { body; } catch { stuff; }
861    to
862         normal_seqence:
863           body;
864           over:
865         eh_seqence:
866           landing_pad:
867           stuff;
868           goto over;
869
870    TP is a GIMPLE_TRY node.  REGION is the region whose post_landing_pad
871    should be placed before the second operand, or NULL.  OVER is
872    an existing label that should be put at the exit, or NULL.  */
873
874 static gimple_seq
875 frob_into_branch_around (gimple tp, eh_region region, tree over)
876 {
877   gimple x;
878   gimple_seq cleanup, result;
879   location_t loc = gimple_location (tp);
880
881   cleanup = gimple_try_cleanup (tp);
882   result = gimple_try_eval (tp);
883
884   if (region)
885     emit_post_landing_pad (&eh_seq, region);
886
887   if (gimple_seq_may_fallthru (cleanup))
888     {
889       if (!over)
890         over = create_artificial_label (loc);
891       x = gimple_build_goto (over);
892       gimple_set_location (x, loc);
893       gimple_seq_add_stmt (&cleanup, x);
894     }
895   gimple_seq_add_seq (&eh_seq, cleanup);
896
897   if (over)
898     {
899       x = gimple_build_label (over);
900       gimple_seq_add_stmt (&result, x);
901     }
902   return result;
903 }
904
905 /* A subroutine of lower_try_finally.  Duplicate the tree rooted at T.
906    Make sure to record all new labels found.  */
907
908 static gimple_seq
909 lower_try_finally_dup_block (gimple_seq seq, struct leh_state *outer_state,
910                              location_t loc)
911 {
912   gimple region = NULL;
913   gimple_seq new_seq;
914   gimple_stmt_iterator gsi;
915
916   new_seq = copy_gimple_seq_and_replace_locals (seq);
917
918   for (gsi = gsi_start (new_seq); !gsi_end_p (gsi); gsi_next (&gsi))
919     {
920       gimple stmt = gsi_stmt (gsi);
921       if (LOCATION_LOCUS (gimple_location (stmt)) == UNKNOWN_LOCATION)
922         {
923           tree block = gimple_block (stmt);
924           gimple_set_location (stmt, loc);
925           gimple_set_block (stmt, block);
926         }
927     }
928
929   if (outer_state->tf)
930     region = outer_state->tf->try_finally_expr;
931   collect_finally_tree_1 (new_seq, region);
932
933   return new_seq;
934 }
935
936 /* A subroutine of lower_try_finally.  Create a fallthru label for
937    the given try_finally state.  The only tricky bit here is that
938    we have to make sure to record the label in our outer context.  */
939
940 static tree
941 lower_try_finally_fallthru_label (struct leh_tf_state *tf)
942 {
943   tree label = tf->fallthru_label;
944   treemple temp;
945
946   if (!label)
947     {
948       label = create_artificial_label (gimple_location (tf->try_finally_expr));
949       tf->fallthru_label = label;
950       if (tf->outer->tf)
951         {
952           temp.t = label;
953           record_in_finally_tree (temp, tf->outer->tf->try_finally_expr);
954         }
955     }
956   return label;
957 }
958
959 /* A subroutine of lower_try_finally.  If FINALLY consits of a
960    GIMPLE_EH_ELSE node, return it.  */
961
962 static inline gimple
963 get_eh_else (gimple_seq finally)
964 {
965   gimple x = gimple_seq_first_stmt (finally);
966   if (gimple_code (x) == GIMPLE_EH_ELSE)
967     {
968       gcc_assert (gimple_seq_singleton_p (finally));
969       return x;
970     }
971   return NULL;
972 }
973
974 /* A subroutine of lower_try_finally.  If the eh_protect_cleanup_actions
975    langhook returns non-null, then the language requires that the exception
976    path out of a try_finally be treated specially.  To wit: the code within
977    the finally block may not itself throw an exception.  We have two choices
978    here. First we can duplicate the finally block and wrap it in a
979    must_not_throw region.  Second, we can generate code like
980
981         try {
982           finally_block;
983         } catch {
984           if (fintmp == eh_edge)
985             protect_cleanup_actions;
986         }
987
988    where "fintmp" is the temporary used in the switch statement generation
989    alternative considered below.  For the nonce, we always choose the first
990    option.
991
992    THIS_STATE may be null if this is a try-cleanup, not a try-finally.  */
993
994 static void
995 honor_protect_cleanup_actions (struct leh_state *outer_state,
996                                struct leh_state *this_state,
997                                struct leh_tf_state *tf)
998 {
999   tree protect_cleanup_actions;
1000   gimple_stmt_iterator gsi;
1001   bool finally_may_fallthru;
1002   gimple_seq finally;
1003   gimple x, eh_else;
1004
1005   /* First check for nothing to do.  */
1006   if (lang_hooks.eh_protect_cleanup_actions == NULL)
1007     return;
1008   protect_cleanup_actions = lang_hooks.eh_protect_cleanup_actions ();
1009   if (protect_cleanup_actions == NULL)
1010     return;
1011
1012   finally = gimple_try_cleanup (tf->top_p);
1013   eh_else = get_eh_else (finally);
1014
1015   /* Duplicate the FINALLY block.  Only need to do this for try-finally,
1016      and not for cleanups.  If we've got an EH_ELSE, extract it now.  */
1017   if (eh_else)
1018     {
1019       finally = gimple_eh_else_e_body (eh_else);
1020       gimple_try_set_cleanup (tf->top_p, gimple_eh_else_n_body (eh_else));
1021     }
1022   else if (this_state)
1023     finally = lower_try_finally_dup_block (finally, outer_state,
1024         gimple_location (tf->try_finally_expr));
1025   finally_may_fallthru = gimple_seq_may_fallthru (finally);
1026
1027   /* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP
1028      set, the handler of the TRY_CATCH_EXPR is another cleanup which ought
1029      to be in an enclosing scope, but needs to be implemented at this level
1030      to avoid a nesting violation (see wrap_temporary_cleanups in
1031      cp/decl.c).  Since it's logically at an outer level, we should call
1032      terminate before we get to it, so strip it away before adding the
1033      MUST_NOT_THROW filter.  */
1034   gsi = gsi_start (finally);
1035   x = gsi_stmt (gsi);
1036   if (gimple_code (x) == GIMPLE_TRY
1037       && gimple_try_kind (x) == GIMPLE_TRY_CATCH
1038       && gimple_try_catch_is_cleanup (x))
1039     {
1040       gsi_insert_seq_before (&gsi, gimple_try_eval (x), GSI_SAME_STMT);
1041       gsi_remove (&gsi, false);
1042     }
1043
1044   /* Wrap the block with protect_cleanup_actions as the action.  */
1045   x = gimple_build_eh_must_not_throw (protect_cleanup_actions);
1046   x = gimple_build_try (finally, gimple_seq_alloc_with_stmt (x),
1047                         GIMPLE_TRY_CATCH);
1048   finally = lower_eh_must_not_throw (outer_state, x);
1049
1050   /* Drop all of this into the exception sequence.  */
1051   emit_post_landing_pad (&eh_seq, tf->region);
1052   gimple_seq_add_seq (&eh_seq, finally);
1053   if (finally_may_fallthru)
1054     emit_resx (&eh_seq, tf->region);
1055
1056   /* Having now been handled, EH isn't to be considered with
1057      the rest of the outgoing edges.  */
1058   tf->may_throw = false;
1059 }
1060
1061 /* A subroutine of lower_try_finally.  We have determined that there is
1062    no fallthru edge out of the finally block.  This means that there is
1063    no outgoing edge corresponding to any incoming edge.  Restructure the
1064    try_finally node for this special case.  */
1065
1066 static void
1067 lower_try_finally_nofallthru (struct leh_state *state,
1068                               struct leh_tf_state *tf)
1069 {
1070   tree lab;
1071   gimple x, eh_else;
1072   gimple_seq finally;
1073   struct goto_queue_node *q, *qe;
1074
1075   lab = create_artificial_label (gimple_location (tf->try_finally_expr));
1076
1077   /* We expect that tf->top_p is a GIMPLE_TRY. */
1078   finally = gimple_try_cleanup (tf->top_p);
1079   tf->top_p_seq = gimple_try_eval (tf->top_p);
1080
1081   x = gimple_build_label (lab);
1082   gimple_seq_add_stmt (&tf->top_p_seq, x);
1083
1084   q = tf->goto_queue;
1085   qe = q + tf->goto_queue_active;
1086   for (; q < qe; ++q)
1087     if (q->index < 0)
1088       do_return_redirection (q, lab, NULL);
1089     else
1090       do_goto_redirection (q, lab, NULL, tf);
1091
1092   replace_goto_queue (tf);
1093
1094   /* Emit the finally block into the stream.  Lower EH_ELSE at this time.  */
1095   eh_else = get_eh_else (finally);
1096   if (eh_else)
1097     {
1098       finally = gimple_eh_else_n_body (eh_else);
1099       lower_eh_constructs_1 (state, &finally);
1100       gimple_seq_add_seq (&tf->top_p_seq, finally);
1101
1102       if (tf->may_throw)
1103         {
1104           finally = gimple_eh_else_e_body (eh_else);
1105           lower_eh_constructs_1 (state, &finally);
1106
1107           emit_post_landing_pad (&eh_seq, tf->region);
1108           gimple_seq_add_seq (&eh_seq, finally);
1109         }
1110     }
1111   else
1112     {
1113       lower_eh_constructs_1 (state, &finally);
1114       gimple_seq_add_seq (&tf->top_p_seq, finally);
1115
1116       if (tf->may_throw)
1117         {
1118           emit_post_landing_pad (&eh_seq, tf->region);
1119
1120           x = gimple_build_goto (lab);
1121           gimple_set_location (x, gimple_location (tf->try_finally_expr));
1122           gimple_seq_add_stmt (&eh_seq, x);
1123         }
1124     }
1125 }
1126
1127 /* A subroutine of lower_try_finally.  We have determined that there is
1128    exactly one destination of the finally block.  Restructure the
1129    try_finally node for this special case.  */
1130
1131 static void
1132 lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
1133 {
1134   struct goto_queue_node *q, *qe;
1135   gimple x;
1136   gimple_seq finally;
1137   gimple_stmt_iterator gsi;
1138   tree finally_label;
1139   location_t loc = gimple_location (tf->try_finally_expr);
1140
1141   finally = gimple_try_cleanup (tf->top_p);
1142   tf->top_p_seq = gimple_try_eval (tf->top_p);
1143
1144   /* Since there's only one destination, and the destination edge can only
1145      either be EH or non-EH, that implies that all of our incoming edges
1146      are of the same type.  Therefore we can lower EH_ELSE immediately.  */
1147   x = get_eh_else (finally);
1148   if (x)
1149     {
1150       if (tf->may_throw)
1151         finally = gimple_eh_else_e_body (x);
1152       else
1153         finally = gimple_eh_else_n_body (x);
1154     }
1155
1156   lower_eh_constructs_1 (state, &finally);
1157
1158   for (gsi = gsi_start (finally); !gsi_end_p (gsi); gsi_next (&gsi))
1159     {
1160       gimple stmt = gsi_stmt (gsi);
1161       if (LOCATION_LOCUS (gimple_location (stmt)) == UNKNOWN_LOCATION)
1162         {
1163           tree block = gimple_block (stmt);
1164           gimple_set_location (stmt, gimple_location (tf->try_finally_expr));
1165           gimple_set_block (stmt, block);
1166         }
1167     }
1168
1169   if (tf->may_throw)
1170     {
1171       /* Only reachable via the exception edge.  Add the given label to
1172          the head of the FINALLY block.  Append a RESX at the end.  */
1173       emit_post_landing_pad (&eh_seq, tf->region);
1174       gimple_seq_add_seq (&eh_seq, finally);
1175       emit_resx (&eh_seq, tf->region);
1176       return;
1177     }
1178
1179   if (tf->may_fallthru)
1180     {
1181       /* Only reachable via the fallthru edge.  Do nothing but let
1182          the two blocks run together; we'll fall out the bottom.  */
1183       gimple_seq_add_seq (&tf->top_p_seq, finally);
1184       return;
1185     }
1186
1187   finally_label = create_artificial_label (loc);
1188   x = gimple_build_label (finally_label);
1189   gimple_seq_add_stmt (&tf->top_p_seq, x);
1190
1191   gimple_seq_add_seq (&tf->top_p_seq, finally);
1192
1193   q = tf->goto_queue;
1194   qe = q + tf->goto_queue_active;
1195
1196   if (tf->may_return)
1197     {
1198       /* Reachable by return expressions only.  Redirect them.  */
1199       for (; q < qe; ++q)
1200         do_return_redirection (q, finally_label, NULL);
1201       replace_goto_queue (tf);
1202     }
1203   else
1204     {
1205       /* Reachable by goto expressions only.  Redirect them.  */
1206       for (; q < qe; ++q)
1207         do_goto_redirection (q, finally_label, NULL, tf);
1208       replace_goto_queue (tf);
1209
1210       if (tf->dest_array[0] == tf->fallthru_label)
1211         {
1212           /* Reachable by goto to fallthru label only.  Redirect it
1213              to the new label (already created, sadly), and do not
1214              emit the final branch out, or the fallthru label.  */
1215           tf->fallthru_label = NULL;
1216           return;
1217         }
1218     }
1219
1220   /* Place the original return/goto to the original destination
1221      immediately after the finally block. */
1222   x = tf->goto_queue[0].cont_stmt;
1223   gimple_seq_add_stmt (&tf->top_p_seq, x);
1224   maybe_record_in_goto_queue (state, x);
1225 }
1226
1227 /* A subroutine of lower_try_finally.  There are multiple edges incoming
1228    and outgoing from the finally block.  Implement this by duplicating the
1229    finally block for every destination.  */
1230
1231 static void
1232 lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
1233 {
1234   gimple_seq finally;
1235   gimple_seq new_stmt;
1236   gimple_seq seq;
1237   gimple x, eh_else;
1238   tree tmp;
1239   location_t tf_loc = gimple_location (tf->try_finally_expr);
1240
1241   finally = gimple_try_cleanup (tf->top_p);
1242
1243   /* Notice EH_ELSE, and simplify some of the remaining code
1244      by considering FINALLY to be the normal return path only.  */
1245   eh_else = get_eh_else (finally);
1246   if (eh_else)
1247     finally = gimple_eh_else_n_body (eh_else);
1248
1249   tf->top_p_seq = gimple_try_eval (tf->top_p);
1250   new_stmt = NULL;
1251
1252   if (tf->may_fallthru)
1253     {
1254       seq = lower_try_finally_dup_block (finally, state, tf_loc);
1255       lower_eh_constructs_1 (state, &seq);
1256       gimple_seq_add_seq (&new_stmt, seq);
1257
1258       tmp = lower_try_finally_fallthru_label (tf);
1259       x = gimple_build_goto (tmp);
1260       gimple_set_location (x, tf_loc);
1261       gimple_seq_add_stmt (&new_stmt, x);
1262     }
1263
1264   if (tf->may_throw)
1265     {
1266       /* We don't need to copy the EH path of EH_ELSE,
1267          since it is only emitted once.  */
1268       if (eh_else)
1269         seq = gimple_eh_else_e_body (eh_else);
1270       else
1271         seq = lower_try_finally_dup_block (finally, state, tf_loc);
1272       lower_eh_constructs_1 (state, &seq);
1273
1274       emit_post_landing_pad (&eh_seq, tf->region);
1275       gimple_seq_add_seq (&eh_seq, seq);
1276       emit_resx (&eh_seq, tf->region);
1277     }
1278
1279   if (tf->goto_queue)
1280     {
1281       struct goto_queue_node *q, *qe;
1282       int return_index, index;
1283       struct labels_s
1284       {
1285         struct goto_queue_node *q;
1286         tree label;
1287       } *labels;
1288
1289       return_index = tf->dest_array.length ();
1290       labels = XCNEWVEC (struct labels_s, return_index + 1);
1291
1292       q = tf->goto_queue;
1293       qe = q + tf->goto_queue_active;
1294       for (; q < qe; q++)
1295         {
1296           index = q->index < 0 ? return_index : q->index;
1297
1298           if (!labels[index].q)
1299             labels[index].q = q;
1300         }
1301
1302       for (index = 0; index < return_index + 1; index++)
1303         {
1304           tree lab;
1305
1306           q = labels[index].q;
1307           if (! q)
1308             continue;
1309
1310           lab = labels[index].label
1311             = create_artificial_label (tf_loc);
1312
1313           if (index == return_index)
1314             do_return_redirection (q, lab, NULL);
1315           else
1316             do_goto_redirection (q, lab, NULL, tf);
1317
1318           x = gimple_build_label (lab);
1319           gimple_seq_add_stmt (&new_stmt, x);
1320
1321           seq = lower_try_finally_dup_block (finally, state, q->location);
1322           lower_eh_constructs_1 (state, &seq);
1323           gimple_seq_add_seq (&new_stmt, seq);
1324
1325           gimple_seq_add_stmt (&new_stmt, q->cont_stmt);
1326           maybe_record_in_goto_queue (state, q->cont_stmt);
1327         }
1328
1329       for (q = tf->goto_queue; q < qe; q++)
1330         {
1331           tree lab;
1332
1333           index = q->index < 0 ? return_index : q->index;
1334
1335           if (labels[index].q == q)
1336             continue;
1337
1338           lab = labels[index].label;
1339
1340           if (index == return_index)
1341             do_return_redirection (q, lab, NULL);
1342           else
1343             do_goto_redirection (q, lab, NULL, tf);
1344         }
1345
1346       replace_goto_queue (tf);
1347       free (labels);
1348     }
1349
1350   /* Need to link new stmts after running replace_goto_queue due
1351      to not wanting to process the same goto stmts twice.  */
1352   gimple_seq_add_seq (&tf->top_p_seq, new_stmt);
1353 }
1354
1355 /* A subroutine of lower_try_finally.  There are multiple edges incoming
1356    and outgoing from the finally block.  Implement this by instrumenting
1357    each incoming edge and creating a switch statement at the end of the
1358    finally block that branches to the appropriate destination.  */
1359
1360 static void
1361 lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
1362 {
1363   struct goto_queue_node *q, *qe;
1364   tree finally_tmp, finally_label;
1365   int return_index, eh_index, fallthru_index;
1366   int nlabels, ndests, j, last_case_index;
1367   tree last_case;
1368   vec<tree> case_label_vec;
1369   gimple_seq switch_body = NULL;
1370   gimple x, eh_else;
1371   tree tmp;
1372   gimple switch_stmt;
1373   gimple_seq finally;
1374   struct pointer_map_t *cont_map = NULL;
1375   /* The location of the TRY_FINALLY stmt.  */
1376   location_t tf_loc = gimple_location (tf->try_finally_expr);
1377   /* The location of the finally block.  */
1378   location_t finally_loc;
1379
1380   finally = gimple_try_cleanup (tf->top_p);
1381   eh_else = get_eh_else (finally);
1382
1383   /* Mash the TRY block to the head of the chain.  */
1384   tf->top_p_seq = gimple_try_eval (tf->top_p);
1385
1386   /* The location of the finally is either the last stmt in the finally
1387      block or the location of the TRY_FINALLY itself.  */
1388   x = gimple_seq_last_stmt (finally);
1389   finally_loc = x ? gimple_location (x) : tf_loc;
1390
1391   /* Prepare for switch statement generation.  */
1392   nlabels = tf->dest_array.length ();
1393   return_index = nlabels;
1394   eh_index = return_index + tf->may_return;
1395   fallthru_index = eh_index + (tf->may_throw && !eh_else);
1396   ndests = fallthru_index + tf->may_fallthru;
1397
1398   finally_tmp = create_tmp_var (integer_type_node, "finally_tmp");
1399   finally_label = create_artificial_label (finally_loc);
1400
1401   /* We use vec::quick_push on case_label_vec throughout this function,
1402      since we know the size in advance and allocate precisely as muce
1403      space as needed.  */
1404   case_label_vec.create (ndests);
1405   last_case = NULL;
1406   last_case_index = 0;
1407
1408   /* Begin inserting code for getting to the finally block.  Things
1409      are done in this order to correspond to the sequence the code is
1410      laid out.  */
1411
1412   if (tf->may_fallthru)
1413     {
1414       x = gimple_build_assign (finally_tmp,
1415                                build_int_cst (integer_type_node,
1416                                               fallthru_index));
1417       gimple_seq_add_stmt (&tf->top_p_seq, x);
1418
1419       tmp = build_int_cst (integer_type_node, fallthru_index);
1420       last_case = build_case_label (tmp, NULL,
1421                                     create_artificial_label (tf_loc));
1422       case_label_vec.quick_push (last_case);
1423       last_case_index++;
1424
1425       x = gimple_build_label (CASE_LABEL (last_case));
1426       gimple_seq_add_stmt (&switch_body, x);
1427
1428       tmp = lower_try_finally_fallthru_label (tf);
1429       x = gimple_build_goto (tmp);
1430       gimple_set_location (x, tf_loc);
1431       gimple_seq_add_stmt (&switch_body, x);
1432     }
1433
1434   /* For EH_ELSE, emit the exception path (plus resx) now, then
1435      subsequently we only need consider the normal path.  */
1436   if (eh_else)
1437     {
1438       if (tf->may_throw)
1439         {
1440           finally = gimple_eh_else_e_body (eh_else);
1441           lower_eh_constructs_1 (state, &finally);
1442
1443           emit_post_landing_pad (&eh_seq, tf->region);
1444           gimple_seq_add_seq (&eh_seq, finally);
1445           emit_resx (&eh_seq, tf->region);
1446         }
1447
1448       finally = gimple_eh_else_n_body (eh_else);
1449     }
1450   else if (tf->may_throw)
1451     {
1452       emit_post_landing_pad (&eh_seq, tf->region);
1453
1454       x = gimple_build_assign (finally_tmp,
1455                                build_int_cst (integer_type_node, eh_index));
1456       gimple_seq_add_stmt (&eh_seq, x);
1457
1458       x = gimple_build_goto (finally_label);
1459       gimple_set_location (x, tf_loc);
1460       gimple_seq_add_stmt (&eh_seq, x);
1461
1462       tmp = build_int_cst (integer_type_node, eh_index);
1463       last_case = build_case_label (tmp, NULL,
1464                                     create_artificial_label (tf_loc));
1465       case_label_vec.quick_push (last_case);
1466       last_case_index++;
1467
1468       x = gimple_build_label (CASE_LABEL (last_case));
1469       gimple_seq_add_stmt (&eh_seq, x);
1470       emit_resx (&eh_seq, tf->region);
1471     }
1472
1473   x = gimple_build_label (finally_label);
1474   gimple_seq_add_stmt (&tf->top_p_seq, x);
1475
1476   lower_eh_constructs_1 (state, &finally);
1477   gimple_seq_add_seq (&tf->top_p_seq, finally);
1478
1479   /* Redirect each incoming goto edge.  */
1480   q = tf->goto_queue;
1481   qe = q + tf->goto_queue_active;
1482   j = last_case_index + tf->may_return;
1483   /* Prepare the assignments to finally_tmp that are executed upon the
1484      entrance through a particular edge. */
1485   for (; q < qe; ++q)
1486     {
1487       gimple_seq mod = NULL;
1488       int switch_id;
1489       unsigned int case_index;
1490
1491       if (q->index < 0)
1492         {
1493           x = gimple_build_assign (finally_tmp,
1494                                    build_int_cst (integer_type_node,
1495                                                   return_index));
1496           gimple_seq_add_stmt (&mod, x);
1497           do_return_redirection (q, finally_label, mod);
1498           switch_id = return_index;
1499         }
1500       else
1501         {
1502           x = gimple_build_assign (finally_tmp,
1503                                    build_int_cst (integer_type_node, q->index));
1504           gimple_seq_add_stmt (&mod, x);
1505           do_goto_redirection (q, finally_label, mod, tf);
1506           switch_id = q->index;
1507         }
1508
1509       case_index = j + q->index;
1510       if (case_label_vec.length () <= case_index || !case_label_vec[case_index])
1511         {
1512           tree case_lab;
1513           void **slot;
1514           tmp = build_int_cst (integer_type_node, switch_id);
1515           case_lab = build_case_label (tmp, NULL,
1516                                        create_artificial_label (tf_loc));
1517           /* We store the cont_stmt in the pointer map, so that we can recover
1518              it in the loop below.  */
1519           if (!cont_map)
1520             cont_map = pointer_map_create ();
1521           slot = pointer_map_insert (cont_map, case_lab);
1522           *slot = q->cont_stmt;
1523           case_label_vec.quick_push (case_lab);
1524         }
1525     }
1526   for (j = last_case_index; j < last_case_index + nlabels; j++)
1527     {
1528       gimple cont_stmt;
1529       void **slot;
1530
1531       last_case = case_label_vec[j];
1532
1533       gcc_assert (last_case);
1534       gcc_assert (cont_map);
1535
1536       slot = pointer_map_contains (cont_map, last_case);
1537       gcc_assert (slot);
1538       cont_stmt = *(gimple *) slot;
1539
1540       x = gimple_build_label (CASE_LABEL (last_case));
1541       gimple_seq_add_stmt (&switch_body, x);
1542       gimple_seq_add_stmt (&switch_body, cont_stmt);
1543       maybe_record_in_goto_queue (state, cont_stmt);
1544     }
1545   if (cont_map)
1546     pointer_map_destroy (cont_map);
1547
1548   replace_goto_queue (tf);
1549
1550   /* Make sure that the last case is the default label, as one is required.
1551      Then sort the labels, which is also required in GIMPLE.  */
1552   CASE_LOW (last_case) = NULL;
1553   tree tem = case_label_vec.pop ();
1554   gcc_assert (tem == last_case);
1555   sort_case_labels (case_label_vec);
1556
1557   /* Build the switch statement, setting last_case to be the default
1558      label.  */
1559   switch_stmt = gimple_build_switch (finally_tmp, last_case,
1560                                      case_label_vec);
1561   gimple_set_location (switch_stmt, finally_loc);
1562
1563   /* Need to link SWITCH_STMT after running replace_goto_queue
1564      due to not wanting to process the same goto stmts twice.  */
1565   gimple_seq_add_stmt (&tf->top_p_seq, switch_stmt);
1566   gimple_seq_add_seq (&tf->top_p_seq, switch_body);
1567 }
1568
1569 /* Decide whether or not we are going to duplicate the finally block.
1570    There are several considerations.
1571
1572    First, if this is Java, then the finally block contains code
1573    written by the user.  It has line numbers associated with it,
1574    so duplicating the block means it's difficult to set a breakpoint.
1575    Since controlling code generation via -g is verboten, we simply
1576    never duplicate code without optimization.
1577
1578    Second, we'd like to prevent egregious code growth.  One way to
1579    do this is to estimate the size of the finally block, multiply
1580    that by the number of copies we'd need to make, and compare against
1581    the estimate of the size of the switch machinery we'd have to add.  */
1582
1583 static bool
1584 decide_copy_try_finally (int ndests, bool may_throw, gimple_seq finally)
1585 {
1586   int f_estimate, sw_estimate;
1587   gimple eh_else;
1588
1589   /* If there's an EH_ELSE involved, the exception path is separate
1590      and really doesn't come into play for this computation.  */
1591   eh_else = get_eh_else (finally);
1592   if (eh_else)
1593     {
1594       ndests -= may_throw;
1595       finally = gimple_eh_else_n_body (eh_else);
1596     }
1597
1598   if (!optimize)
1599     {
1600       gimple_stmt_iterator gsi;
1601
1602       if (ndests == 1)
1603         return true;
1604
1605       for (gsi = gsi_start (finally); !gsi_end_p (gsi); gsi_next (&gsi))
1606         {
1607           gimple stmt = gsi_stmt (gsi);
1608           if (!is_gimple_debug (stmt) && !gimple_clobber_p (stmt))
1609             return false;
1610         }
1611       return true;
1612     }
1613
1614   /* Finally estimate N times, plus N gotos.  */
1615   f_estimate = count_insns_seq (finally, &eni_size_weights);
1616   f_estimate = (f_estimate + 1) * ndests;
1617
1618   /* Switch statement (cost 10), N variable assignments, N gotos.  */
1619   sw_estimate = 10 + 2 * ndests;
1620
1621   /* Optimize for size clearly wants our best guess.  */
1622   if (optimize_function_for_size_p (cfun))
1623     return f_estimate < sw_estimate;
1624
1625   /* ??? These numbers are completely made up so far.  */
1626   if (optimize > 1)
1627     return f_estimate < 100 || f_estimate < sw_estimate * 2;
1628   else
1629     return f_estimate < 40 || f_estimate * 2 < sw_estimate * 3;
1630 }
1631
1632 /* REG is the enclosing region for a possible cleanup region, or the region
1633    itself.  Returns TRUE if such a region would be unreachable.
1634
1635    Cleanup regions within a must-not-throw region aren't actually reachable
1636    even if there are throwing stmts within them, because the personality
1637    routine will call terminate before unwinding.  */
1638
1639 static bool
1640 cleanup_is_dead_in (eh_region reg)
1641 {
1642   while (reg && reg->type == ERT_CLEANUP)
1643     reg = reg->outer;
1644   return (reg && reg->type == ERT_MUST_NOT_THROW);
1645 }
1646
1647 /* A subroutine of lower_eh_constructs_1.  Lower a GIMPLE_TRY_FINALLY nodes
1648    to a sequence of labels and blocks, plus the exception region trees
1649    that record all the magic.  This is complicated by the need to
1650    arrange for the FINALLY block to be executed on all exits.  */
1651
1652 static gimple_seq
1653 lower_try_finally (struct leh_state *state, gimple tp)
1654 {
1655   struct leh_tf_state this_tf;
1656   struct leh_state this_state;
1657   int ndests;
1658   gimple_seq old_eh_seq;
1659
1660   /* Process the try block.  */
1661
1662   memset (&this_tf, 0, sizeof (this_tf));
1663   this_tf.try_finally_expr = tp;
1664   this_tf.top_p = tp;
1665   this_tf.outer = state;
1666   if (using_eh_for_cleanups_p () && !cleanup_is_dead_in (state->cur_region))
1667     {
1668       this_tf.region = gen_eh_region_cleanup (state->cur_region);
1669       this_state.cur_region = this_tf.region;
1670     }
1671   else
1672     {
1673       this_tf.region = NULL;
1674       this_state.cur_region = state->cur_region;
1675     }
1676
1677   this_state.ehp_region = state->ehp_region;
1678   this_state.tf = &this_tf;
1679
1680   old_eh_seq = eh_seq;
1681   eh_seq = NULL;
1682
1683   lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
1684
1685   /* Determine if the try block is escaped through the bottom.  */
1686   this_tf.may_fallthru = gimple_seq_may_fallthru (gimple_try_eval (tp));
1687
1688   /* Determine if any exceptions are possible within the try block.  */
1689   if (this_tf.region)
1690     this_tf.may_throw = eh_region_may_contain_throw (this_tf.region);
1691   if (this_tf.may_throw)
1692     honor_protect_cleanup_actions (state, &this_state, &this_tf);
1693
1694   /* Determine how many edges (still) reach the finally block.  Or rather,
1695      how many destinations are reached by the finally block.  Use this to
1696      determine how we process the finally block itself.  */
1697
1698   ndests = this_tf.dest_array.length ();
1699   ndests += this_tf.may_fallthru;
1700   ndests += this_tf.may_return;
1701   ndests += this_tf.may_throw;
1702
1703   /* If the FINALLY block is not reachable, dike it out.  */
1704   if (ndests == 0)
1705     {
1706       gimple_seq_add_seq (&this_tf.top_p_seq, gimple_try_eval (tp));
1707       gimple_try_set_cleanup (tp, NULL);
1708     }
1709   /* If the finally block doesn't fall through, then any destination
1710      we might try to impose there isn't reached either.  There may be
1711      some minor amount of cleanup and redirection still needed.  */
1712   else if (!gimple_seq_may_fallthru (gimple_try_cleanup (tp)))
1713     lower_try_finally_nofallthru (state, &this_tf);
1714
1715   /* We can easily special-case redirection to a single destination.  */
1716   else if (ndests == 1)
1717     lower_try_finally_onedest (state, &this_tf);
1718   else if (decide_copy_try_finally (ndests, this_tf.may_throw,
1719                                     gimple_try_cleanup (tp)))
1720     lower_try_finally_copy (state, &this_tf);
1721   else
1722     lower_try_finally_switch (state, &this_tf);
1723
1724   /* If someone requested we add a label at the end of the transformed
1725      block, do so.  */
1726   if (this_tf.fallthru_label)
1727     {
1728       /* This must be reached only if ndests == 0. */
1729       gimple x = gimple_build_label (this_tf.fallthru_label);
1730       gimple_seq_add_stmt (&this_tf.top_p_seq, x);
1731     }
1732
1733   this_tf.dest_array.release ();
1734   free (this_tf.goto_queue);
1735   if (this_tf.goto_queue_map)
1736     pointer_map_destroy (this_tf.goto_queue_map);
1737
1738   /* If there was an old (aka outer) eh_seq, append the current eh_seq.
1739      If there was no old eh_seq, then the append is trivially already done.  */
1740   if (old_eh_seq)
1741     {
1742       if (eh_seq == NULL)
1743         eh_seq = old_eh_seq;
1744       else
1745         {
1746           gimple_seq new_eh_seq = eh_seq;
1747           eh_seq = old_eh_seq;
1748           gimple_seq_add_seq (&eh_seq, new_eh_seq);
1749         }
1750     }
1751
1752   return this_tf.top_p_seq;
1753 }
1754
1755 /* A subroutine of lower_eh_constructs_1.  Lower a GIMPLE_TRY_CATCH with a
1756    list of GIMPLE_CATCH to a sequence of labels and blocks, plus the
1757    exception region trees that records all the magic.  */
1758
1759 static gimple_seq
1760 lower_catch (struct leh_state *state, gimple tp)
1761 {
1762   eh_region try_region = NULL;
1763   struct leh_state this_state = *state;
1764   gimple_stmt_iterator gsi;
1765   tree out_label;
1766   gimple_seq new_seq, cleanup;
1767   gimple x;
1768   location_t try_catch_loc = gimple_location (tp);
1769
1770   if (flag_exceptions)
1771     {
1772       try_region = gen_eh_region_try (state->cur_region);
1773       this_state.cur_region = try_region;
1774     }
1775
1776   lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
1777
1778   if (!eh_region_may_contain_throw (try_region))
1779     return gimple_try_eval (tp);
1780
1781   new_seq = NULL;
1782   emit_eh_dispatch (&new_seq, try_region);
1783   emit_resx (&new_seq, try_region);
1784
1785   this_state.cur_region = state->cur_region;
1786   this_state.ehp_region = try_region;
1787
1788   out_label = NULL;
1789   cleanup = gimple_try_cleanup (tp);
1790   for (gsi = gsi_start (cleanup);
1791        !gsi_end_p (gsi);
1792        gsi_next (&gsi))
1793     {
1794       eh_catch c;
1795       gimple gcatch;
1796       gimple_seq handler;
1797
1798       gcatch = gsi_stmt (gsi);
1799       c = gen_eh_region_catch (try_region, gimple_catch_types (gcatch));
1800
1801       handler = gimple_catch_handler (gcatch);
1802       lower_eh_constructs_1 (&this_state, &handler);
1803
1804       c->label = create_artificial_label (UNKNOWN_LOCATION);
1805       x = gimple_build_label (c->label);
1806       gimple_seq_add_stmt (&new_seq, x);
1807
1808       gimple_seq_add_seq (&new_seq, handler);
1809
1810       if (gimple_seq_may_fallthru (new_seq))
1811         {
1812           if (!out_label)
1813             out_label = create_artificial_label (try_catch_loc);
1814
1815           x = gimple_build_goto (out_label);
1816           gimple_seq_add_stmt (&new_seq, x);
1817         }
1818       if (!c->type_list)
1819         break;
1820     }
1821
1822   gimple_try_set_cleanup (tp, new_seq);
1823
1824   return frob_into_branch_around (tp, try_region, out_label);
1825 }
1826
1827 /* A subroutine of lower_eh_constructs_1.  Lower a GIMPLE_TRY with a
1828    GIMPLE_EH_FILTER to a sequence of labels and blocks, plus the exception
1829    region trees that record all the magic.  */
1830
1831 static gimple_seq
1832 lower_eh_filter (struct leh_state *state, gimple tp)
1833 {
1834   struct leh_state this_state = *state;
1835   eh_region this_region = NULL;
1836   gimple inner, x;
1837   gimple_seq new_seq;
1838
1839   inner = gimple_seq_first_stmt (gimple_try_cleanup (tp));
1840
1841   if (flag_exceptions)
1842     {
1843       this_region = gen_eh_region_allowed (state->cur_region,
1844                                            gimple_eh_filter_types (inner));
1845       this_state.cur_region = this_region;
1846     }
1847
1848   lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
1849
1850   if (!eh_region_may_contain_throw (this_region))
1851     return gimple_try_eval (tp);
1852
1853   new_seq = NULL;
1854   this_state.cur_region = state->cur_region;
1855   this_state.ehp_region = this_region;
1856
1857   emit_eh_dispatch (&new_seq, this_region);
1858   emit_resx (&new_seq, this_region);
1859
1860   this_region->u.allowed.label = create_artificial_label (UNKNOWN_LOCATION);
1861   x = gimple_build_label (this_region->u.allowed.label);
1862   gimple_seq_add_stmt (&new_seq, x);
1863
1864   lower_eh_constructs_1 (&this_state, gimple_eh_filter_failure_ptr (inner));
1865   gimple_seq_add_seq (&new_seq, gimple_eh_filter_failure (inner));
1866
1867   gimple_try_set_cleanup (tp, new_seq);
1868
1869   return frob_into_branch_around (tp, this_region, NULL);
1870 }
1871
1872 /* A subroutine of lower_eh_constructs_1.  Lower a GIMPLE_TRY with
1873    an GIMPLE_EH_MUST_NOT_THROW to a sequence of labels and blocks,
1874    plus the exception region trees that record all the magic.  */
1875
1876 static gimple_seq
1877 lower_eh_must_not_throw (struct leh_state *state, gimple tp)
1878 {
1879   struct leh_state this_state = *state;
1880
1881   if (flag_exceptions)
1882     {
1883       gimple inner = gimple_seq_first_stmt (gimple_try_cleanup (tp));
1884       eh_region this_region;
1885
1886       this_region = gen_eh_region_must_not_throw (state->cur_region);
1887       this_region->u.must_not_throw.failure_decl
1888         = gimple_eh_must_not_throw_fndecl (inner);
1889       this_region->u.must_not_throw.failure_loc
1890         = LOCATION_LOCUS (gimple_location (tp));
1891
1892       /* In order to get mangling applied to this decl, we must mark it
1893          used now.  Otherwise, pass_ipa_free_lang_data won't think it
1894          needs to happen.  */
1895       TREE_USED (this_region->u.must_not_throw.failure_decl) = 1;
1896
1897       this_state.cur_region = this_region;
1898     }
1899
1900   lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
1901
1902   return gimple_try_eval (tp);
1903 }
1904
1905 /* Implement a cleanup expression.  This is similar to try-finally,
1906    except that we only execute the cleanup block for exception edges.  */
1907
1908 static gimple_seq
1909 lower_cleanup (struct leh_state *state, gimple tp)
1910 {
1911   struct leh_state this_state = *state;
1912   eh_region this_region = NULL;
1913   struct leh_tf_state fake_tf;
1914   gimple_seq result;
1915   bool cleanup_dead = cleanup_is_dead_in (state->cur_region);
1916
1917   if (flag_exceptions && !cleanup_dead)
1918     {
1919       this_region = gen_eh_region_cleanup (state->cur_region);
1920       this_state.cur_region = this_region;
1921     }
1922
1923   lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
1924
1925   if (cleanup_dead || !eh_region_may_contain_throw (this_region))
1926     return gimple_try_eval (tp);
1927
1928   /* Build enough of a try-finally state so that we can reuse
1929      honor_protect_cleanup_actions.  */
1930   memset (&fake_tf, 0, sizeof (fake_tf));
1931   fake_tf.top_p = fake_tf.try_finally_expr = tp;
1932   fake_tf.outer = state;
1933   fake_tf.region = this_region;
1934   fake_tf.may_fallthru = gimple_seq_may_fallthru (gimple_try_eval (tp));
1935   fake_tf.may_throw = true;
1936
1937   honor_protect_cleanup_actions (state, NULL, &fake_tf);
1938
1939   if (fake_tf.may_throw)
1940     {
1941       /* In this case honor_protect_cleanup_actions had nothing to do,
1942          and we should process this normally.  */
1943       lower_eh_constructs_1 (state, gimple_try_cleanup_ptr (tp));
1944       result = frob_into_branch_around (tp, this_region,
1945                                         fake_tf.fallthru_label);
1946     }
1947   else
1948     {
1949       /* In this case honor_protect_cleanup_actions did nearly all of
1950          the work.  All we have left is to append the fallthru_label.  */
1951
1952       result = gimple_try_eval (tp);
1953       if (fake_tf.fallthru_label)
1954         {
1955           gimple x = gimple_build_label (fake_tf.fallthru_label);
1956           gimple_seq_add_stmt (&result, x);
1957         }
1958     }
1959   return result;
1960 }
1961
1962 /* Main loop for lowering eh constructs. Also moves gsi to the next
1963    statement. */
1964
1965 static void
1966 lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi)
1967 {
1968   gimple_seq replace;
1969   gimple x;
1970   gimple stmt = gsi_stmt (*gsi);
1971
1972   switch (gimple_code (stmt))
1973     {
1974     case GIMPLE_CALL:
1975       {
1976         tree fndecl = gimple_call_fndecl (stmt);
1977         tree rhs, lhs;
1978
1979         if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
1980           switch (DECL_FUNCTION_CODE (fndecl))
1981             {
1982             case BUILT_IN_EH_POINTER:
1983               /* The front end may have generated a call to
1984                  __builtin_eh_pointer (0) within a catch region.  Replace
1985                  this zero argument with the current catch region number.  */
1986               if (state->ehp_region)
1987                 {
1988                   tree nr = build_int_cst (integer_type_node,
1989                                            state->ehp_region->index);
1990                   gimple_call_set_arg (stmt, 0, nr);
1991                 }
1992               else
1993                 {
1994                   /* The user has dome something silly.  Remove it.  */
1995                   rhs = null_pointer_node;
1996                   goto do_replace;
1997                 }
1998               break;
1999
2000             case BUILT_IN_EH_FILTER:
2001               /* ??? This should never appear, but since it's a builtin it
2002                  is accessible to abuse by users.  Just remove it and
2003                  replace the use with the arbitrary value zero.  */
2004               rhs = build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
2005             do_replace:
2006               lhs = gimple_call_lhs (stmt);
2007               x = gimple_build_assign (lhs, rhs);
2008               gsi_insert_before (gsi, x, GSI_SAME_STMT);
2009               /* FALLTHRU */
2010
2011             case BUILT_IN_EH_COPY_VALUES:
2012               /* Likewise this should not appear.  Remove it.  */
2013               gsi_remove (gsi, true);
2014               return;
2015
2016             default:
2017               break;
2018             }
2019       }
2020       /* FALLTHRU */
2021
2022     case GIMPLE_ASSIGN:
2023       /* If the stmt can throw use a new temporary for the assignment
2024          to a LHS.  This makes sure the old value of the LHS is
2025          available on the EH edge.  Only do so for statements that
2026          potentially fall through (no noreturn calls e.g.), otherwise
2027          this new assignment might create fake fallthru regions.  */
2028       if (stmt_could_throw_p (stmt)
2029           && gimple_has_lhs (stmt)
2030           && gimple_stmt_may_fallthru (stmt)
2031           && !tree_could_throw_p (gimple_get_lhs (stmt))
2032           && is_gimple_reg_type (TREE_TYPE (gimple_get_lhs (stmt))))
2033         {
2034           tree lhs = gimple_get_lhs (stmt);
2035           tree tmp = create_tmp_var (TREE_TYPE (lhs), NULL);
2036           gimple s = gimple_build_assign (lhs, tmp);
2037           gimple_set_location (s, gimple_location (stmt));
2038           gimple_set_block (s, gimple_block (stmt));
2039           gimple_set_lhs (stmt, tmp);
2040           if (TREE_CODE (TREE_TYPE (tmp)) == COMPLEX_TYPE
2041               || TREE_CODE (TREE_TYPE (tmp)) == VECTOR_TYPE)
2042             DECL_GIMPLE_REG_P (tmp) = 1;
2043           gsi_insert_after (gsi, s, GSI_SAME_STMT);
2044         }
2045       /* Look for things that can throw exceptions, and record them.  */
2046       if (state->cur_region && stmt_could_throw_p (stmt))
2047         {
2048           record_stmt_eh_region (state->cur_region, stmt);
2049           note_eh_region_may_contain_throw (state->cur_region);
2050         }
2051       break;
2052
2053     case GIMPLE_COND:
2054     case GIMPLE_GOTO:
2055     case GIMPLE_RETURN:
2056       maybe_record_in_goto_queue (state, stmt);
2057       break;
2058
2059     case GIMPLE_SWITCH:
2060       verify_norecord_switch_expr (state, stmt);
2061       break;
2062
2063     case GIMPLE_TRY:
2064       if (gimple_try_kind (stmt) == GIMPLE_TRY_FINALLY)
2065         replace = lower_try_finally (state, stmt);
2066       else
2067         {
2068           x = gimple_seq_first_stmt (gimple_try_cleanup (stmt));
2069           if (!x)
2070             {
2071               replace = gimple_try_eval (stmt);
2072               lower_eh_constructs_1 (state, &replace);
2073             }
2074           else
2075             switch (gimple_code (x))
2076               {
2077                 case GIMPLE_CATCH:
2078                     replace = lower_catch (state, stmt);
2079                     break;
2080                 case GIMPLE_EH_FILTER:
2081                     replace = lower_eh_filter (state, stmt);
2082                     break;
2083                 case GIMPLE_EH_MUST_NOT_THROW:
2084                     replace = lower_eh_must_not_throw (state, stmt);
2085                     break;
2086                 case GIMPLE_EH_ELSE:
2087                     /* This code is only valid with GIMPLE_TRY_FINALLY.  */
2088                     gcc_unreachable ();
2089                 default:
2090                     replace = lower_cleanup (state, stmt);
2091                     break;
2092               }
2093         }
2094
2095       /* Remove the old stmt and insert the transformed sequence
2096          instead. */
2097       gsi_insert_seq_before (gsi, replace, GSI_SAME_STMT);
2098       gsi_remove (gsi, true);
2099
2100       /* Return since we don't want gsi_next () */
2101       return;
2102
2103     case GIMPLE_EH_ELSE:
2104       /* We should be eliminating this in lower_try_finally et al.  */
2105       gcc_unreachable ();
2106
2107     default:
2108       /* A type, a decl, or some kind of statement that we're not
2109          interested in.  Don't walk them.  */
2110       break;
2111     }
2112
2113   gsi_next (gsi);
2114 }
2115
2116 /* A helper to unwrap a gimple_seq and feed stmts to lower_eh_constructs_2. */
2117
2118 static void
2119 lower_eh_constructs_1 (struct leh_state *state, gimple_seq *pseq)
2120 {
2121   gimple_stmt_iterator gsi;
2122   for (gsi = gsi_start (*pseq); !gsi_end_p (gsi);)
2123     lower_eh_constructs_2 (state, &gsi);
2124 }
2125
2126 namespace {
2127
2128 const pass_data pass_data_lower_eh =
2129 {
2130   GIMPLE_PASS, /* type */
2131   "eh", /* name */
2132   OPTGROUP_NONE, /* optinfo_flags */
2133   TV_TREE_EH, /* tv_id */
2134   PROP_gimple_lcf, /* properties_required */
2135   PROP_gimple_leh, /* properties_provided */
2136   0, /* properties_destroyed */
2137   0, /* todo_flags_start */
2138   0, /* todo_flags_finish */
2139 };
2140
2141 class pass_lower_eh : public gimple_opt_pass
2142 {
2143 public:
2144   pass_lower_eh (gcc::context *ctxt)
2145     : gimple_opt_pass (pass_data_lower_eh, ctxt)
2146   {}
2147
2148   /* opt_pass methods: */
2149   virtual unsigned int execute (function *);
2150
2151 }; // class pass_lower_eh
2152
2153 unsigned int
2154 pass_lower_eh::execute (function *fun)
2155 {
2156   struct leh_state null_state;
2157   gimple_seq bodyp;
2158
2159   bodyp = gimple_body (current_function_decl);
2160   if (bodyp == NULL)
2161     return 0;
2162
2163   finally_tree = new hash_table<finally_tree_hasher> (31);
2164   eh_region_may_contain_throw_map = BITMAP_ALLOC (NULL);
2165   memset (&null_state, 0, sizeof (null_state));
2166
2167   collect_finally_tree_1 (bodyp, NULL);
2168   lower_eh_constructs_1 (&null_state, &bodyp);
2169   gimple_set_body (current_function_decl, bodyp);
2170
2171   /* We assume there's a return statement, or something, at the end of
2172      the function, and thus ploping the EH sequence afterward won't
2173      change anything.  */
2174   gcc_assert (!gimple_seq_may_fallthru (bodyp));
2175   gimple_seq_add_seq (&bodyp, eh_seq);
2176
2177   /* We assume that since BODYP already existed, adding EH_SEQ to it
2178      didn't change its value, and we don't have to re-set the function.  */
2179   gcc_assert (bodyp == gimple_body (current_function_decl));
2180
2181   delete finally_tree;
2182   finally_tree = NULL;
2183   BITMAP_FREE (eh_region_may_contain_throw_map);
2184   eh_seq = NULL;
2185
2186   /* If this function needs a language specific EH personality routine
2187      and the frontend didn't already set one do so now.  */
2188   if (function_needs_eh_personality (fun) == eh_personality_lang
2189       && !DECL_FUNCTION_PERSONALITY (current_function_decl))
2190     DECL_FUNCTION_PERSONALITY (current_function_decl)
2191       = lang_hooks.eh_personality ();
2192
2193   return 0;
2194 }
2195
2196 } // anon namespace
2197
2198 gimple_opt_pass *
2199 make_pass_lower_eh (gcc::context *ctxt)
2200 {
2201   return new pass_lower_eh (ctxt);
2202 }
2203 \f
2204 /* Create the multiple edges from an EH_DISPATCH statement to all of
2205    the possible handlers for its EH region.  Return true if there's
2206    no fallthru edge; false if there is.  */
2207
2208 bool
2209 make_eh_dispatch_edges (gimple stmt)
2210 {
2211   eh_region r;
2212   eh_catch c;
2213   basic_block src, dst;
2214
2215   r = get_eh_region_from_number (gimple_eh_dispatch_region (stmt));
2216   src = gimple_bb (stmt);
2217
2218   switch (r->type)
2219     {
2220     case ERT_TRY:
2221       for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
2222         {
2223           dst = label_to_block (c->label);
2224           make_edge (src, dst, 0);
2225
2226           /* A catch-all handler doesn't have a fallthru.  */
2227           if (c->type_list == NULL)
2228             return false;
2229         }
2230       break;
2231
2232     case ERT_ALLOWED_EXCEPTIONS:
2233       dst = label_to_block (r->u.allowed.label);
2234       make_edge (src, dst, 0);
2235       break;
2236
2237     default:
2238       gcc_unreachable ();
2239     }
2240
2241   return true;
2242 }
2243
2244 /* Create the single EH edge from STMT to its nearest landing pad,
2245    if there is such a landing pad within the current function.  */
2246
2247 void
2248 make_eh_edges (gimple stmt)
2249 {
2250   basic_block src, dst;
2251   eh_landing_pad lp;
2252   int lp_nr;
2253
2254   lp_nr = lookup_stmt_eh_lp (stmt);
2255   if (lp_nr <= 0)
2256     return;
2257
2258   lp = get_eh_landing_pad_from_number (lp_nr);
2259   gcc_assert (lp != NULL);
2260
2261   src = gimple_bb (stmt);
2262   dst = label_to_block (lp->post_landing_pad);
2263   make_edge (src, dst, EDGE_EH);
2264 }
2265
2266 /* Do the work in redirecting EDGE_IN to NEW_BB within the EH region tree;
2267    do not actually perform the final edge redirection.
2268
2269    CHANGE_REGION is true when we're being called from cleanup_empty_eh and
2270    we intend to change the destination EH region as well; this means
2271    EH_LANDING_PAD_NR must already be set on the destination block label.
2272    If false, we're being called from generic cfg manipulation code and we
2273    should preserve our place within the region tree.  */
2274
2275 static void
2276 redirect_eh_edge_1 (edge edge_in, basic_block new_bb, bool change_region)
2277 {
2278   eh_landing_pad old_lp, new_lp;
2279   basic_block old_bb;
2280   gimple throw_stmt;
2281   int old_lp_nr, new_lp_nr;
2282   tree old_label, new_label;
2283   edge_iterator ei;
2284   edge e;
2285
2286   old_bb = edge_in->dest;
2287   old_label = gimple_block_label (old_bb);
2288   old_lp_nr = EH_LANDING_PAD_NR (old_label);
2289   gcc_assert (old_lp_nr > 0);
2290   old_lp = get_eh_landing_pad_from_number (old_lp_nr);
2291
2292   throw_stmt = last_stmt (edge_in->src);
2293   gcc_assert (lookup_stmt_eh_lp (throw_stmt) == old_lp_nr);
2294
2295   new_label = gimple_block_label (new_bb);
2296
2297   /* Look for an existing region that might be using NEW_BB already.  */
2298   new_lp_nr = EH_LANDING_PAD_NR (new_label);
2299   if (new_lp_nr)
2300     {
2301       new_lp = get_eh_landing_pad_from_number (new_lp_nr);
2302       gcc_assert (new_lp);
2303
2304       /* Unless CHANGE_REGION is true, the new and old landing pad
2305          had better be associated with the same EH region.  */
2306       gcc_assert (change_region || new_lp->region == old_lp->region);
2307     }
2308   else
2309     {
2310       new_lp = NULL;
2311       gcc_assert (!change_region);
2312     }
2313
2314   /* Notice when we redirect the last EH edge away from OLD_BB.  */
2315   FOR_EACH_EDGE (e, ei, old_bb->preds)
2316     if (e != edge_in && (e->flags & EDGE_EH))
2317       break;
2318
2319   if (new_lp)
2320     {
2321       /* NEW_LP already exists.  If there are still edges into OLD_LP,
2322          there's nothing to do with the EH tree.  If there are no more
2323          edges into OLD_LP, then we want to remove OLD_LP as it is unused.
2324          If CHANGE_REGION is true, then our caller is expecting to remove
2325          the landing pad.  */
2326       if (e == NULL && !change_region)
2327         remove_eh_landing_pad (old_lp);
2328     }
2329   else
2330     {
2331       /* No correct landing pad exists.  If there are no more edges
2332          into OLD_LP, then we can simply re-use the existing landing pad.
2333          Otherwise, we have to create a new landing pad.  */
2334       if (e == NULL)
2335         {
2336           EH_LANDING_PAD_NR (old_lp->post_landing_pad) = 0;
2337           new_lp = old_lp;
2338         }
2339       else
2340         new_lp = gen_eh_landing_pad (old_lp->region);
2341       new_lp->post_landing_pad = new_label;
2342       EH_LANDING_PAD_NR (new_label) = new_lp->index;
2343     }
2344
2345   /* Maybe move the throwing statement to the new region.  */
2346   if (old_lp != new_lp)
2347     {
2348       remove_stmt_from_eh_lp (throw_stmt);
2349       add_stmt_to_eh_lp (throw_stmt, new_lp->index);
2350     }
2351 }
2352
2353 /* Redirect EH edge E to NEW_BB.  */
2354
2355 edge
2356 redirect_eh_edge (edge edge_in, basic_block new_bb)
2357 {
2358   redirect_eh_edge_1 (edge_in, new_bb, false);
2359   return ssa_redirect_edge (edge_in, new_bb);
2360 }
2361
2362 /* This is a subroutine of gimple_redirect_edge_and_branch.  Update the
2363    labels for redirecting a non-fallthru EH_DISPATCH edge E to NEW_BB.
2364    The actual edge update will happen in the caller.  */
2365
2366 void
2367 redirect_eh_dispatch_edge (gimple stmt, edge e, basic_block new_bb)
2368 {
2369   tree new_lab = gimple_block_label (new_bb);
2370   bool any_changed = false;
2371   basic_block old_bb;
2372   eh_region r;
2373   eh_catch c;
2374
2375   r = get_eh_region_from_number (gimple_eh_dispatch_region (stmt));
2376   switch (r->type)
2377     {
2378     case ERT_TRY:
2379       for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
2380         {
2381           old_bb = label_to_block (c->label);
2382           if (old_bb == e->dest)
2383             {
2384               c->label = new_lab;
2385               any_changed = true;
2386             }
2387         }
2388       break;
2389
2390     case ERT_ALLOWED_EXCEPTIONS:
2391       old_bb = label_to_block (r->u.allowed.label);
2392       gcc_assert (old_bb == e->dest);
2393       r->u.allowed.label = new_lab;
2394       any_changed = true;
2395       break;
2396
2397     default:
2398       gcc_unreachable ();
2399     }
2400
2401   gcc_assert (any_changed);
2402 }
2403 \f
2404 /* Helper function for operation_could_trap_p and stmt_could_throw_p.  */
2405
2406 bool
2407 operation_could_trap_helper_p (enum tree_code op,
2408                                bool fp_operation,
2409                                bool honor_trapv,
2410                                bool honor_nans,
2411                                bool honor_snans,
2412                                tree divisor,
2413                                bool *handled)
2414 {
2415   *handled = true;
2416   switch (op)
2417     {
2418     case TRUNC_DIV_EXPR:
2419     case CEIL_DIV_EXPR:
2420     case FLOOR_DIV_EXPR:
2421     case ROUND_DIV_EXPR:
2422     case EXACT_DIV_EXPR:
2423     case CEIL_MOD_EXPR:
2424     case FLOOR_MOD_EXPR:
2425     case ROUND_MOD_EXPR:
2426     case TRUNC_MOD_EXPR:
2427     case RDIV_EXPR:
2428       if (honor_snans || honor_trapv)
2429         return true;
2430       if (fp_operation)
2431         return flag_trapping_math;
2432       if (!TREE_CONSTANT (divisor) || integer_zerop (divisor))
2433         return true;
2434       return false;
2435
2436     case LT_EXPR:
2437     case LE_EXPR:
2438     case GT_EXPR:
2439     case GE_EXPR:
2440     case LTGT_EXPR:
2441       /* Some floating point comparisons may trap.  */
2442       return honor_nans;
2443
2444     case EQ_EXPR:
2445     case NE_EXPR:
2446     case UNORDERED_EXPR:
2447     case ORDERED_EXPR:
2448     case UNLT_EXPR:
2449     case UNLE_EXPR:
2450     case UNGT_EXPR:
2451     case UNGE_EXPR:
2452     case UNEQ_EXPR:
2453       return honor_snans;
2454
2455     case CONVERT_EXPR:
2456     case FIX_TRUNC_EXPR:
2457       /* Conversion of floating point might trap.  */
2458       return honor_nans;
2459
2460     case NEGATE_EXPR:
2461     case ABS_EXPR:
2462     case CONJ_EXPR:
2463       /* These operations don't trap with floating point.  */
2464       if (honor_trapv)
2465         return true;
2466       return false;
2467
2468     case PLUS_EXPR:
2469     case MINUS_EXPR:
2470     case MULT_EXPR:
2471       /* Any floating arithmetic may trap.  */
2472       if (fp_operation && flag_trapping_math)
2473         return true;
2474       if (honor_trapv)
2475         return true;
2476       return false;
2477
2478     case COMPLEX_EXPR:
2479     case CONSTRUCTOR:
2480       /* Constructing an object cannot trap.  */
2481       return false;
2482
2483     default:
2484       /* Any floating arithmetic may trap.  */
2485       if (fp_operation && flag_trapping_math)
2486         return true;
2487
2488       *handled = false;
2489       return false;
2490     }
2491 }
2492
2493 /* Return true if operation OP may trap.  FP_OPERATION is true if OP is applied
2494    on floating-point values.  HONOR_TRAPV is true if OP is applied on integer
2495    type operands that may trap.  If OP is a division operator, DIVISOR contains
2496    the value of the divisor.  */
2497
2498 bool
2499 operation_could_trap_p (enum tree_code op, bool fp_operation, bool honor_trapv,
2500                         tree divisor)
2501 {
2502   bool honor_nans = (fp_operation && flag_trapping_math
2503                      && !flag_finite_math_only);
2504   bool honor_snans = fp_operation && flag_signaling_nans != 0;
2505   bool handled;
2506
2507   if (TREE_CODE_CLASS (op) != tcc_comparison
2508       && TREE_CODE_CLASS (op) != tcc_unary
2509       && TREE_CODE_CLASS (op) != tcc_binary)
2510     return false;
2511
2512   return operation_could_trap_helper_p (op, fp_operation, honor_trapv,
2513                                         honor_nans, honor_snans, divisor,
2514                                         &handled);
2515 }
2516
2517
2518 /* Returns true if it is possible to prove that the index of
2519    an array access REF (an ARRAY_REF expression) falls into the
2520    array bounds.  */
2521
2522 static bool
2523 in_array_bounds_p (tree ref)
2524 {
2525   tree idx = TREE_OPERAND (ref, 1);
2526   tree min, max;
2527
2528   if (TREE_CODE (idx) != INTEGER_CST)
2529     return false;
2530
2531   min = array_ref_low_bound (ref);
2532   max = array_ref_up_bound (ref);
2533   if (!min
2534       || !max
2535       || TREE_CODE (min) != INTEGER_CST
2536       || TREE_CODE (max) != INTEGER_CST)
2537     return false;
2538
2539   if (tree_int_cst_lt (idx, min)
2540       || tree_int_cst_lt (max, idx))
2541     return false;
2542
2543   return true;
2544 }
2545
2546 /* Returns true if it is possible to prove that the range of
2547    an array access REF (an ARRAY_RANGE_REF expression) falls
2548    into the array bounds.  */
2549
2550 static bool
2551 range_in_array_bounds_p (tree ref)
2552 {
2553   tree domain_type = TYPE_DOMAIN (TREE_TYPE (ref));
2554   tree range_min, range_max, min, max;
2555
2556   range_min = TYPE_MIN_VALUE (domain_type);
2557   range_max = TYPE_MAX_VALUE (domain_type);
2558   if (!range_min
2559       || !range_max
2560       || TREE_CODE (range_min) != INTEGER_CST
2561       || TREE_CODE (range_max) != INTEGER_CST)
2562     return false;
2563
2564   min = array_ref_low_bound (ref);
2565   max = array_ref_up_bound (ref);
2566   if (!min
2567       || !max
2568       || TREE_CODE (min) != INTEGER_CST
2569       || TREE_CODE (max) != INTEGER_CST)
2570     return false;
2571
2572   if (tree_int_cst_lt (range_min, min)
2573       || tree_int_cst_lt (max, range_max))
2574     return false;
2575
2576   return true;
2577 }
2578
2579 /* Return true if EXPR can trap, as in dereferencing an invalid pointer
2580    location or floating point arithmetic.  C.f. the rtl version, may_trap_p.
2581    This routine expects only GIMPLE lhs or rhs input.  */
2582
2583 bool
2584 tree_could_trap_p (tree expr)
2585 {
2586   enum tree_code code;
2587   bool fp_operation = false;
2588   bool honor_trapv = false;
2589   tree t, base, div = NULL_TREE;
2590
2591   if (!expr)
2592     return false;
2593
2594   code = TREE_CODE (expr);
2595   t = TREE_TYPE (expr);
2596
2597   if (t)
2598     {
2599       if (COMPARISON_CLASS_P (expr))
2600         fp_operation = FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)));
2601       else
2602         fp_operation = FLOAT_TYPE_P (t);
2603       honor_trapv = INTEGRAL_TYPE_P (t) && TYPE_OVERFLOW_TRAPS (t);
2604     }
2605
2606   if (TREE_CODE_CLASS (code) == tcc_binary)
2607     div = TREE_OPERAND (expr, 1);
2608   if (operation_could_trap_p (code, fp_operation, honor_trapv, div))
2609     return true;
2610
2611  restart:
2612   switch (code)
2613     {
2614     case COMPONENT_REF:
2615     case REALPART_EXPR:
2616     case IMAGPART_EXPR:
2617     case BIT_FIELD_REF:
2618     case VIEW_CONVERT_EXPR:
2619     case WITH_SIZE_EXPR:
2620       expr = TREE_OPERAND (expr, 0);
2621       code = TREE_CODE (expr);
2622       goto restart;
2623
2624     case ARRAY_RANGE_REF:
2625       base = TREE_OPERAND (expr, 0);
2626       if (tree_could_trap_p (base))
2627         return true;
2628       if (TREE_THIS_NOTRAP (expr))
2629         return false;
2630       return !range_in_array_bounds_p (expr);
2631
2632     case ARRAY_REF:
2633       base = TREE_OPERAND (expr, 0);
2634       if (tree_could_trap_p (base))
2635         return true;
2636       if (TREE_THIS_NOTRAP (expr))
2637         return false;
2638       return !in_array_bounds_p (expr);
2639
2640     case TARGET_MEM_REF:
2641     case MEM_REF:
2642       if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR
2643           && tree_could_trap_p (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)))
2644         return true;
2645       if (TREE_THIS_NOTRAP (expr))
2646         return false;
2647       /* We cannot prove that the access is in-bounds when we have
2648          variable-index TARGET_MEM_REFs.  */
2649       if (code == TARGET_MEM_REF
2650           && (TMR_INDEX (expr) || TMR_INDEX2 (expr)))
2651         return true;
2652       if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
2653         {
2654           tree base = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
2655           offset_int off = mem_ref_offset (expr);
2656           if (wi::neg_p (off, SIGNED))
2657             return true;
2658           if (TREE_CODE (base) == STRING_CST)
2659             return wi::leu_p (TREE_STRING_LENGTH (base), off);
2660           else if (DECL_SIZE_UNIT (base) == NULL_TREE
2661                    || TREE_CODE (DECL_SIZE_UNIT (base)) != INTEGER_CST
2662                    || wi::leu_p (wi::to_offset (DECL_SIZE_UNIT (base)), off))
2663             return true;
2664           /* Now we are sure the first byte of the access is inside
2665              the object.  */
2666           return false;
2667         }
2668       return true;
2669
2670     case INDIRECT_REF:
2671       return !TREE_THIS_NOTRAP (expr);
2672
2673     case ASM_EXPR:
2674       return TREE_THIS_VOLATILE (expr);
2675
2676     case CALL_EXPR:
2677       t = get_callee_fndecl (expr);
2678       /* Assume that calls to weak functions may trap.  */
2679       if (!t || !DECL_P (t))
2680         return true;
2681       if (DECL_WEAK (t))
2682         return tree_could_trap_p (t);
2683       return false;
2684
2685     case FUNCTION_DECL:
2686       /* Assume that accesses to weak functions may trap, unless we know
2687          they are certainly defined in current TU or in some other
2688          LTO partition.  */
2689       if (DECL_WEAK (expr) && !DECL_COMDAT (expr))
2690         {
2691           struct cgraph_node *node;
2692           if (!DECL_EXTERNAL (expr))
2693             return false;
2694           node = cgraph_function_node (cgraph_get_node (expr), NULL);
2695           if (node && node->in_other_partition)
2696             return false;
2697           return true;
2698         }
2699       return false;
2700
2701     case VAR_DECL:
2702       /* Assume that accesses to weak vars may trap, unless we know
2703          they are certainly defined in current TU or in some other
2704          LTO partition.  */
2705       if (DECL_WEAK (expr) && !DECL_COMDAT (expr))
2706         {
2707           varpool_node *node;
2708           if (!DECL_EXTERNAL (expr))
2709             return false;
2710           node = varpool_variable_node (varpool_get_node (expr), NULL);
2711           if (node && node->in_other_partition)
2712             return false;
2713           return true;
2714         }
2715       return false;
2716
2717     default:
2718       return false;
2719     }
2720 }
2721
2722
2723 /* Helper for stmt_could_throw_p.  Return true if STMT (assumed to be a
2724    an assignment or a conditional) may throw.  */
2725
2726 static bool
2727 stmt_could_throw_1_p (gimple stmt)
2728 {
2729   enum tree_code code = gimple_expr_code (stmt);
2730   bool honor_nans = false;
2731   bool honor_snans = false;
2732   bool fp_operation = false;
2733   bool honor_trapv = false;
2734   tree t;
2735   size_t i;
2736   bool handled, ret;
2737
2738   if (TREE_CODE_CLASS (code) == tcc_comparison
2739       || TREE_CODE_CLASS (code) == tcc_unary
2740       || TREE_CODE_CLASS (code) == tcc_binary)
2741     {
2742       if (is_gimple_assign (stmt)
2743           && TREE_CODE_CLASS (code) == tcc_comparison)
2744         t = TREE_TYPE (gimple_assign_rhs1 (stmt));
2745       else if (gimple_code (stmt) == GIMPLE_COND)
2746         t = TREE_TYPE (gimple_cond_lhs (stmt));
2747       else
2748         t = gimple_expr_type (stmt);
2749       fp_operation = FLOAT_TYPE_P (t);
2750       if (fp_operation)
2751         {
2752           honor_nans = flag_trapping_math && !flag_finite_math_only;
2753           honor_snans = flag_signaling_nans != 0;
2754         }
2755       else if (INTEGRAL_TYPE_P (t) && TYPE_OVERFLOW_TRAPS (t))
2756         honor_trapv = true;
2757     }
2758
2759   /* Check if the main expression may trap.  */
2760   t = is_gimple_assign (stmt) ? gimple_assign_rhs2 (stmt) : NULL;
2761   ret = operation_could_trap_helper_p (code, fp_operation, honor_trapv,
2762                                        honor_nans, honor_snans, t,
2763                                        &handled);
2764   if (handled)
2765     return ret;
2766
2767   /* If the expression does not trap, see if any of the individual operands may
2768      trap.  */
2769   for (i = 0; i < gimple_num_ops (stmt); i++)
2770     if (tree_could_trap_p (gimple_op (stmt, i)))
2771       return true;
2772
2773   return false;
2774 }
2775
2776
2777 /* Return true if statement STMT could throw an exception.  */
2778
2779 bool
2780 stmt_could_throw_p (gimple stmt)
2781 {
2782   if (!flag_exceptions)
2783     return false;
2784
2785   /* The only statements that can throw an exception are assignments,
2786      conditionals, calls, resx, and asms.  */
2787   switch (gimple_code (stmt))
2788     {
2789     case GIMPLE_RESX:
2790       return true;
2791
2792     case GIMPLE_CALL:
2793       return !gimple_call_nothrow_p (stmt);
2794
2795     case GIMPLE_ASSIGN:
2796     case GIMPLE_COND:
2797       if (!cfun->can_throw_non_call_exceptions)
2798         return false;
2799       return stmt_could_throw_1_p (stmt);
2800
2801     case GIMPLE_ASM:
2802       if (!cfun->can_throw_non_call_exceptions)
2803         return false;
2804       return gimple_asm_volatile_p (stmt);
2805
2806     default:
2807       return false;
2808     }
2809 }
2810
2811
2812 /* Return true if expression T could throw an exception.  */
2813
2814 bool
2815 tree_could_throw_p (tree t)
2816 {
2817   if (!flag_exceptions)
2818     return false;
2819   if (TREE_CODE (t) == MODIFY_EXPR)
2820     {
2821       if (cfun->can_throw_non_call_exceptions
2822           && tree_could_trap_p (TREE_OPERAND (t, 0)))
2823         return true;
2824       t = TREE_OPERAND (t, 1);
2825     }
2826
2827   if (TREE_CODE (t) == WITH_SIZE_EXPR)
2828     t = TREE_OPERAND (t, 0);
2829   if (TREE_CODE (t) == CALL_EXPR)
2830     return (call_expr_flags (t) & ECF_NOTHROW) == 0;
2831   if (cfun->can_throw_non_call_exceptions)
2832     return tree_could_trap_p (t);
2833   return false;
2834 }
2835
2836 /* Return true if STMT can throw an exception that is not caught within
2837    the current function (CFUN).  */
2838
2839 bool
2840 stmt_can_throw_external (gimple stmt)
2841 {
2842   int lp_nr;
2843
2844   if (!stmt_could_throw_p (stmt))
2845     return false;
2846
2847   lp_nr = lookup_stmt_eh_lp (stmt);
2848   return lp_nr == 0;
2849 }
2850
2851 /* Return true if STMT can throw an exception that is caught within
2852    the current function (CFUN).  */
2853
2854 bool
2855 stmt_can_throw_internal (gimple stmt)
2856 {
2857   int lp_nr;
2858
2859   if (!stmt_could_throw_p (stmt))
2860     return false;
2861
2862   lp_nr = lookup_stmt_eh_lp (stmt);
2863   return lp_nr > 0;
2864 }
2865
2866 /* Given a statement STMT in IFUN, if STMT can no longer throw, then
2867    remove any entry it might have from the EH table.  Return true if
2868    any change was made.  */
2869
2870 bool
2871 maybe_clean_eh_stmt_fn (struct function *ifun, gimple stmt)
2872 {
2873   if (stmt_could_throw_p (stmt))
2874     return false;
2875   return remove_stmt_from_eh_lp_fn (ifun, stmt);
2876 }
2877
2878 /* Likewise, but always use the current function.  */
2879
2880 bool
2881 maybe_clean_eh_stmt (gimple stmt)
2882 {
2883   return maybe_clean_eh_stmt_fn (cfun, stmt);
2884 }
2885
2886 /* Given a statement OLD_STMT and a new statement NEW_STMT that has replaced
2887    OLD_STMT in the function, remove OLD_STMT from the EH table and put NEW_STMT
2888    in the table if it should be in there.  Return TRUE if a replacement was
2889    done that my require an EH edge purge.  */
2890
2891 bool
2892 maybe_clean_or_replace_eh_stmt (gimple old_stmt, gimple new_stmt)
2893 {
2894   int lp_nr = lookup_stmt_eh_lp (old_stmt);
2895
2896   if (lp_nr != 0)
2897     {
2898       bool new_stmt_could_throw = stmt_could_throw_p (new_stmt);
2899
2900       if (new_stmt == old_stmt && new_stmt_could_throw)
2901         return false;
2902
2903       remove_stmt_from_eh_lp (old_stmt);
2904       if (new_stmt_could_throw)
2905         {
2906           add_stmt_to_eh_lp (new_stmt, lp_nr);
2907           return false;
2908         }
2909       else
2910         return true;
2911     }
2912
2913   return false;
2914 }
2915
2916 /* Given a statement OLD_STMT in OLD_FUN and a duplicate statement NEW_STMT
2917    in NEW_FUN, copy the EH table data from OLD_STMT to NEW_STMT.  The MAP
2918    operand is the return value of duplicate_eh_regions.  */
2919
2920 bool
2921 maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt,
2922                             struct function *old_fun, gimple old_stmt,
2923                             struct pointer_map_t *map, int default_lp_nr)
2924 {
2925   int old_lp_nr, new_lp_nr;
2926   void **slot;
2927
2928   if (!stmt_could_throw_p (new_stmt))
2929     return false;
2930
2931   old_lp_nr = lookup_stmt_eh_lp_fn (old_fun, old_stmt);
2932   if (old_lp_nr == 0)
2933     {
2934       if (default_lp_nr == 0)
2935         return false;
2936       new_lp_nr = default_lp_nr;
2937     }
2938   else if (old_lp_nr > 0)
2939     {
2940       eh_landing_pad old_lp, new_lp;
2941
2942       old_lp = (*old_fun->eh->lp_array)[old_lp_nr];
2943       slot = pointer_map_contains (map, old_lp);
2944       new_lp = (eh_landing_pad) *slot;
2945       new_lp_nr = new_lp->index;
2946     }
2947   else
2948     {
2949       eh_region old_r, new_r;
2950
2951       old_r = (*old_fun->eh->region_array)[-old_lp_nr];
2952       slot = pointer_map_contains (map, old_r);
2953       new_r = (eh_region) *slot;
2954       new_lp_nr = -new_r->index;
2955     }
2956
2957   add_stmt_to_eh_lp_fn (new_fun, new_stmt, new_lp_nr);
2958   return true;
2959 }
2960
2961 /* Similar, but both OLD_STMT and NEW_STMT are within the current function,
2962    and thus no remapping is required.  */
2963
2964 bool
2965 maybe_duplicate_eh_stmt (gimple new_stmt, gimple old_stmt)
2966 {
2967   int lp_nr;
2968
2969   if (!stmt_could_throw_p (new_stmt))
2970     return false;
2971
2972   lp_nr = lookup_stmt_eh_lp (old_stmt);
2973   if (lp_nr == 0)
2974     return false;
2975
2976   add_stmt_to_eh_lp (new_stmt, lp_nr);
2977   return true;
2978 }
2979 \f
2980 /* Returns TRUE if oneh and twoh are exception handlers (gimple_try_cleanup of
2981    GIMPLE_TRY) that are similar enough to be considered the same.  Currently
2982    this only handles handlers consisting of a single call, as that's the
2983    important case for C++: a destructor call for a particular object showing
2984    up in multiple handlers.  */
2985
2986 static bool
2987 same_handler_p (gimple_seq oneh, gimple_seq twoh)
2988 {
2989   gimple_stmt_iterator gsi;
2990   gimple ones, twos;
2991   unsigned int ai;
2992
2993   gsi = gsi_start (oneh);
2994   if (!gsi_one_before_end_p (gsi))
2995     return false;
2996   ones = gsi_stmt (gsi);
2997
2998   gsi = gsi_start (twoh);
2999   if (!gsi_one_before_end_p (gsi))
3000     return false;
3001   twos = gsi_stmt (gsi);
3002
3003   if (!is_gimple_call (ones)
3004       || !is_gimple_call (twos)
3005       || gimple_call_lhs (ones)
3006       || gimple_call_lhs (twos)
3007       || gimple_call_chain (ones)
3008       || gimple_call_chain (twos)
3009       || !gimple_call_same_target_p (ones, twos)
3010       || gimple_call_num_args (ones) != gimple_call_num_args (twos))
3011     return false;
3012
3013   for (ai = 0; ai < gimple_call_num_args (ones); ++ai)
3014     if (!operand_equal_p (gimple_call_arg (ones, ai),
3015                           gimple_call_arg (twos, ai), 0))
3016       return false;
3017
3018   return true;
3019 }
3020
3021 /* Optimize
3022     try { A() } finally { try { ~B() } catch { ~A() } }
3023     try { ... } finally { ~A() }
3024    into
3025     try { A() } catch { ~B() }
3026     try { ~B() ... } finally { ~A() }
3027
3028    This occurs frequently in C++, where A is a local variable and B is a
3029    temporary used in the initializer for A.  */
3030
3031 static void
3032 optimize_double_finally (gimple one, gimple two)
3033 {
3034   gimple oneh;
3035   gimple_stmt_iterator gsi;
3036   gimple_seq cleanup;
3037
3038   cleanup = gimple_try_cleanup (one);
3039   gsi = gsi_start (cleanup);
3040   if (!gsi_one_before_end_p (gsi))
3041     return;
3042
3043   oneh = gsi_stmt (gsi);
3044   if (gimple_code (oneh) != GIMPLE_TRY
3045       || gimple_try_kind (oneh) != GIMPLE_TRY_CATCH)
3046     return;
3047
3048   if (same_handler_p (gimple_try_cleanup (oneh), gimple_try_cleanup (two)))
3049     {
3050       gimple_seq seq = gimple_try_eval (oneh);
3051
3052       gimple_try_set_cleanup (one, seq);
3053       gimple_try_set_kind (one, GIMPLE_TRY_CATCH);
3054       seq = copy_gimple_seq_and_replace_locals (seq);
3055       gimple_seq_add_seq (&seq, gimple_try_eval (two));
3056       gimple_try_set_eval (two, seq);
3057     }
3058 }
3059
3060 /* Perform EH refactoring optimizations that are simpler to do when code
3061    flow has been lowered but EH structures haven't.  */
3062
3063 static void
3064 refactor_eh_r (gimple_seq seq)
3065 {
3066   gimple_stmt_iterator gsi;
3067   gimple one, two;
3068
3069   one = NULL;
3070   two = NULL;
3071   gsi = gsi_start (seq);
3072   while (1)
3073     {
3074       one = two;
3075       if (gsi_end_p (gsi))
3076         two = NULL;
3077       else
3078         two = gsi_stmt (gsi);
3079       if (one
3080           && two
3081           && gimple_code (one) == GIMPLE_TRY
3082           && gimple_code (two) == GIMPLE_TRY
3083           && gimple_try_kind (one) == GIMPLE_TRY_FINALLY
3084           && gimple_try_kind (two) == GIMPLE_TRY_FINALLY)
3085         optimize_double_finally (one, two);
3086       if (one)
3087         switch (gimple_code (one))
3088           {
3089           case GIMPLE_TRY:
3090             refactor_eh_r (gimple_try_eval (one));
3091             refactor_eh_r (gimple_try_cleanup (one));
3092             break;
3093           case GIMPLE_CATCH:
3094             refactor_eh_r (gimple_catch_handler (one));
3095             break;
3096           case GIMPLE_EH_FILTER:
3097             refactor_eh_r (gimple_eh_filter_failure (one));
3098             break;
3099           case GIMPLE_EH_ELSE:
3100             refactor_eh_r (gimple_eh_else_n_body (one));
3101             refactor_eh_r (gimple_eh_else_e_body (one));
3102             break;
3103           default:
3104             break;
3105           }
3106       if (two)
3107         gsi_next (&gsi);
3108       else
3109         break;
3110     }
3111 }
3112
3113 namespace {
3114
3115 const pass_data pass_data_refactor_eh =
3116 {
3117   GIMPLE_PASS, /* type */
3118   "ehopt", /* name */
3119   OPTGROUP_NONE, /* optinfo_flags */
3120   TV_TREE_EH, /* tv_id */
3121   PROP_gimple_lcf, /* properties_required */
3122   0, /* properties_provided */
3123   0, /* properties_destroyed */
3124   0, /* todo_flags_start */
3125   0, /* todo_flags_finish */
3126 };
3127
3128 class pass_refactor_eh : public gimple_opt_pass
3129 {
3130 public:
3131   pass_refactor_eh (gcc::context *ctxt)
3132     : gimple_opt_pass (pass_data_refactor_eh, ctxt)
3133   {}
3134
3135   /* opt_pass methods: */
3136   virtual bool gate (function *) { return flag_exceptions != 0; }
3137   virtual unsigned int execute (function *)
3138     {
3139       refactor_eh_r (gimple_body (current_function_decl));
3140       return 0;
3141     }
3142
3143 }; // class pass_refactor_eh
3144
3145 } // anon namespace
3146
3147 gimple_opt_pass *
3148 make_pass_refactor_eh (gcc::context *ctxt)
3149 {
3150   return new pass_refactor_eh (ctxt);
3151 }
3152 \f
3153 /* At the end of gimple optimization, we can lower RESX.  */
3154
3155 static bool
3156 lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map)
3157 {
3158   int lp_nr;
3159   eh_region src_r, dst_r;
3160   gimple_stmt_iterator gsi;
3161   gimple x;
3162   tree fn, src_nr;
3163   bool ret = false;
3164
3165   lp_nr = lookup_stmt_eh_lp (stmt);
3166   if (lp_nr != 0)
3167     dst_r = get_eh_region_from_lp_number (lp_nr);
3168   else
3169     dst_r = NULL;
3170
3171   src_r = get_eh_region_from_number (gimple_resx_region (stmt));
3172   gsi = gsi_last_bb (bb);
3173
3174   if (src_r == NULL)
3175     {
3176       /* We can wind up with no source region when pass_cleanup_eh shows
3177          that there are no entries into an eh region and deletes it, but
3178          then the block that contains the resx isn't removed.  This can
3179          happen without optimization when the switch statement created by
3180          lower_try_finally_switch isn't simplified to remove the eh case.
3181
3182          Resolve this by expanding the resx node to an abort.  */
3183
3184       fn = builtin_decl_implicit (BUILT_IN_TRAP);
3185       x = gimple_build_call (fn, 0);
3186       gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3187
3188       while (EDGE_COUNT (bb->succs) > 0)
3189         remove_edge (EDGE_SUCC (bb, 0));
3190     }
3191   else if (dst_r)
3192     {
3193       /* When we have a destination region, we resolve this by copying
3194          the excptr and filter values into place, and changing the edge
3195          to immediately after the landing pad.  */
3196       edge e;
3197
3198       if (lp_nr < 0)
3199         {
3200           basic_block new_bb;
3201           void **slot;
3202           tree lab;
3203
3204           /* We are resuming into a MUST_NOT_CALL region.  Expand a call to
3205              the failure decl into a new block, if needed.  */
3206           gcc_assert (dst_r->type == ERT_MUST_NOT_THROW);
3207
3208           slot = pointer_map_contains (mnt_map, dst_r);
3209           if (slot == NULL)
3210             {
3211               gimple_stmt_iterator gsi2;
3212
3213               new_bb = create_empty_bb (bb);
3214               add_bb_to_loop (new_bb, bb->loop_father);
3215               lab = gimple_block_label (new_bb);
3216               gsi2 = gsi_start_bb (new_bb);
3217
3218               fn = dst_r->u.must_not_throw.failure_decl;
3219               x = gimple_build_call (fn, 0);
3220               gimple_set_location (x, dst_r->u.must_not_throw.failure_loc);
3221               gsi_insert_after (&gsi2, x, GSI_CONTINUE_LINKING);
3222
3223               slot = pointer_map_insert (mnt_map, dst_r);
3224               *slot = lab;
3225             }
3226           else
3227             {
3228               lab = (tree) *slot;
3229               new_bb = label_to_block (lab);
3230             }
3231
3232           gcc_assert (EDGE_COUNT (bb->succs) == 0);
3233           e = make_edge (bb, new_bb, EDGE_FALLTHRU);
3234           e->count = bb->count;
3235           e->probability = REG_BR_PROB_BASE;
3236         }
3237       else
3238         {
3239           edge_iterator ei;
3240           tree dst_nr = build_int_cst (integer_type_node, dst_r->index);
3241
3242           fn = builtin_decl_implicit (BUILT_IN_EH_COPY_VALUES);
3243           src_nr = build_int_cst (integer_type_node, src_r->index);
3244           x = gimple_build_call (fn, 2, dst_nr, src_nr);
3245           gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3246
3247           /* Update the flags for the outgoing edge.  */
3248           e = single_succ_edge (bb);
3249           gcc_assert (e->flags & EDGE_EH);
3250           e->flags = (e->flags & ~EDGE_EH) | EDGE_FALLTHRU;
3251
3252           /* If there are no more EH users of the landing pad, delete it.  */
3253           FOR_EACH_EDGE (e, ei, e->dest->preds)
3254             if (e->flags & EDGE_EH)
3255               break;
3256           if (e == NULL)
3257             {
3258               eh_landing_pad lp = get_eh_landing_pad_from_number (lp_nr);
3259               remove_eh_landing_pad (lp);
3260             }
3261         }
3262
3263       ret = true;
3264     }
3265   else
3266     {
3267       tree var;
3268
3269       /* When we don't have a destination region, this exception escapes
3270          up the call chain.  We resolve this by generating a call to the
3271          _Unwind_Resume library function.  */
3272
3273       /* The ARM EABI redefines _Unwind_Resume as __cxa_end_cleanup
3274          with no arguments for C++ and Java.  Check for that.  */
3275       if (src_r->use_cxa_end_cleanup)
3276         {
3277           fn = builtin_decl_implicit (BUILT_IN_CXA_END_CLEANUP);
3278           x = gimple_build_call (fn, 0);
3279           gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3280         }
3281       else
3282         {
3283           fn = builtin_decl_implicit (BUILT_IN_EH_POINTER);
3284           src_nr = build_int_cst (integer_type_node, src_r->index);
3285           x = gimple_build_call (fn, 1, src_nr);
3286           var = create_tmp_var (ptr_type_node, NULL);
3287           var = make_ssa_name (var, x);
3288           gimple_call_set_lhs (x, var);
3289           gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3290
3291           fn = builtin_decl_implicit (BUILT_IN_UNWIND_RESUME);
3292           x = gimple_build_call (fn, 1, var);
3293           gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3294         }
3295
3296       gcc_assert (EDGE_COUNT (bb->succs) == 0);
3297     }
3298
3299   gsi_remove (&gsi, true);
3300
3301   return ret;
3302 }
3303
3304 namespace {
3305
3306 const pass_data pass_data_lower_resx =
3307 {
3308   GIMPLE_PASS, /* type */
3309   "resx", /* name */
3310   OPTGROUP_NONE, /* optinfo_flags */
3311   TV_TREE_EH, /* tv_id */
3312   PROP_gimple_lcf, /* properties_required */
3313   0, /* properties_provided */
3314   0, /* properties_destroyed */
3315   0, /* todo_flags_start */
3316   0, /* todo_flags_finish */
3317 };
3318
3319 class pass_lower_resx : public gimple_opt_pass
3320 {
3321 public:
3322   pass_lower_resx (gcc::context *ctxt)
3323     : gimple_opt_pass (pass_data_lower_resx, ctxt)
3324   {}
3325
3326   /* opt_pass methods: */
3327   virtual bool gate (function *) { return flag_exceptions != 0; }
3328   virtual unsigned int execute (function *);
3329
3330 }; // class pass_lower_resx
3331
3332 unsigned
3333 pass_lower_resx::execute (function *fun)
3334 {
3335   basic_block bb;
3336   struct pointer_map_t *mnt_map;
3337   bool dominance_invalidated = false;
3338   bool any_rewritten = false;
3339
3340   mnt_map = pointer_map_create ();
3341
3342   FOR_EACH_BB_FN (bb, fun)
3343     {
3344       gimple last = last_stmt (bb);
3345       if (last && is_gimple_resx (last))
3346         {
3347           dominance_invalidated |= lower_resx (bb, last, mnt_map);
3348           any_rewritten = true;
3349         }
3350     }
3351
3352   pointer_map_destroy (mnt_map);
3353
3354   if (dominance_invalidated)
3355     {
3356       free_dominance_info (CDI_DOMINATORS);
3357       free_dominance_info (CDI_POST_DOMINATORS);
3358     }
3359
3360   return any_rewritten ? TODO_update_ssa_only_virtuals : 0;
3361 }
3362
3363 } // anon namespace
3364
3365 gimple_opt_pass *
3366 make_pass_lower_resx (gcc::context *ctxt)
3367 {
3368   return new pass_lower_resx (ctxt);
3369 }
3370
3371 /* Try to optimize var = {v} {CLOBBER} stmts followed just by
3372    external throw.  */
3373
3374 static void
3375 optimize_clobbers (basic_block bb)
3376 {
3377   gimple_stmt_iterator gsi = gsi_last_bb (bb);
3378   bool any_clobbers = false;
3379   bool seen_stack_restore = false;
3380   edge_iterator ei;
3381   edge e;
3382
3383   /* Only optimize anything if the bb contains at least one clobber,
3384      ends with resx (checked by caller), optionally contains some
3385      debug stmts or labels, or at most one __builtin_stack_restore
3386      call, and has an incoming EH edge.  */
3387   for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
3388     {
3389       gimple stmt = gsi_stmt (gsi);
3390       if (is_gimple_debug (stmt))
3391         continue;
3392       if (gimple_clobber_p (stmt))
3393         {
3394           any_clobbers = true;
3395           continue;
3396         }
3397       if (!seen_stack_restore
3398           && gimple_call_builtin_p (stmt, BUILT_IN_STACK_RESTORE))
3399         {
3400           seen_stack_restore = true;
3401           continue;
3402         }
3403       if (gimple_code (stmt) == GIMPLE_LABEL)
3404         break;
3405       return;
3406     }
3407   if (!any_clobbers)
3408     return;
3409   FOR_EACH_EDGE (e, ei, bb->preds)
3410     if (e->flags & EDGE_EH)
3411       break;
3412   if (e == NULL)
3413     return;
3414   gsi = gsi_last_bb (bb);
3415   for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
3416     {
3417       gimple stmt = gsi_stmt (gsi);
3418       if (!gimple_clobber_p (stmt))
3419         continue;
3420       unlink_stmt_vdef (stmt);
3421       gsi_remove (&gsi, true);
3422       release_defs (stmt);
3423     }
3424 }
3425
3426 /* Try to sink var = {v} {CLOBBER} stmts followed just by
3427    internal throw to successor BB.  */
3428
3429 static int
3430 sink_clobbers (basic_block bb)
3431 {
3432   edge e;
3433   edge_iterator ei;
3434   gimple_stmt_iterator gsi, dgsi;
3435   basic_block succbb;
3436   bool any_clobbers = false;
3437   unsigned todo = 0;
3438
3439   /* Only optimize if BB has a single EH successor and
3440      all predecessor edges are EH too.  */
3441   if (!single_succ_p (bb)
3442       || (single_succ_edge (bb)->flags & EDGE_EH) == 0)
3443     return 0;
3444
3445   FOR_EACH_EDGE (e, ei, bb->preds)
3446     {
3447       if ((e->flags & EDGE_EH) == 0)
3448         return 0;
3449     }
3450
3451   /* And BB contains only CLOBBER stmts before the final
3452      RESX.  */
3453   gsi = gsi_last_bb (bb);
3454   for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
3455     {
3456       gimple stmt = gsi_stmt (gsi);
3457       if (is_gimple_debug (stmt))
3458         continue;
3459       if (gimple_code (stmt) == GIMPLE_LABEL)
3460         break;
3461       if (!gimple_clobber_p (stmt))
3462         return 0;
3463       any_clobbers = true;
3464     }
3465   if (!any_clobbers)
3466     return 0;
3467
3468   edge succe = single_succ_edge (bb);
3469   succbb = succe->dest;
3470
3471   /* See if there is a virtual PHI node to take an updated virtual
3472      operand from.  */
3473   gimple vphi = NULL;
3474   tree vuse = NULL_TREE;
3475   for (gsi = gsi_start_phis (succbb); !gsi_end_p (gsi); gsi_next (&gsi))
3476     {
3477       tree res = gimple_phi_result (gsi_stmt (gsi));
3478       if (virtual_operand_p (res))
3479         {
3480           vphi = gsi_stmt (gsi);
3481           vuse = res;
3482           break;
3483         }
3484     }
3485
3486   dgsi = gsi_after_labels (succbb);
3487   gsi = gsi_last_bb (bb);
3488   for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
3489     {
3490       gimple stmt = gsi_stmt (gsi);
3491       tree lhs;
3492       if (is_gimple_debug (stmt))
3493         continue;
3494       if (gimple_code (stmt) == GIMPLE_LABEL)
3495         break;
3496       lhs = gimple_assign_lhs (stmt);
3497       /* Unfortunately we don't have dominance info updated at this
3498          point, so checking if
3499          dominated_by_p (CDI_DOMINATORS, succbb,
3500                          gimple_bb (SSA_NAME_DEF_STMT (TREE_OPERAND (lhs, 0)))
3501          would be too costly.  Thus, avoid sinking any clobbers that
3502          refer to non-(D) SSA_NAMEs.  */
3503       if (TREE_CODE (lhs) == MEM_REF
3504           && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME
3505           && !SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (lhs, 0)))
3506         {
3507           unlink_stmt_vdef (stmt);
3508           gsi_remove (&gsi, true);
3509           release_defs (stmt);
3510           continue;
3511         }
3512
3513       /* As we do not change stmt order when sinking across a
3514          forwarder edge we can keep virtual operands in place.  */
3515       gsi_remove (&gsi, false);
3516       gsi_insert_before (&dgsi, stmt, GSI_NEW_STMT);
3517
3518       /* But adjust virtual operands if we sunk across a PHI node.  */
3519       if (vuse)
3520         {
3521           gimple use_stmt;
3522           imm_use_iterator iter;
3523           use_operand_p use_p;
3524           FOR_EACH_IMM_USE_STMT (use_stmt, iter, vuse)
3525             FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
3526               SET_USE (use_p, gimple_vdef (stmt));
3527           if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vuse))
3528             {
3529               SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_vdef (stmt)) = 1;
3530               SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vuse) = 0;
3531             }
3532           /* Adjust the incoming virtual operand.  */
3533           SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (vphi, succe), gimple_vuse (stmt));
3534           SET_USE (gimple_vuse_op (stmt), vuse);
3535         }
3536       /* If there isn't a single predecessor but no virtual PHI node
3537          arrange for virtual operands to be renamed.  */
3538       else if (gimple_vuse_op (stmt) != NULL_USE_OPERAND_P
3539                && !single_pred_p (succbb))
3540         {
3541           /* In this case there will be no use of the VDEF of this stmt. 
3542              ???  Unless this is a secondary opportunity and we have not
3543              removed unreachable blocks yet, so we cannot assert this.  
3544              Which also means we will end up renaming too many times.  */
3545           SET_USE (gimple_vuse_op (stmt), gimple_vop (cfun));
3546           mark_virtual_operands_for_renaming (cfun);
3547           todo |= TODO_update_ssa_only_virtuals;
3548         }
3549     }
3550
3551   return todo;
3552 }
3553
3554 /* At the end of inlining, we can lower EH_DISPATCH.  Return true when 
3555    we have found some duplicate labels and removed some edges.  */
3556
3557 static bool
3558 lower_eh_dispatch (basic_block src, gimple stmt)
3559 {
3560   gimple_stmt_iterator gsi;
3561   int region_nr;
3562   eh_region r;
3563   tree filter, fn;
3564   gimple x;
3565   bool redirected = false;
3566
3567   region_nr = gimple_eh_dispatch_region (stmt);
3568   r = get_eh_region_from_number (region_nr);
3569
3570   gsi = gsi_last_bb (src);
3571
3572   switch (r->type)
3573     {
3574     case ERT_TRY:
3575       {
3576         auto_vec<tree> labels;
3577         tree default_label = NULL;
3578         eh_catch c;
3579         edge_iterator ei;
3580         edge e;
3581         struct pointer_set_t *seen_values = pointer_set_create ();
3582
3583         /* Collect the labels for a switch.  Zero the post_landing_pad
3584            field becase we'll no longer have anything keeping these labels
3585            in existence and the optimizer will be free to merge these
3586            blocks at will.  */
3587         for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
3588           {
3589             tree tp_node, flt_node, lab = c->label;
3590             bool have_label = false;
3591
3592             c->label = NULL;
3593             tp_node = c->type_list;
3594             flt_node = c->filter_list;
3595
3596             if (tp_node == NULL)
3597               {
3598                 default_label = lab;
3599                 break;
3600               }
3601             do
3602               {
3603                 /* Filter out duplicate labels that arise when this handler 
3604                    is shadowed by an earlier one.  When no labels are 
3605                    attached to the handler anymore, we remove 
3606                    the corresponding edge and then we delete unreachable 
3607                    blocks at the end of this pass.  */
3608                 if (! pointer_set_contains (seen_values, TREE_VALUE (flt_node)))
3609                   {
3610                     tree t = build_case_label (TREE_VALUE (flt_node),
3611                                                NULL, lab);
3612                     labels.safe_push (t);
3613                     pointer_set_insert (seen_values, TREE_VALUE (flt_node));
3614                     have_label = true;
3615                   }
3616
3617                 tp_node = TREE_CHAIN (tp_node);
3618                 flt_node = TREE_CHAIN (flt_node);
3619               }
3620             while (tp_node);
3621             if (! have_label)
3622               {
3623                 remove_edge (find_edge (src, label_to_block (lab)));
3624                 redirected = true;
3625               }
3626           }
3627
3628         /* Clean up the edge flags.  */
3629         FOR_EACH_EDGE (e, ei, src->succs)
3630           {
3631             if (e->flags & EDGE_FALLTHRU)
3632               {
3633                 /* If there was no catch-all, use the fallthru edge.  */
3634                 if (default_label == NULL)
3635                   default_label = gimple_block_label (e->dest);
3636                 e->flags &= ~EDGE_FALLTHRU;
3637               }
3638           }
3639         gcc_assert (default_label != NULL);
3640
3641         /* Don't generate a switch if there's only a default case.
3642            This is common in the form of try { A; } catch (...) { B; }.  */
3643         if (!labels.exists ())
3644           {
3645             e = single_succ_edge (src);
3646             e->flags |= EDGE_FALLTHRU;
3647           }
3648         else
3649           {
3650             fn = builtin_decl_implicit (BUILT_IN_EH_FILTER);
3651             x = gimple_build_call (fn, 1, build_int_cst (integer_type_node,
3652                                                          region_nr));
3653             filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL);
3654             filter = make_ssa_name (filter, x);
3655             gimple_call_set_lhs (x, filter);
3656             gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3657
3658             /* Turn the default label into a default case.  */
3659             default_label = build_case_label (NULL, NULL, default_label);
3660             sort_case_labels (labels);
3661
3662             x = gimple_build_switch (filter, default_label, labels);
3663             gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3664           }
3665         pointer_set_destroy (seen_values);
3666       }
3667       break;
3668
3669     case ERT_ALLOWED_EXCEPTIONS:
3670       {
3671         edge b_e = BRANCH_EDGE (src);
3672         edge f_e = FALLTHRU_EDGE (src);
3673
3674         fn = builtin_decl_implicit (BUILT_IN_EH_FILTER);
3675         x = gimple_build_call (fn, 1, build_int_cst (integer_type_node,
3676                                                      region_nr));
3677         filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL);
3678         filter = make_ssa_name (filter, x);
3679         gimple_call_set_lhs (x, filter);
3680         gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3681
3682         r->u.allowed.label = NULL;
3683         x = gimple_build_cond (EQ_EXPR, filter,
3684                                build_int_cst (TREE_TYPE (filter),
3685                                               r->u.allowed.filter),
3686                                NULL_TREE, NULL_TREE);
3687         gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3688
3689         b_e->flags = b_e->flags | EDGE_TRUE_VALUE;
3690         f_e->flags = (f_e->flags & ~EDGE_FALLTHRU) | EDGE_FALSE_VALUE;
3691       }
3692       break;
3693
3694     default:
3695       gcc_unreachable ();
3696     }
3697
3698   /* Replace the EH_DISPATCH with the SWITCH or COND generated above.  */
3699   gsi_remove (&gsi, true);
3700   return redirected;
3701 }
3702
3703 namespace {
3704
3705 const pass_data pass_data_lower_eh_dispatch =
3706 {
3707   GIMPLE_PASS, /* type */
3708   "ehdisp", /* name */
3709   OPTGROUP_NONE, /* optinfo_flags */
3710   TV_TREE_EH, /* tv_id */
3711   PROP_gimple_lcf, /* properties_required */
3712   0, /* properties_provided */
3713   0, /* properties_destroyed */
3714   0, /* todo_flags_start */
3715   0, /* todo_flags_finish */
3716 };
3717
3718 class pass_lower_eh_dispatch : public gimple_opt_pass
3719 {
3720 public:
3721   pass_lower_eh_dispatch (gcc::context *ctxt)
3722     : gimple_opt_pass (pass_data_lower_eh_dispatch, ctxt)
3723   {}
3724
3725   /* opt_pass methods: */
3726   virtual bool gate (function *fun) { return fun->eh->region_tree != NULL; }
3727   virtual unsigned int execute (function *);
3728
3729 }; // class pass_lower_eh_dispatch
3730
3731 unsigned
3732 pass_lower_eh_dispatch::execute (function *fun)
3733 {
3734   basic_block bb;
3735   int flags = 0;
3736   bool redirected = false;
3737
3738   assign_filter_values ();
3739
3740   FOR_EACH_BB_FN (bb, fun)
3741     {
3742       gimple last = last_stmt (bb);
3743       if (last == NULL)
3744         continue;
3745       if (gimple_code (last) == GIMPLE_EH_DISPATCH)
3746         {
3747           redirected |= lower_eh_dispatch (bb, last);
3748           flags |= TODO_update_ssa_only_virtuals;
3749         }
3750       else if (gimple_code (last) == GIMPLE_RESX)
3751         {
3752           if (stmt_can_throw_external (last))
3753             optimize_clobbers (bb);
3754           else
3755             flags |= sink_clobbers (bb);
3756         }
3757     }
3758
3759   if (redirected)
3760     delete_unreachable_blocks ();
3761   return flags;
3762 }
3763
3764 } // anon namespace
3765
3766 gimple_opt_pass *
3767 make_pass_lower_eh_dispatch (gcc::context *ctxt)
3768 {
3769   return new pass_lower_eh_dispatch (ctxt);
3770 }
3771 \f
3772 /* Walk statements, see what regions and, optionally, landing pads
3773    are really referenced.
3774    
3775    Returns in R_REACHABLEP an sbitmap with bits set for reachable regions,
3776    and in LP_REACHABLE an sbitmap with bits set for reachable landing pads.
3777
3778    Passing NULL for LP_REACHABLE is valid, in this case only reachable
3779    regions are marked.
3780
3781    The caller is responsible for freeing the returned sbitmaps.  */
3782
3783 static void
3784 mark_reachable_handlers (sbitmap *r_reachablep, sbitmap *lp_reachablep)
3785 {
3786   sbitmap r_reachable, lp_reachable;
3787   basic_block bb;
3788   bool mark_landing_pads = (lp_reachablep != NULL);
3789   gcc_checking_assert (r_reachablep != NULL);
3790
3791   r_reachable = sbitmap_alloc (cfun->eh->region_array->length ());
3792   bitmap_clear (r_reachable);
3793   *r_reachablep = r_reachable;
3794
3795   if (mark_landing_pads)
3796     {
3797       lp_reachable = sbitmap_alloc (cfun->eh->lp_array->length ());
3798       bitmap_clear (lp_reachable);
3799       *lp_reachablep = lp_reachable;
3800     }
3801   else
3802     lp_reachable = NULL;
3803
3804   FOR_EACH_BB_FN (bb, cfun)
3805     {
3806       gimple_stmt_iterator gsi;
3807
3808       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3809         {
3810           gimple stmt = gsi_stmt (gsi);
3811
3812           if (mark_landing_pads)
3813             {
3814               int lp_nr = lookup_stmt_eh_lp (stmt);
3815
3816               /* Negative LP numbers are MUST_NOT_THROW regions which
3817                  are not considered BB enders.  */
3818               if (lp_nr < 0)
3819                 bitmap_set_bit (r_reachable, -lp_nr);
3820
3821               /* Positive LP numbers are real landing pads, and BB enders.  */
3822               else if (lp_nr > 0)
3823                 {
3824                   gcc_assert (gsi_one_before_end_p (gsi));
3825                   eh_region region = get_eh_region_from_lp_number (lp_nr);
3826                   bitmap_set_bit (r_reachable, region->index);
3827                   bitmap_set_bit (lp_reachable, lp_nr);
3828                 }
3829             }
3830
3831           /* Avoid removing regions referenced from RESX/EH_DISPATCH.  */
3832           switch (gimple_code (stmt))
3833             {
3834             case GIMPLE_RESX:
3835               bitmap_set_bit (r_reachable, gimple_resx_region (stmt));
3836               break;
3837             case GIMPLE_EH_DISPATCH:
3838               bitmap_set_bit (r_reachable, gimple_eh_dispatch_region (stmt));
3839               break;
3840             default:
3841               break;
3842             }
3843         }
3844     }
3845 }
3846
3847 /* Remove unreachable handlers and unreachable landing pads.  */
3848
3849 static void
3850 remove_unreachable_handlers (void)
3851 {
3852   sbitmap r_reachable, lp_reachable;
3853   eh_region region;
3854   eh_landing_pad lp;
3855   unsigned i;
3856
3857   mark_reachable_handlers (&r_reachable, &lp_reachable);
3858
3859   if (dump_file)
3860     {
3861       fprintf (dump_file, "Before removal of unreachable regions:\n");
3862       dump_eh_tree (dump_file, cfun);
3863       fprintf (dump_file, "Reachable regions: ");
3864       dump_bitmap_file (dump_file, r_reachable);
3865       fprintf (dump_file, "Reachable landing pads: ");
3866       dump_bitmap_file (dump_file, lp_reachable);
3867     }
3868
3869   if (dump_file)
3870     {
3871       FOR_EACH_VEC_SAFE_ELT (cfun->eh->region_array, i, region)
3872         if (region && !bitmap_bit_p (r_reachable, region->index))
3873           fprintf (dump_file,
3874                    "Removing unreachable region %d\n",
3875                    region->index);
3876     }
3877
3878   remove_unreachable_eh_regions (r_reachable);
3879
3880   FOR_EACH_VEC_SAFE_ELT (cfun->eh->lp_array, i, lp)
3881     if (lp && !bitmap_bit_p (lp_reachable, lp->index))
3882       {
3883         if (dump_file)
3884           fprintf (dump_file,
3885                    "Removing unreachable landing pad %d\n",
3886                    lp->index);
3887         remove_eh_landing_pad (lp);
3888       }
3889
3890   if (dump_file)
3891     {
3892       fprintf (dump_file, "\n\nAfter removal of unreachable regions:\n");
3893       dump_eh_tree (dump_file, cfun);
3894       fprintf (dump_file, "\n\n");
3895     }
3896
3897   sbitmap_free (r_reachable);
3898   sbitmap_free (lp_reachable);
3899
3900 #ifdef ENABLE_CHECKING
3901   verify_eh_tree (cfun);
3902 #endif
3903 }
3904
3905 /* Remove unreachable handlers if any landing pads have been removed after
3906    last ehcleanup pass (due to gimple_purge_dead_eh_edges).  */
3907
3908 void
3909 maybe_remove_unreachable_handlers (void)
3910 {
3911   eh_landing_pad lp;
3912   unsigned i;
3913
3914   if (cfun->eh == NULL)
3915     return;
3916            
3917   FOR_EACH_VEC_SAFE_ELT (cfun->eh->lp_array, i, lp)
3918     if (lp && lp->post_landing_pad)
3919       {
3920         if (label_to_block (lp->post_landing_pad) == NULL)
3921           {
3922             remove_unreachable_handlers ();
3923             return;
3924           }
3925       }
3926 }
3927
3928 /* Remove regions that do not have landing pads.  This assumes
3929    that remove_unreachable_handlers has already been run, and
3930    that we've just manipulated the landing pads since then.
3931
3932    Preserve regions with landing pads and regions that prevent
3933    exceptions from propagating further, even if these regions
3934    are not reachable.  */
3935
3936 static void
3937 remove_unreachable_handlers_no_lp (void)
3938 {
3939   eh_region region;
3940   sbitmap r_reachable;
3941   unsigned i;
3942
3943   mark_reachable_handlers (&r_reachable, /*lp_reachablep=*/NULL);
3944
3945   FOR_EACH_VEC_SAFE_ELT (cfun->eh->region_array, i, region)
3946     {
3947       if (! region)
3948         continue;
3949
3950       if (region->landing_pads != NULL
3951           || region->type == ERT_MUST_NOT_THROW)
3952         bitmap_set_bit (r_reachable, region->index);
3953
3954       if (dump_file
3955           && !bitmap_bit_p (r_reachable, region->index))
3956         fprintf (dump_file,
3957                  "Removing unreachable region %d\n",
3958                  region->index);
3959     }
3960
3961   remove_unreachable_eh_regions (r_reachable);
3962
3963   sbitmap_free (r_reachable);
3964 }
3965
3966 /* Undo critical edge splitting on an EH landing pad.  Earlier, we
3967    optimisticaly split all sorts of edges, including EH edges.  The
3968    optimization passes in between may not have needed them; if not,
3969    we should undo the split.
3970
3971    Recognize this case by having one EH edge incoming to the BB and
3972    one normal edge outgoing; BB should be empty apart from the
3973    post_landing_pad label.
3974
3975    Note that this is slightly different from the empty handler case
3976    handled by cleanup_empty_eh, in that the actual handler may yet
3977    have actual code but the landing pad has been separated from the
3978    handler.  As such, cleanup_empty_eh relies on this transformation
3979    having been done first.  */
3980
3981 static bool
3982 unsplit_eh (eh_landing_pad lp)
3983 {
3984   basic_block bb = label_to_block (lp->post_landing_pad);
3985   gimple_stmt_iterator gsi;
3986   edge e_in, e_out;
3987
3988   /* Quickly check the edge counts on BB for singularity.  */
3989   if (!single_pred_p (bb) || !single_succ_p (bb))
3990     return false;
3991   e_in = single_pred_edge (bb);
3992   e_out = single_succ_edge (bb);
3993
3994   /* Input edge must be EH and output edge must be normal.  */
3995   if ((e_in->flags & EDGE_EH) == 0 || (e_out->flags & EDGE_EH) != 0)
3996     return false;
3997
3998   /* The block must be empty except for the labels and debug insns.  */
3999   gsi = gsi_after_labels (bb);
4000   if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
4001     gsi_next_nondebug (&gsi);
4002   if (!gsi_end_p (gsi))
4003     return false;
4004
4005   /* The destination block must not already have a landing pad
4006      for a different region.  */
4007   for (gsi = gsi_start_bb (e_out->dest); !gsi_end_p (gsi); gsi_next (&gsi))
4008     {
4009       gimple stmt = gsi_stmt (gsi);
4010       tree lab;
4011       int lp_nr;
4012
4013       if (gimple_code (stmt) != GIMPLE_LABEL)
4014         break;
4015       lab = gimple_label_label (stmt);
4016       lp_nr = EH_LANDING_PAD_NR (lab);
4017       if (lp_nr && get_eh_region_from_lp_number (lp_nr) != lp->region)
4018         return false;
4019     }
4020
4021   /* The new destination block must not already be a destination of
4022      the source block, lest we merge fallthru and eh edges and get
4023      all sorts of confused.  */
4024   if (find_edge (e_in->src, e_out->dest))
4025     return false;
4026
4027   /* ??? We can get degenerate phis due to cfg cleanups.  I would have
4028      thought this should have been cleaned up by a phicprop pass, but
4029      that doesn't appear to handle virtuals.  Propagate by hand.  */
4030   if (!gimple_seq_empty_p (phi_nodes (bb)))
4031     {
4032       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
4033         {
4034           gimple use_stmt, phi = gsi_stmt (gsi);
4035           tree lhs = gimple_phi_result (phi);
4036           tree rhs = gimple_phi_arg_def (phi, 0);
4037           use_operand_p use_p;
4038           imm_use_iterator iter;
4039
4040           FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
4041             {
4042               FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
4043                 SET_USE (use_p, rhs);
4044             }
4045
4046           if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
4047             SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs) = 1;
4048
4049           remove_phi_node (&gsi, true);
4050         }
4051     }
4052
4053   if (dump_file && (dump_flags & TDF_DETAILS))
4054     fprintf (dump_file, "Unsplit EH landing pad %d to block %i.\n",
4055              lp->index, e_out->dest->index);
4056
4057   /* Redirect the edge.  Since redirect_eh_edge_1 expects to be moving
4058      a successor edge, humor it.  But do the real CFG change with the
4059      predecessor of E_OUT in order to preserve the ordering of arguments
4060      to the PHI nodes in E_OUT->DEST.  */
4061   redirect_eh_edge_1 (e_in, e_out->dest, false);
4062   redirect_edge_pred (e_out, e_in->src);
4063   e_out->flags = e_in->flags;
4064   e_out->probability = e_in->probability;
4065   e_out->count = e_in->count;
4066   remove_edge (e_in);
4067
4068   return true;
4069 }
4070
4071 /* Examine each landing pad block and see if it matches unsplit_eh.  */
4072
4073 static bool
4074 unsplit_all_eh (void)
4075 {
4076   bool changed = false;
4077   eh_landing_pad lp;
4078   int i;
4079
4080   for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
4081     if (lp)
4082       changed |= unsplit_eh (lp);
4083
4084   return changed;
4085 }
4086
4087 /* A subroutine of cleanup_empty_eh.  Redirect all EH edges incoming
4088    to OLD_BB to NEW_BB; return true on success, false on failure.
4089
4090    OLD_BB_OUT is the edge into NEW_BB from OLD_BB, so if we miss any
4091    PHI variables from OLD_BB we can pick them up from OLD_BB_OUT.
4092    Virtual PHIs may be deleted and marked for renaming.  */
4093
4094 static bool
4095 cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
4096                              edge old_bb_out, bool change_region)
4097 {
4098   gimple_stmt_iterator ngsi, ogsi;
4099   edge_iterator ei;
4100   edge e;
4101   bitmap ophi_handled;
4102
4103   /* The destination block must not be a regular successor for any
4104      of the preds of the landing pad.  Thus, avoid turning
4105         <..>
4106          |  \ EH
4107          |  <..>
4108          |  /
4109         <..>
4110      into
4111         <..>
4112         |  | EH
4113         <..>
4114      which CFG verification would choke on.  See PR45172 and PR51089.  */
4115   FOR_EACH_EDGE (e, ei, old_bb->preds)
4116     if (find_edge (e->src, new_bb))
4117       return false;
4118
4119   FOR_EACH_EDGE (e, ei, old_bb->preds)
4120     redirect_edge_var_map_clear (e);
4121
4122   ophi_handled = BITMAP_ALLOC (NULL);
4123
4124   /* First, iterate through the PHIs on NEW_BB and set up the edge_var_map
4125      for the edges we're going to move.  */
4126   for (ngsi = gsi_start_phis (new_bb); !gsi_end_p (ngsi); gsi_next (&ngsi))
4127     {
4128       gimple ophi, nphi = gsi_stmt (ngsi);
4129       tree nresult, nop;
4130
4131       nresult = gimple_phi_result (nphi);
4132       nop = gimple_phi_arg_def (nphi, old_bb_out->dest_idx);
4133
4134       /* Find the corresponding PHI in OLD_BB so we can forward-propagate
4135          the source ssa_name.  */
4136       ophi = NULL;
4137       for (ogsi = gsi_start_phis (old_bb); !gsi_end_p (ogsi); gsi_next (&ogsi))
4138         {
4139           ophi = gsi_stmt (ogsi);
4140           if (gimple_phi_result (ophi) == nop)
4141             break;
4142           ophi = NULL;
4143         }
4144
4145       /* If we did find the corresponding PHI, copy those inputs.  */
4146       if (ophi)
4147         {
4148           /* If NOP is used somewhere else beyond phis in new_bb, give up.  */
4149           if (!has_single_use (nop))
4150             {
4151               imm_use_iterator imm_iter;
4152               use_operand_p use_p;
4153
4154               FOR_EACH_IMM_USE_FAST (use_p, imm_iter, nop)
4155                 {
4156                   if (!gimple_debug_bind_p (USE_STMT (use_p))
4157                       && (gimple_code (USE_STMT (use_p)) != GIMPLE_PHI
4158                           || gimple_bb (USE_STMT (use_p)) != new_bb))
4159                     goto fail;
4160                 }
4161             }
4162           bitmap_set_bit (ophi_handled, SSA_NAME_VERSION (nop));
4163           FOR_EACH_EDGE (e, ei, old_bb->preds)
4164             {
4165               location_t oloc;
4166               tree oop;
4167
4168               if ((e->flags & EDGE_EH) == 0)
4169                 continue;
4170               oop = gimple_phi_arg_def (ophi, e->dest_idx);
4171               oloc = gimple_phi_arg_location (ophi, e->dest_idx);
4172               redirect_edge_var_map_add (e, nresult, oop, oloc);
4173             }
4174         }
4175       /* If we didn't find the PHI, if it's a real variable or a VOP, we know
4176          from the fact that OLD_BB is tree_empty_eh_handler_p that the
4177          variable is unchanged from input to the block and we can simply
4178          re-use the input to NEW_BB from the OLD_BB_OUT edge.  */
4179       else
4180         {
4181           location_t nloc
4182             = gimple_phi_arg_location (nphi, old_bb_out->dest_idx);
4183           FOR_EACH_EDGE (e, ei, old_bb->preds)
4184             redirect_edge_var_map_add (e, nresult, nop, nloc);
4185         }
4186     }
4187
4188   /* Second, verify that all PHIs from OLD_BB have been handled.  If not,
4189      we don't know what values from the other edges into NEW_BB to use.  */
4190   for (ogsi = gsi_start_phis (old_bb); !gsi_end_p (ogsi); gsi_next (&ogsi))
4191     {
4192       gimple ophi = gsi_stmt (ogsi);
4193       tree oresult = gimple_phi_result (ophi);
4194       if (!bitmap_bit_p (ophi_handled, SSA_NAME_VERSION (oresult)))
4195         goto fail;
4196     }
4197
4198   /* Finally, move the edges and update the PHIs.  */
4199   for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)); )
4200     if (e->flags & EDGE_EH)
4201       {
4202         /* ???  CFG manipluation routines do not try to update loop
4203            form on edge redirection.  Do so manually here for now.  */
4204         /* If we redirect a loop entry or latch edge that will either create
4205            a multiple entry loop or rotate the loop.  If the loops merge
4206            we may have created a loop with multiple latches.
4207            All of this isn't easily fixed thus cancel the affected loop
4208            and mark the other loop as possibly having multiple latches.  */
4209         if (e->dest == e->dest->loop_father->header)
4210           {
4211             e->dest->loop_father->header = NULL;
4212             e->dest->loop_father->latch = NULL;
4213             new_bb->loop_father->latch = NULL;
4214             loops_state_set (LOOPS_NEED_FIXUP|LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
4215           }
4216         redirect_eh_edge_1 (e, new_bb, change_region);
4217         redirect_edge_succ (e, new_bb);
4218         flush_pending_stmts (e);
4219       }
4220     else
4221       ei_next (&ei);
4222
4223   BITMAP_FREE (ophi_handled);
4224   return true;
4225
4226  fail:
4227   FOR_EACH_EDGE (e, ei, old_bb->preds)
4228     redirect_edge_var_map_clear (e);
4229   BITMAP_FREE (ophi_handled);
4230   return false;
4231 }
4232
4233 /* A subroutine of cleanup_empty_eh.  Move a landing pad LP from its
4234    old region to NEW_REGION at BB.  */
4235
4236 static void
4237 cleanup_empty_eh_move_lp (basic_block bb, edge e_out,
4238                           eh_landing_pad lp, eh_region new_region)
4239 {
4240   gimple_stmt_iterator gsi;
4241   eh_landing_pad *pp;
4242
4243   for (pp = &lp->region->landing_pads; *pp != lp; pp = &(*pp)->next_lp)
4244     continue;
4245   *pp = lp->next_lp;
4246
4247   lp->region = new_region;
4248   lp->next_lp = new_region->landing_pads;
4249   new_region->landing_pads = lp;
4250
4251   /* Delete the RESX that was matched within the empty handler block.  */
4252   gsi = gsi_last_bb (bb);
4253   unlink_stmt_vdef (gsi_stmt (gsi));
4254   gsi_remove (&gsi, true);
4255
4256   /* Clean up E_OUT for the fallthru.  */
4257   e_out->flags = (e_out->flags & ~EDGE_EH) | EDGE_FALLTHRU;
4258   e_out->probability = REG_BR_PROB_BASE;
4259 }
4260
4261 /* A subroutine of cleanup_empty_eh.  Handle more complex cases of
4262    unsplitting than unsplit_eh was prepared to handle, e.g. when
4263    multiple incoming edges and phis are involved.  */
4264
4265 static bool
4266 cleanup_empty_eh_unsplit (basic_block bb, edge e_out, eh_landing_pad lp)
4267 {
4268   gimple_stmt_iterator gsi;
4269   tree lab;
4270
4271   /* We really ought not have totally lost everything following
4272      a landing pad label.  Given that BB is empty, there had better
4273      be a successor.  */
4274   gcc_assert (e_out != NULL);
4275
4276   /* The destination block must not already have a landing pad
4277      for a different region.  */
4278   lab = NULL;
4279   for (gsi = gsi_start_bb (e_out->dest); !gsi_end_p (gsi); gsi_next (&gsi))
4280     {
4281       gimple stmt = gsi_stmt (gsi);
4282       int lp_nr;
4283
4284       if (gimple_code (stmt) != GIMPLE_LABEL)
4285         break;
4286       lab = gimple_label_label (stmt);
4287       lp_nr = EH_LANDING_PAD_NR (lab);
4288       if (lp_nr && get_eh_region_from_lp_number (lp_nr) != lp->region)
4289         return false;
4290     }
4291
4292   /* Attempt to move the PHIs into the successor block.  */
4293   if (cleanup_empty_eh_merge_phis (e_out->dest, bb, e_out, false))
4294     {
4295       if (dump_file && (dump_flags & TDF_DETAILS))
4296         fprintf (dump_file,
4297                  "Unsplit EH landing pad %d to block %i "
4298                  "(via cleanup_empty_eh).\n",
4299                  lp->index, e_out->dest->index);
4300       return true;
4301     }
4302
4303   return false;
4304 }
4305
4306 /* Return true if edge E_FIRST is part of an empty infinite loop
4307    or leads to such a loop through a series of single successor
4308    empty bbs.  */
4309
4310 static bool
4311 infinite_empty_loop_p (edge e_first)
4312 {
4313   bool inf_loop = false;
4314   edge e;
4315
4316   if (e_first->dest == e_first->src)
4317     return true;
4318
4319   e_first->src->aux = (void *) 1;
4320   for (e = e_first; single_succ_p (e->dest); e = single_succ_edge (e->dest))
4321     {
4322       gimple_stmt_iterator gsi;
4323       if (e->dest->aux)
4324         {
4325           inf_loop = true;
4326           break;
4327         }
4328       e->dest->aux = (void *) 1;
4329       gsi = gsi_after_labels (e->dest);
4330       if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
4331         gsi_next_nondebug (&gsi);
4332       if (!gsi_end_p (gsi))
4333         break;
4334     }
4335   e_first->src->aux = NULL;
4336   for (e = e_first; e->dest->aux; e = single_succ_edge (e->dest))
4337     e->dest->aux = NULL;
4338
4339   return inf_loop;
4340 }
4341
4342 /* Examine the block associated with LP to determine if it's an empty
4343    handler for its EH region.  If so, attempt to redirect EH edges to
4344    an outer region.  Return true the CFG was updated in any way.  This
4345    is similar to jump forwarding, just across EH edges.  */
4346
4347 static bool
4348 cleanup_empty_eh (eh_landing_pad lp)
4349 {
4350   basic_block bb = label_to_block (lp->post_landing_pad);
4351   gimple_stmt_iterator gsi;
4352   gimple resx;
4353   eh_region new_region;
4354   edge_iterator ei;
4355   edge e, e_out;
4356   bool has_non_eh_pred;
4357   bool ret = false;
4358   int new_lp_nr;
4359
4360   /* There can be zero or one edges out of BB.  This is the quickest test.  */
4361   switch (EDGE_COUNT (bb->succs))
4362     {
4363     case 0:
4364       e_out = NULL;
4365       break;
4366     case 1:
4367       e_out = single_succ_edge (bb);
4368       break;
4369     default:
4370       return false;
4371     }
4372
4373   resx = last_stmt (bb);
4374   if (resx && is_gimple_resx (resx))
4375     {
4376       if (stmt_can_throw_external (resx))
4377         optimize_clobbers (bb);
4378       else if (sink_clobbers (bb))
4379         ret = true;
4380     }
4381
4382   gsi = gsi_after_labels (bb);
4383
4384   /* Make sure to skip debug statements.  */
4385   if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
4386     gsi_next_nondebug (&gsi);
4387
4388   /* If the block is totally empty, look for more unsplitting cases.  */
4389   if (gsi_end_p (gsi))
4390     {
4391       /* For the degenerate case of an infinite loop bail out.
4392          If bb has no successors and is totally empty, which can happen e.g.
4393          because of incorrect noreturn attribute, bail out too.  */
4394       if (e_out == NULL
4395           || infinite_empty_loop_p (e_out))
4396         return ret;
4397
4398       return ret | cleanup_empty_eh_unsplit (bb, e_out, lp);
4399     }
4400
4401   /* The block should consist only of a single RESX statement, modulo a
4402      preceding call to __builtin_stack_restore if there is no outgoing
4403      edge, since the call can be eliminated in this case.  */
4404   resx = gsi_stmt (gsi);
4405   if (!e_out && gimple_call_builtin_p (resx, BUILT_IN_STACK_RESTORE))
4406     {
4407       gsi_next (&gsi);
4408       resx = gsi_stmt (gsi);
4409     }
4410   if (!is_gimple_resx (resx))
4411     return ret;
4412   gcc_assert (gsi_one_before_end_p (gsi));
4413
4414   /* Determine if there are non-EH edges, or resx edges into the handler.  */
4415   has_non_eh_pred = false;
4416   FOR_EACH_EDGE (e, ei, bb->preds)
4417     if (!(e->flags & EDGE_EH))
4418       has_non_eh_pred = true;
4419
4420   /* Find the handler that's outer of the empty handler by looking at
4421      where the RESX instruction was vectored.  */
4422   new_lp_nr = lookup_stmt_eh_lp (resx);
4423   new_region = get_eh_region_from_lp_number (new_lp_nr);
4424
4425   /* If there's no destination region within the current function,
4426      redirection is trivial via removing the throwing statements from
4427      the EH region, removing the EH edges, and allowing the block
4428      to go unreachable.  */
4429   if (new_region == NULL)
4430     {
4431       gcc_assert (e_out == NULL);
4432       for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
4433         if (e->flags & EDGE_EH)
4434           {
4435             gimple stmt = last_stmt (e->src);
4436             remove_stmt_from_eh_lp (stmt);
4437             remove_edge (e);
4438           }
4439         else
4440           ei_next (&ei);
4441       goto succeed;
4442     }
4443
4444   /* If the destination region is a MUST_NOT_THROW, allow the runtime
4445      to handle the abort and allow the blocks to go unreachable.  */
4446   if (new_region->type == ERT_MUST_NOT_THROW)
4447     {
4448       for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
4449         if (e->flags & EDGE_EH)
4450           {
4451             gimple stmt = last_stmt (e->src);
4452             remove_stmt_from_eh_lp (stmt);
4453             add_stmt_to_eh_lp (stmt, new_lp_nr);
4454             remove_edge (e);
4455           }
4456         else
4457           ei_next (&ei);
4458       goto succeed;
4459     }
4460
4461   /* Try to redirect the EH edges and merge the PHIs into the destination
4462      landing pad block.  If the merge succeeds, we'll already have redirected
4463      all the EH edges.  The handler itself will go unreachable if there were
4464      no normal edges.  */
4465   if (cleanup_empty_eh_merge_phis (e_out->dest, bb, e_out, true))
4466     goto succeed;
4467
4468   /* Finally, if all input edges are EH edges, then we can (potentially)
4469      reduce the number of transfers from the runtime by moving the landing
4470      pad from the original region to the new region.  This is a win when
4471      we remove the last CLEANUP region along a particular exception
4472      propagation path.  Since nothing changes except for the region with
4473      which the landing pad is associated, the PHI nodes do not need to be
4474      adjusted at all.  */
4475   if (!has_non_eh_pred)
4476     {
4477       cleanup_empty_eh_move_lp (bb, e_out, lp, new_region);
4478       if (dump_file && (dump_flags & TDF_DETAILS))
4479         fprintf (dump_file, "Empty EH handler %i moved to EH region %i.\n",
4480                  lp->index, new_region->index);
4481
4482       /* ??? The CFG didn't change, but we may have rendered the
4483          old EH region unreachable.  Trigger a cleanup there.  */
4484       return true;
4485     }
4486
4487   return ret;
4488
4489  succeed:
4490   if (dump_file && (dump_flags & TDF_DETAILS))
4491     fprintf (dump_file, "Empty EH handler %i removed.\n", lp->index);
4492   remove_eh_landing_pad (lp);
4493   return true;
4494 }
4495
4496 /* Do a post-order traversal of the EH region tree.  Examine each
4497    post_landing_pad block and see if we can eliminate it as empty.  */
4498
4499 static bool
4500 cleanup_all_empty_eh (void)
4501 {
4502   bool changed = false;
4503   eh_landing_pad lp;
4504   int i;
4505
4506   for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
4507     if (lp)
4508       changed |= cleanup_empty_eh (lp);
4509
4510   return changed;
4511 }
4512
4513 /* Perform cleanups and lowering of exception handling
4514     1) cleanups regions with handlers doing nothing are optimized out
4515     2) MUST_NOT_THROW regions that became dead because of 1) are optimized out
4516     3) Info about regions that are containing instructions, and regions
4517        reachable via local EH edges is collected
4518     4) Eh tree is pruned for regions no longer necessary.
4519
4520    TODO: Push MUST_NOT_THROW regions to the root of the EH tree.
4521          Unify those that have the same failure decl and locus.
4522 */
4523
4524 static unsigned int
4525 execute_cleanup_eh_1 (void)
4526 {
4527   /* Do this first: unsplit_all_eh and cleanup_all_empty_eh can die
4528      looking up unreachable landing pads.  */
4529   remove_unreachable_handlers ();
4530
4531   /* Watch out for the region tree vanishing due to all unreachable.  */
4532   if (cfun->eh->region_tree)
4533     {
4534       bool changed = false;
4535
4536       if (optimize)
4537         changed |= unsplit_all_eh ();
4538       changed |= cleanup_all_empty_eh ();
4539
4540       if (changed)
4541         {
4542           free_dominance_info (CDI_DOMINATORS);
4543           free_dominance_info (CDI_POST_DOMINATORS);
4544
4545           /* We delayed all basic block deletion, as we may have performed
4546              cleanups on EH edges while non-EH edges were still present.  */
4547           delete_unreachable_blocks ();
4548
4549           /* We manipulated the landing pads.  Remove any region that no
4550              longer has a landing pad.  */
4551           remove_unreachable_handlers_no_lp ();
4552
4553           return TODO_cleanup_cfg | TODO_update_ssa_only_virtuals;
4554         }
4555     }
4556
4557   return 0;
4558 }
4559
4560 namespace {
4561
4562 const pass_data pass_data_cleanup_eh =
4563 {
4564   GIMPLE_PASS, /* type */
4565   "ehcleanup", /* name */
4566   OPTGROUP_NONE, /* optinfo_flags */
4567   TV_TREE_EH, /* tv_id */
4568   PROP_gimple_lcf, /* properties_required */
4569   0, /* properties_provided */
4570   0, /* properties_destroyed */
4571   0, /* todo_flags_start */
4572   0, /* todo_flags_finish */
4573 };
4574
4575 class pass_cleanup_eh : public gimple_opt_pass
4576 {
4577 public:
4578   pass_cleanup_eh (gcc::context *ctxt)
4579     : gimple_opt_pass (pass_data_cleanup_eh, ctxt)
4580   {}
4581
4582   /* opt_pass methods: */
4583   opt_pass * clone () { return new pass_cleanup_eh (m_ctxt); }
4584   virtual bool gate (function *fun)
4585     {
4586       return fun->eh != NULL && fun->eh->region_tree != NULL;
4587     }
4588
4589   virtual unsigned int execute (function *);
4590
4591 }; // class pass_cleanup_eh
4592
4593 unsigned int
4594 pass_cleanup_eh::execute (function *fun)
4595 {
4596   int ret = execute_cleanup_eh_1 ();
4597
4598   /* If the function no longer needs an EH personality routine
4599      clear it.  This exposes cross-language inlining opportunities
4600      and avoids references to a never defined personality routine.  */
4601   if (DECL_FUNCTION_PERSONALITY (current_function_decl)
4602       && function_needs_eh_personality (fun) != eh_personality_lang)
4603     DECL_FUNCTION_PERSONALITY (current_function_decl) = NULL_TREE;
4604
4605   return ret;
4606 }
4607
4608 } // anon namespace
4609
4610 gimple_opt_pass *
4611 make_pass_cleanup_eh (gcc::context *ctxt)
4612 {
4613   return new pass_cleanup_eh (ctxt);
4614 }
4615 \f
4616 /* Verify that BB containing STMT as the last statement, has precisely the
4617    edge that make_eh_edges would create.  */
4618
4619 DEBUG_FUNCTION bool
4620 verify_eh_edges (gimple stmt)
4621 {
4622   basic_block bb = gimple_bb (stmt);
4623   eh_landing_pad lp = NULL;
4624   int lp_nr;
4625   edge_iterator ei;
4626   edge e, eh_edge;
4627
4628   lp_nr = lookup_stmt_eh_lp (stmt);
4629   if (lp_nr > 0)
4630     lp = get_eh_landing_pad_from_number (lp_nr);
4631
4632   eh_edge = NULL;
4633   FOR_EACH_EDGE (e, ei, bb->succs)
4634     {
4635       if (e->flags & EDGE_EH)
4636         {
4637           if (eh_edge)
4638             {
4639               error ("BB %i has multiple EH edges", bb->index);
4640               return true;
4641             }
4642           else
4643             eh_edge = e;
4644         }
4645     }
4646
4647   if (lp == NULL)
4648     {
4649       if (eh_edge)
4650         {
4651           error ("BB %i can not throw but has an EH edge", bb->index);
4652           return true;
4653         }
4654       return false;
4655     }
4656
4657   if (!stmt_could_throw_p (stmt))
4658     {
4659       error ("BB %i last statement has incorrectly set lp", bb->index);
4660       return true;
4661     }
4662
4663   if (eh_edge == NULL)
4664     {
4665       error ("BB %i is missing an EH edge", bb->index);
4666       return true;
4667     }
4668
4669   if (eh_edge->dest != label_to_block (lp->post_landing_pad))
4670     {
4671       error ("Incorrect EH edge %i->%i", bb->index, eh_edge->dest->index);
4672       return true;
4673     }
4674
4675   return false;
4676 }
4677
4678 /* Similarly, but handle GIMPLE_EH_DISPATCH specifically.  */
4679
4680 DEBUG_FUNCTION bool
4681 verify_eh_dispatch_edge (gimple stmt)
4682 {
4683   eh_region r;
4684   eh_catch c;
4685   basic_block src, dst;
4686   bool want_fallthru = true;
4687   edge_iterator ei;
4688   edge e, fall_edge;
4689
4690   r = get_eh_region_from_number (gimple_eh_dispatch_region (stmt));
4691   src = gimple_bb (stmt);
4692
4693   FOR_EACH_EDGE (e, ei, src->succs)
4694     gcc_assert (e->aux == NULL);
4695
4696   switch (r->type)
4697     {
4698     case ERT_TRY:
4699       for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
4700         {
4701           dst = label_to_block (c->label);
4702           e = find_edge (src, dst);
4703           if (e == NULL)
4704             {
4705               error ("BB %i is missing an edge", src->index);
4706               return true;
4707             }
4708           e->aux = (void *)e;
4709
4710           /* A catch-all handler doesn't have a fallthru.  */
4711           if (c->type_list == NULL)
4712             {
4713               want_fallthru = false;
4714               break;
4715             }
4716         }
4717       break;
4718
4719     case ERT_ALLOWED_EXCEPTIONS:
4720       dst = label_to_block (r->u.allowed.label);
4721       e = find_edge (src, dst);
4722       if (e == NULL)
4723         {
4724           error ("BB %i is missing an edge", src->index);
4725           return true;
4726         }
4727       e->aux = (void *)e;
4728       break;
4729
4730     default:
4731       gcc_unreachable ();
4732     }
4733
4734   fall_edge = NULL;
4735   FOR_EACH_EDGE (e, ei, src->succs)
4736     {
4737       if (e->flags & EDGE_FALLTHRU)
4738         {
4739           if (fall_edge != NULL)
4740             {
4741               error ("BB %i too many fallthru edges", src->index);
4742               return true;
4743             }
4744           fall_edge = e;
4745         }
4746       else if (e->aux)
4747         e->aux = NULL;
4748       else
4749         {
4750           error ("BB %i has incorrect edge", src->index);
4751           return true;
4752         }
4753     }
4754   if ((fall_edge != NULL) ^ want_fallthru)
4755     {
4756       error ("BB %i has incorrect fallthru edge", src->index);
4757       return true;
4758     }
4759
4760   return false;
4761 }