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