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