OSDN Git Service

* de.po: Update.
[pf3gnuchains/gcc-fork.git] / gcc / except.c
1 /* Implements exception handling.
2    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4    Contributed by Mike Stump <mrs@cygnus.com>.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA.  */
22
23
24 /* An exception is an event that can be signaled from within a
25    function. This event can then be "caught" or "trapped" by the
26    callers of this function. This potentially allows program flow to
27    be transferred to any arbitrary code associated with a function call
28    several levels up the stack.
29
30    The intended use for this mechanism is for signaling "exceptional
31    events" in an out-of-band fashion, hence its name. The C++ language
32    (and many other OO-styled or functional languages) practically
33    requires such a mechanism, as otherwise it becomes very difficult
34    or even impossible to signal failure conditions in complex
35    situations.  The traditional C++ example is when an error occurs in
36    the process of constructing an object; without such a mechanism, it
37    is impossible to signal that the error occurs without adding global
38    state variables and error checks around every object construction.
39
40    The act of causing this event to occur is referred to as "throwing
41    an exception". (Alternate terms include "raising an exception" or
42    "signaling an exception".) The term "throw" is used because control
43    is returned to the callers of the function that is signaling the
44    exception, and thus there is the concept of "throwing" the
45    exception up the call stack.
46
47    [ Add updated documentation on how to use this.  ]  */
48
49
50 #include "config.h"
51 #include "system.h"
52 #include "coretypes.h"
53 #include "tm.h"
54 #include "rtl.h"
55 #include "tree.h"
56 #include "flags.h"
57 #include "function.h"
58 #include "expr.h"
59 #include "libfuncs.h"
60 #include "insn-config.h"
61 #include "except.h"
62 #include "integrate.h"
63 #include "hard-reg-set.h"
64 #include "basic-block.h"
65 #include "output.h"
66 #include "dwarf2asm.h"
67 #include "dwarf2out.h"
68 #include "dwarf2.h"
69 #include "toplev.h"
70 #include "hashtab.h"
71 #include "intl.h"
72 #include "ggc.h"
73 #include "tm_p.h"
74 #include "target.h"
75 #include "langhooks.h"
76 #include "cgraph.h"
77 #include "diagnostic.h"
78
79 /* Provide defaults for stuff that may not be defined when using
80    sjlj exceptions.  */
81 #ifndef EH_RETURN_DATA_REGNO
82 #define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM
83 #endif
84
85
86 /* Protect cleanup actions with must-not-throw regions, with a call
87    to the given failure handler.  */
88 tree (*lang_protect_cleanup_actions) (void);
89
90 /* Return true if type A catches type B.  */
91 int (*lang_eh_type_covers) (tree a, tree b);
92
93 /* Map a type to a runtime object to match type.  */
94 tree (*lang_eh_runtime_type) (tree);
95
96 /* A hash table of label to region number.  */
97
98 struct ehl_map_entry GTY(())
99 {
100   rtx label;
101   struct eh_region *region;
102 };
103
104 static GTY(()) int call_site_base;
105 static GTY ((param_is (union tree_node)))
106   htab_t type_to_runtime_map;
107
108 /* Describe the SjLj_Function_Context structure.  */
109 static GTY(()) tree sjlj_fc_type_node;
110 static int sjlj_fc_call_site_ofs;
111 static int sjlj_fc_data_ofs;
112 static int sjlj_fc_personality_ofs;
113 static int sjlj_fc_lsda_ofs;
114 static int sjlj_fc_jbuf_ofs;
115 \f
116 /* Describes one exception region.  */
117 struct eh_region GTY(())
118 {
119   /* The immediately surrounding region.  */
120   struct eh_region *outer;
121
122   /* The list of immediately contained regions.  */
123   struct eh_region *inner;
124   struct eh_region *next_peer;
125
126   /* An identifier for this region.  */
127   int region_number;
128
129   /* When a region is deleted, its parents inherit the REG_EH_REGION
130      numbers already assigned.  */
131   bitmap aka;
132
133   /* Each region does exactly one thing.  */
134   enum eh_region_type
135   { 
136     ERT_UNKNOWN = 0,
137     ERT_CLEANUP,
138     ERT_TRY,
139     ERT_CATCH,
140     ERT_ALLOWED_EXCEPTIONS,
141     ERT_MUST_NOT_THROW,
142     ERT_THROW,
143     ERT_FIXUP
144   } type;
145
146   /* Holds the action to perform based on the preceding type.  */
147   union eh_region_u {
148     /* A list of catch blocks, a surrounding try block,
149        and the label for continuing after a catch.  */
150     struct eh_region_u_try {
151       struct eh_region *catch;
152       struct eh_region *last_catch;
153       struct eh_region *prev_try;
154       rtx continue_label;
155     } GTY ((tag ("ERT_TRY"))) try;
156
157     /* The list through the catch handlers, the list of type objects
158        matched, and the list of associated filters.  */
159     struct eh_region_u_catch {
160       struct eh_region *next_catch;
161       struct eh_region *prev_catch;
162       tree type_list;
163       tree filter_list;
164     } GTY ((tag ("ERT_CATCH"))) catch;
165
166     /* A tree_list of allowed types.  */
167     struct eh_region_u_allowed {
168       tree type_list;
169       int filter;
170     } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
171
172     /* The type given by a call to "throw foo();", or discovered
173        for a throw.  */
174     struct eh_region_u_throw {
175       tree type;
176     } GTY ((tag ("ERT_THROW"))) throw;
177
178     /* Retain the cleanup expression even after expansion so that
179        we can match up fixup regions.  */
180     struct eh_region_u_cleanup {
181       struct eh_region *prev_try;
182     } GTY ((tag ("ERT_CLEANUP"))) cleanup;
183
184     /* The real region (by expression and by pointer) that fixup code
185        should live in.  */
186     struct eh_region_u_fixup {
187       struct eh_region *real_region;
188       bool resolved;
189     } GTY ((tag ("ERT_FIXUP"))) fixup;
190   } GTY ((desc ("%0.type"))) u;
191
192   /* Entry point for this region's handler before landing pads are built.  */
193   rtx label;
194   tree tree_label;
195
196   /* Entry point for this region's handler from the runtime eh library.  */
197   rtx landing_pad;
198
199   /* Entry point for this region's handler from an inner region.  */
200   rtx post_landing_pad;
201
202   /* The RESX insn for handing off control to the next outermost handler,
203      if appropriate.  */
204   rtx resume;
205
206   /* True if something in this region may throw.  */
207   unsigned may_contain_throw : 1;
208 };
209
210 struct call_site_record GTY(())
211 {
212   rtx landing_pad;
213   int action;
214 };
215
216 /* Used to save exception status for each function.  */
217 struct eh_status GTY(())
218 {
219   /* The tree of all regions for this function.  */
220   struct eh_region *region_tree;
221
222   /* The same information as an indexable array.  */
223   struct eh_region ** GTY ((length ("%h.last_region_number"))) region_array;
224
225   /* The most recently open region.  */
226   struct eh_region *cur_region;
227
228   /* This is the region for which we are processing catch blocks.  */
229   struct eh_region *try_region;
230
231   rtx filter;
232   rtx exc_ptr;
233
234   int built_landing_pads;
235   int last_region_number;
236
237   varray_type ttype_data;
238   varray_type ehspec_data;
239   varray_type action_record_data;
240
241   htab_t GTY ((param_is (struct ehl_map_entry))) exception_handler_label_map;
242
243   struct call_site_record * GTY ((length ("%h.call_site_data_used")))
244     call_site_data;
245   int call_site_data_used;
246   int call_site_data_size;
247
248   rtx ehr_stackadj;
249   rtx ehr_handler;
250   rtx ehr_label;
251
252   rtx sjlj_fc;
253   rtx sjlj_exit_after;
254 };
255
256 \f
257 static int t2r_eq (const void *, const void *);
258 static hashval_t t2r_hash (const void *);
259 static void add_type_for_runtime (tree);
260 static tree lookup_type_for_runtime (tree);
261
262 static void remove_unreachable_regions (rtx);
263
264 static int ttypes_filter_eq (const void *, const void *);
265 static hashval_t ttypes_filter_hash (const void *);
266 static int ehspec_filter_eq (const void *, const void *);
267 static hashval_t ehspec_filter_hash (const void *);
268 static int add_ttypes_entry (htab_t, tree);
269 static int add_ehspec_entry (htab_t, htab_t, tree);
270 static void assign_filter_values (void);
271 static void build_post_landing_pads (void);
272 static void connect_post_landing_pads (void);
273 static void dw2_build_landing_pads (void);
274
275 struct sjlj_lp_info;
276 static bool sjlj_find_directly_reachable_regions (struct sjlj_lp_info *);
277 static void sjlj_assign_call_site_values (rtx, struct sjlj_lp_info *);
278 static void sjlj_mark_call_sites (struct sjlj_lp_info *);
279 static void sjlj_emit_function_enter (rtx);
280 static void sjlj_emit_function_exit (void);
281 static void sjlj_emit_dispatch_table (rtx, struct sjlj_lp_info *);
282 static void sjlj_build_landing_pads (void);
283
284 static hashval_t ehl_hash (const void *);
285 static int ehl_eq (const void *, const void *);
286 static void add_ehl_entry (rtx, struct eh_region *);
287 static void remove_exception_handler_label (rtx);
288 static void remove_eh_handler (struct eh_region *);
289 static int for_each_eh_label_1 (void **, void *);
290
291 /* The return value of reachable_next_level.  */
292 enum reachable_code
293 {
294   /* The given exception is not processed by the given region.  */
295   RNL_NOT_CAUGHT,
296   /* The given exception may need processing by the given region.  */
297   RNL_MAYBE_CAUGHT,
298   /* The given exception is completely processed by the given region.  */
299   RNL_CAUGHT,
300   /* The given exception is completely processed by the runtime.  */
301   RNL_BLOCKED
302 };
303
304 struct reachable_info;
305 static enum reachable_code reachable_next_level (struct eh_region *, tree,
306                                                  struct reachable_info *);
307
308 static int action_record_eq (const void *, const void *);
309 static hashval_t action_record_hash (const void *);
310 static int add_action_record (htab_t, int, int);
311 static int collect_one_action_chain (htab_t, struct eh_region *);
312 static int add_call_site (rtx, int);
313
314 static void push_uleb128 (varray_type *, unsigned int);
315 static void push_sleb128 (varray_type *, int);
316 #ifndef HAVE_AS_LEB128
317 static int dw2_size_of_call_site_table (void);
318 static int sjlj_size_of_call_site_table (void);
319 #endif
320 static void dw2_output_call_site_table (void);
321 static void sjlj_output_call_site_table (void);
322
323 \f
324 /* Routine to see if exception handling is turned on.
325    DO_WARN is nonzero if we want to inform the user that exception
326    handling is turned off.
327
328    This is used to ensure that -fexceptions has been specified if the
329    compiler tries to use any exception-specific functions.  */
330
331 int
332 doing_eh (int do_warn)
333 {
334   if (! flag_exceptions)
335     {
336       static int warned = 0;
337       if (! warned && do_warn)
338         {
339           error ("exception handling disabled, use -fexceptions to enable");
340           warned = 1;
341         }
342       return 0;
343     }
344   return 1;
345 }
346
347 \f
348 void
349 init_eh (void)
350 {
351   if (! flag_exceptions)
352     return;
353
354   type_to_runtime_map = htab_create_ggc (31, t2r_hash, t2r_eq, NULL);
355
356   /* Create the SjLj_Function_Context structure.  This should match
357      the definition in unwind-sjlj.c.  */
358   if (USING_SJLJ_EXCEPTIONS)
359     {
360       tree f_jbuf, f_per, f_lsda, f_prev, f_cs, f_data, tmp;
361
362       sjlj_fc_type_node = lang_hooks.types.make_type (RECORD_TYPE);
363
364       f_prev = build_decl (FIELD_DECL, get_identifier ("__prev"),
365                            build_pointer_type (sjlj_fc_type_node));
366       DECL_FIELD_CONTEXT (f_prev) = sjlj_fc_type_node;
367
368       f_cs = build_decl (FIELD_DECL, get_identifier ("__call_site"),
369                          integer_type_node);
370       DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node;
371
372       tmp = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
373       tmp = build_array_type (lang_hooks.types.type_for_mode (word_mode, 1),
374                               tmp);
375       f_data = build_decl (FIELD_DECL, get_identifier ("__data"), tmp);
376       DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node;
377
378       f_per = build_decl (FIELD_DECL, get_identifier ("__personality"),
379                           ptr_type_node);
380       DECL_FIELD_CONTEXT (f_per) = sjlj_fc_type_node;
381
382       f_lsda = build_decl (FIELD_DECL, get_identifier ("__lsda"),
383                            ptr_type_node);
384       DECL_FIELD_CONTEXT (f_lsda) = sjlj_fc_type_node;
385
386 #ifdef DONT_USE_BUILTIN_SETJMP
387 #ifdef JMP_BUF_SIZE
388       tmp = build_int_cst (NULL_TREE, JMP_BUF_SIZE - 1);
389 #else
390       /* Should be large enough for most systems, if it is not,
391          JMP_BUF_SIZE should be defined with the proper value.  It will
392          also tend to be larger than necessary for most systems, a more
393          optimal port will define JMP_BUF_SIZE.  */
394       tmp = build_int_cst (NULL_TREE, FIRST_PSEUDO_REGISTER + 2 - 1);
395 #endif
396 #else
397       /* builtin_setjmp takes a pointer to 5 words.  */
398       tmp = build_int_cst (NULL_TREE, 5 * BITS_PER_WORD / POINTER_SIZE - 1);
399 #endif
400       tmp = build_index_type (tmp);
401       tmp = build_array_type (ptr_type_node, tmp);
402       f_jbuf = build_decl (FIELD_DECL, get_identifier ("__jbuf"), tmp);
403 #ifdef DONT_USE_BUILTIN_SETJMP
404       /* We don't know what the alignment requirements of the
405          runtime's jmp_buf has.  Overestimate.  */
406       DECL_ALIGN (f_jbuf) = BIGGEST_ALIGNMENT;
407       DECL_USER_ALIGN (f_jbuf) = 1;
408 #endif
409       DECL_FIELD_CONTEXT (f_jbuf) = sjlj_fc_type_node;
410
411       TYPE_FIELDS (sjlj_fc_type_node) = f_prev;
412       TREE_CHAIN (f_prev) = f_cs;
413       TREE_CHAIN (f_cs) = f_data;
414       TREE_CHAIN (f_data) = f_per;
415       TREE_CHAIN (f_per) = f_lsda;
416       TREE_CHAIN (f_lsda) = f_jbuf;
417
418       layout_type (sjlj_fc_type_node);
419
420       /* Cache the interesting field offsets so that we have
421          easy access from rtl.  */
422       sjlj_fc_call_site_ofs
423         = (tree_low_cst (DECL_FIELD_OFFSET (f_cs), 1)
424            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_cs), 1) / BITS_PER_UNIT);
425       sjlj_fc_data_ofs
426         = (tree_low_cst (DECL_FIELD_OFFSET (f_data), 1)
427            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_data), 1) / BITS_PER_UNIT);
428       sjlj_fc_personality_ofs
429         = (tree_low_cst (DECL_FIELD_OFFSET (f_per), 1)
430            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_per), 1) / BITS_PER_UNIT);
431       sjlj_fc_lsda_ofs
432         = (tree_low_cst (DECL_FIELD_OFFSET (f_lsda), 1)
433            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_lsda), 1) / BITS_PER_UNIT);
434       sjlj_fc_jbuf_ofs
435         = (tree_low_cst (DECL_FIELD_OFFSET (f_jbuf), 1)
436            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_jbuf), 1) / BITS_PER_UNIT);
437     }
438 }
439
440 void
441 init_eh_for_function (void)
442 {
443   cfun->eh = ggc_alloc_cleared (sizeof (struct eh_status));
444 }
445 \f
446 /* Routines to generate the exception tree somewhat directly.  
447    These are used from tree-eh.c when processing exception related
448    nodes during tree optimization.  */
449
450 static struct eh_region *
451 gen_eh_region (enum eh_region_type type, struct eh_region *outer)
452 {
453   struct eh_region *new;
454
455 #ifdef ENABLE_CHECKING
456   gcc_assert (doing_eh (0));
457 #endif
458
459   /* Insert a new blank region as a leaf in the tree.  */
460   new = ggc_alloc_cleared (sizeof (*new));
461   new->type = type;
462   new->outer = outer;
463   if (outer)
464     {
465       new->next_peer = outer->inner;
466       outer->inner = new;
467     }
468   else
469     {
470       new->next_peer = cfun->eh->region_tree;
471       cfun->eh->region_tree = new;
472     }
473
474   new->region_number = ++cfun->eh->last_region_number;
475
476   return new;
477 }
478
479 struct eh_region *
480 gen_eh_region_cleanup (struct eh_region *outer, struct eh_region *prev_try)
481 {
482   struct eh_region *cleanup = gen_eh_region (ERT_CLEANUP, outer);
483   cleanup->u.cleanup.prev_try = prev_try;
484   return cleanup;
485 }
486
487 struct eh_region *
488 gen_eh_region_try (struct eh_region *outer)
489 {
490   return gen_eh_region (ERT_TRY, outer);
491 }
492
493 struct eh_region *
494 gen_eh_region_catch (struct eh_region *t, tree type_or_list)
495 {
496   struct eh_region *c, *l;
497   tree type_list, type_node;
498
499   /* Ensure to always end up with a type list to normalize further
500      processing, then register each type against the runtime types map.  */
501   type_list = type_or_list;
502   if (type_or_list)
503     {
504       if (TREE_CODE (type_or_list) != TREE_LIST)
505         type_list = tree_cons (NULL_TREE, type_or_list, NULL_TREE);
506
507       type_node = type_list;
508       for (; type_node; type_node = TREE_CHAIN (type_node))
509         add_type_for_runtime (TREE_VALUE (type_node));
510     }
511
512   c = gen_eh_region (ERT_CATCH, t->outer);
513   c->u.catch.type_list = type_list;
514   l = t->u.try.last_catch;
515   c->u.catch.prev_catch = l;
516   if (l)
517     l->u.catch.next_catch = c;
518   else
519     t->u.try.catch = c;
520   t->u.try.last_catch = c;
521
522   return c;
523 }
524
525 struct eh_region *
526 gen_eh_region_allowed (struct eh_region *outer, tree allowed)
527 {
528   struct eh_region *region = gen_eh_region (ERT_ALLOWED_EXCEPTIONS, outer);
529   region->u.allowed.type_list = allowed;
530
531   for (; allowed ; allowed = TREE_CHAIN (allowed))
532     add_type_for_runtime (TREE_VALUE (allowed));
533
534   return region;
535 }
536
537 struct eh_region *
538 gen_eh_region_must_not_throw (struct eh_region *outer)
539 {
540   return gen_eh_region (ERT_MUST_NOT_THROW, outer);
541 }
542
543 int
544 get_eh_region_number (struct eh_region *region)
545 {
546   return region->region_number;
547 }
548
549 bool
550 get_eh_region_may_contain_throw (struct eh_region *region)
551 {
552   return region->may_contain_throw;
553 }
554
555 tree
556 get_eh_region_tree_label (struct eh_region *region)
557 {
558   return region->tree_label;
559 }
560
561 void
562 set_eh_region_tree_label (struct eh_region *region, tree lab)
563 {
564   region->tree_label = lab;
565 }
566 \f
567 void
568 expand_resx_expr (tree exp)
569 {
570   int region_nr = TREE_INT_CST_LOW (TREE_OPERAND (exp, 0));
571   struct eh_region *reg = cfun->eh->region_array[region_nr];
572
573   reg->resume = emit_jump_insn (gen_rtx_RESX (VOIDmode, region_nr));
574   emit_barrier ();
575 }
576
577 /* Note that the current EH region (if any) may contain a throw, or a
578    call to a function which itself may contain a throw.  */
579
580 void
581 note_eh_region_may_contain_throw (struct eh_region *region)
582 {
583   while (region && !region->may_contain_throw)
584     {
585       region->may_contain_throw = 1;
586       region = region->outer;
587     }
588 }
589
590 void
591 note_current_region_may_contain_throw (void)
592 {
593   note_eh_region_may_contain_throw (cfun->eh->cur_region);
594 }
595
596
597 /* Return an rtl expression for a pointer to the exception object
598    within a handler.  */
599
600 rtx
601 get_exception_pointer (struct function *fun)
602 {
603   rtx exc_ptr = fun->eh->exc_ptr;
604   if (fun == cfun && ! exc_ptr)
605     {
606       exc_ptr = gen_reg_rtx (ptr_mode);
607       fun->eh->exc_ptr = exc_ptr;
608     }
609   return exc_ptr;
610 }
611
612 /* Return an rtl expression for the exception dispatch filter
613    within a handler.  */
614
615 rtx
616 get_exception_filter (struct function *fun)
617 {
618   rtx filter = fun->eh->filter;
619   if (fun == cfun && ! filter)
620     {
621       filter = gen_reg_rtx (targetm.eh_return_filter_mode ());
622       fun->eh->filter = filter;
623     }
624   return filter;
625 }
626 \f
627 /* This section is for the exception handling specific optimization pass.  */
628
629 /* Random access the exception region tree.  */
630
631 void
632 collect_eh_region_array (void)
633 {
634   struct eh_region **array, *i;
635
636   i = cfun->eh->region_tree;
637   if (! i)
638     return;
639
640   array = ggc_alloc_cleared ((cfun->eh->last_region_number + 1)
641                              * sizeof (*array));
642   cfun->eh->region_array = array;
643
644   while (1)
645     {
646       array[i->region_number] = i;
647
648       /* If there are sub-regions, process them.  */
649       if (i->inner)
650         i = i->inner;
651       /* If there are peers, process them.  */
652       else if (i->next_peer)
653         i = i->next_peer;
654       /* Otherwise, step back up the tree to the next peer.  */
655       else
656         {
657           do {
658             i = i->outer;
659             if (i == NULL)
660               return;
661           } while (i->next_peer == NULL);
662           i = i->next_peer;
663         }
664     }
665 }
666
667 /* Remove all regions whose labels are not reachable from insns.  */
668
669 static void
670 remove_unreachable_regions (rtx insns)
671 {
672   int i, *uid_region_num;
673   bool *reachable;
674   struct eh_region *r;
675   rtx insn;
676
677   uid_region_num = xcalloc (get_max_uid (), sizeof(int));
678   reachable = xcalloc (cfun->eh->last_region_number + 1, sizeof(bool));
679
680   for (i = cfun->eh->last_region_number; i > 0; --i)
681     {
682       r = cfun->eh->region_array[i];
683       if (!r || r->region_number != i)
684         continue;
685
686       if (r->resume)
687         {
688           gcc_assert (!uid_region_num[INSN_UID (r->resume)]);
689           uid_region_num[INSN_UID (r->resume)] = i;
690         }
691       if (r->label)
692         {
693           gcc_assert (!uid_region_num[INSN_UID (r->label)]);
694           uid_region_num[INSN_UID (r->label)] = i;
695         }
696     }
697
698   for (insn = insns; insn; insn = NEXT_INSN (insn))
699     reachable[uid_region_num[INSN_UID (insn)]] = true;
700
701   for (i = cfun->eh->last_region_number; i > 0; --i)
702     {
703       r = cfun->eh->region_array[i];
704       if (r && r->region_number == i && !reachable[i])
705         {
706           bool kill_it = true;
707           switch (r->type)
708             {
709             case ERT_THROW:
710               /* Don't remove ERT_THROW regions if their outer region
711                  is reachable.  */
712               if (r->outer && reachable[r->outer->region_number])
713                 kill_it = false;
714               break;
715
716             case ERT_MUST_NOT_THROW:
717               /* MUST_NOT_THROW regions are implementable solely in the
718                  runtime, but their existence continues to affect calls
719                  within that region.  Never delete them here.  */
720               kill_it = false;
721               break;
722
723             case ERT_TRY:
724               {
725                 /* TRY regions are reachable if any of its CATCH regions
726                    are reachable.  */
727                 struct eh_region *c;
728                 for (c = r->u.try.catch; c ; c = c->u.catch.next_catch)
729                   if (reachable[c->region_number])
730                     {
731                       kill_it = false;
732                       break;
733                     }
734                 break;
735               }
736
737             default:
738               break;
739             }
740               
741           if (kill_it)
742             remove_eh_handler (r);
743         }
744     }
745
746   free (reachable);
747   free (uid_region_num);
748 }
749
750 /* Set up EH labels for RTL.  */
751
752 void
753 convert_from_eh_region_ranges (void)
754 {
755   rtx insns = get_insns ();
756   int i, n = cfun->eh->last_region_number;
757
758   /* Most of the work is already done at the tree level.  All we need to
759      do is collect the rtl labels that correspond to the tree labels that
760      collect the rtl labels that correspond to the tree labels
761      we allocated earlier.  */
762   for (i = 1; i <= n; ++i)
763     {
764       struct eh_region *region = cfun->eh->region_array[i];
765       if (region && region->tree_label)
766         region->label = DECL_RTL_IF_SET (region->tree_label);
767     }
768
769   remove_unreachable_regions (insns);
770 }
771
772 static void
773 add_ehl_entry (rtx label, struct eh_region *region)
774 {
775   struct ehl_map_entry **slot, *entry;
776
777   LABEL_PRESERVE_P (label) = 1;
778
779   entry = ggc_alloc (sizeof (*entry));
780   entry->label = label;
781   entry->region = region;
782
783   slot = (struct ehl_map_entry **)
784     htab_find_slot (cfun->eh->exception_handler_label_map, entry, INSERT);
785
786   /* Before landing pad creation, each exception handler has its own
787      label.  After landing pad creation, the exception handlers may
788      share landing pads.  This is ok, since maybe_remove_eh_handler
789      only requires the 1-1 mapping before landing pad creation.  */
790   gcc_assert (!*slot || cfun->eh->built_landing_pads);
791
792   *slot = entry;
793 }
794
795 void
796 find_exception_handler_labels (void)
797 {
798   int i;
799
800   if (cfun->eh->exception_handler_label_map)
801     htab_empty (cfun->eh->exception_handler_label_map);
802   else
803     {
804       /* ??? The expansion factor here (3/2) must be greater than the htab
805          occupancy factor (4/3) to avoid unnecessary resizing.  */
806       cfun->eh->exception_handler_label_map
807         = htab_create_ggc (cfun->eh->last_region_number * 3 / 2,
808                            ehl_hash, ehl_eq, NULL);
809     }
810
811   if (cfun->eh->region_tree == NULL)
812     return;
813
814   for (i = cfun->eh->last_region_number; i > 0; --i)
815     {
816       struct eh_region *region = cfun->eh->region_array[i];
817       rtx lab;
818
819       if (! region || region->region_number != i)
820         continue;
821       if (cfun->eh->built_landing_pads)
822         lab = region->landing_pad;
823       else
824         lab = region->label;
825
826       if (lab)
827         add_ehl_entry (lab, region);
828     }
829
830   /* For sjlj exceptions, need the return label to remain live until
831      after landing pad generation.  */
832   if (USING_SJLJ_EXCEPTIONS && ! cfun->eh->built_landing_pads)
833     add_ehl_entry (return_label, NULL);
834 }
835
836 bool
837 current_function_has_exception_handlers (void)
838 {
839   int i;
840
841   for (i = cfun->eh->last_region_number; i > 0; --i)
842     {
843       struct eh_region *region = cfun->eh->region_array[i];
844
845       if (! region || region->region_number != i)
846         continue;
847       if (region->type != ERT_THROW)
848         return true;
849     }
850
851   return false;
852 }
853 \f
854 static int
855 t2r_eq (const void *pentry, const void *pdata)
856 {
857   tree entry = (tree) pentry;
858   tree data = (tree) pdata;
859
860   return TREE_PURPOSE (entry) == data;
861 }
862
863 static hashval_t
864 t2r_hash (const void *pentry)
865 {
866   tree entry = (tree) pentry;
867   return TREE_HASH (TREE_PURPOSE (entry));
868 }
869
870 static void
871 add_type_for_runtime (tree type)
872 {
873   tree *slot;
874
875   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
876                                             TREE_HASH (type), INSERT);
877   if (*slot == NULL)
878     {
879       tree runtime = (*lang_eh_runtime_type) (type);
880       *slot = tree_cons (type, runtime, NULL_TREE);
881     }
882 }
883
884 static tree
885 lookup_type_for_runtime (tree type)
886 {
887   tree *slot;
888
889   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
890                                             TREE_HASH (type), NO_INSERT);
891
892   /* We should have always inserted the data earlier.  */
893   return TREE_VALUE (*slot);
894 }
895
896 \f
897 /* Represent an entry in @TTypes for either catch actions
898    or exception filter actions.  */
899 struct ttypes_filter GTY(())
900 {
901   tree t;
902   int filter;
903 };
904
905 /* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
906    (a tree) for a @TTypes type node we are thinking about adding.  */
907
908 static int
909 ttypes_filter_eq (const void *pentry, const void *pdata)
910 {
911   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
912   tree data = (tree) pdata;
913
914   return entry->t == data;
915 }
916
917 static hashval_t
918 ttypes_filter_hash (const void *pentry)
919 {
920   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
921   return TREE_HASH (entry->t);
922 }
923
924 /* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
925    exception specification list we are thinking about adding.  */
926 /* ??? Currently we use the type lists in the order given.  Someone
927    should put these in some canonical order.  */
928
929 static int
930 ehspec_filter_eq (const void *pentry, const void *pdata)
931 {
932   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
933   const struct ttypes_filter *data = (const struct ttypes_filter *) pdata;
934
935   return type_list_equal (entry->t, data->t);
936 }
937
938 /* Hash function for exception specification lists.  */
939
940 static hashval_t
941 ehspec_filter_hash (const void *pentry)
942 {
943   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
944   hashval_t h = 0;
945   tree list;
946
947   for (list = entry->t; list ; list = TREE_CHAIN (list))
948     h = (h << 5) + (h >> 27) + TREE_HASH (TREE_VALUE (list));
949   return h;
950 }
951
952 /* Add TYPE (which may be NULL) to cfun->eh->ttype_data, using TYPES_HASH
953    to speed up the search.  Return the filter value to be used.  */
954
955 static int
956 add_ttypes_entry (htab_t ttypes_hash, tree type)
957 {
958   struct ttypes_filter **slot, *n;
959
960   slot = (struct ttypes_filter **)
961     htab_find_slot_with_hash (ttypes_hash, type, TREE_HASH (type), INSERT);
962
963   if ((n = *slot) == NULL)
964     {
965       /* Filter value is a 1 based table index.  */
966
967       n = xmalloc (sizeof (*n));
968       n->t = type;
969       n->filter = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) + 1;
970       *slot = n;
971
972       VARRAY_PUSH_TREE (cfun->eh->ttype_data, type);
973     }
974
975   return n->filter;
976 }
977
978 /* Add LIST to cfun->eh->ehspec_data, using EHSPEC_HASH and TYPES_HASH
979    to speed up the search.  Return the filter value to be used.  */
980
981 static int
982 add_ehspec_entry (htab_t ehspec_hash, htab_t ttypes_hash, tree list)
983 {
984   struct ttypes_filter **slot, *n;
985   struct ttypes_filter dummy;
986
987   dummy.t = list;
988   slot = (struct ttypes_filter **)
989     htab_find_slot (ehspec_hash, &dummy, INSERT);
990
991   if ((n = *slot) == NULL)
992     {
993       /* Filter value is a -1 based byte index into a uleb128 buffer.  */
994
995       n = xmalloc (sizeof (*n));
996       n->t = list;
997       n->filter = -(VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) + 1);
998       *slot = n;
999
1000       /* Look up each type in the list and encode its filter
1001          value as a uleb128.  Terminate the list with 0.  */
1002       for (; list ; list = TREE_CHAIN (list))
1003         push_uleb128 (&cfun->eh->ehspec_data,
1004                       add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
1005       VARRAY_PUSH_UCHAR (cfun->eh->ehspec_data, 0);
1006     }
1007
1008   return n->filter;
1009 }
1010
1011 /* Generate the action filter values to be used for CATCH and
1012    ALLOWED_EXCEPTIONS regions.  When using dwarf2 exception regions,
1013    we use lots of landing pads, and so every type or list can share
1014    the same filter value, which saves table space.  */
1015
1016 static void
1017 assign_filter_values (void)
1018 {
1019   int i;
1020   htab_t ttypes, ehspec;
1021
1022   VARRAY_TREE_INIT (cfun->eh->ttype_data, 16, "ttype_data");
1023   VARRAY_UCHAR_INIT (cfun->eh->ehspec_data, 64, "ehspec_data");
1024
1025   ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free);
1026   ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free);
1027
1028   for (i = cfun->eh->last_region_number; i > 0; --i)
1029     {
1030       struct eh_region *r = cfun->eh->region_array[i];
1031
1032       /* Mind we don't process a region more than once.  */
1033       if (!r || r->region_number != i)
1034         continue;
1035
1036       switch (r->type)
1037         {
1038         case ERT_CATCH:
1039           /* Whatever type_list is (NULL or true list), we build a list
1040              of filters for the region.  */
1041           r->u.catch.filter_list = NULL_TREE;
1042
1043           if (r->u.catch.type_list != NULL)
1044             {
1045               /* Get a filter value for each of the types caught and store
1046                  them in the region's dedicated list.  */
1047               tree tp_node = r->u.catch.type_list;
1048
1049               for (;tp_node; tp_node = TREE_CHAIN (tp_node))
1050                 {
1051                   int flt = add_ttypes_entry (ttypes, TREE_VALUE (tp_node));
1052                   tree flt_node = build_int_cst (NULL_TREE, flt);
1053
1054                   r->u.catch.filter_list
1055                     = tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list);
1056                 }
1057             }
1058           else
1059             {
1060               /* Get a filter value for the NULL list also since it will need
1061                  an action record anyway.  */
1062               int flt = add_ttypes_entry (ttypes, NULL);
1063               tree flt_node = build_int_cst (NULL_TREE, flt);
1064
1065               r->u.catch.filter_list
1066                 = tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list);
1067             }
1068
1069           break;
1070
1071         case ERT_ALLOWED_EXCEPTIONS:
1072           r->u.allowed.filter
1073             = add_ehspec_entry (ehspec, ttypes, r->u.allowed.type_list);
1074           break;
1075
1076         default:
1077           break;
1078         }
1079     }
1080
1081   htab_delete (ttypes);
1082   htab_delete (ehspec);
1083 }
1084
1085 /* Emit SEQ into basic block just before INSN (that is assumed to be
1086    first instruction of some existing BB and return the newly
1087    produced block.  */
1088 static basic_block
1089 emit_to_new_bb_before (rtx seq, rtx insn)
1090 {
1091   rtx last;
1092   basic_block bb;
1093   edge e;
1094   edge_iterator ei;
1095
1096   /* If there happens to be a fallthru edge (possibly created by cleanup_cfg
1097      call), we don't want it to go into newly created landing pad or other EH 
1098      construct.  */
1099   for (ei = ei_start (BLOCK_FOR_INSN (insn)->preds); (e = ei_safe_edge (ei)); )
1100     if (e->flags & EDGE_FALLTHRU)
1101       force_nonfallthru (e);
1102     else
1103       ei_next (&ei);
1104   last = emit_insn_before (seq, insn);
1105   if (BARRIER_P (last))
1106     last = PREV_INSN (last);
1107   bb = create_basic_block (seq, last, BLOCK_FOR_INSN (insn)->prev_bb);
1108   update_bb_for_insn (bb);
1109   bb->flags |= BB_SUPERBLOCK;
1110   return bb;
1111 }
1112
1113 /* Generate the code to actually handle exceptions, which will follow the
1114    landing pads.  */
1115
1116 static void
1117 build_post_landing_pads (void)
1118 {
1119   int i;
1120
1121   for (i = cfun->eh->last_region_number; i > 0; --i)
1122     {
1123       struct eh_region *region = cfun->eh->region_array[i];
1124       rtx seq;
1125
1126       /* Mind we don't process a region more than once.  */
1127       if (!region || region->region_number != i)
1128         continue;
1129
1130       switch (region->type)
1131         {
1132         case ERT_TRY:
1133           /* ??? Collect the set of all non-overlapping catch handlers
1134                all the way up the chain until blocked by a cleanup.  */
1135           /* ??? Outer try regions can share landing pads with inner
1136              try regions if the types are completely non-overlapping,
1137              and there are no intervening cleanups.  */
1138
1139           region->post_landing_pad = gen_label_rtx ();
1140
1141           start_sequence ();
1142
1143           emit_label (region->post_landing_pad);
1144
1145           /* ??? It is mighty inconvenient to call back into the
1146              switch statement generation code in expand_end_case.
1147              Rapid prototyping sez a sequence of ifs.  */
1148           {
1149             struct eh_region *c;
1150             for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
1151               {
1152                 if (c->u.catch.type_list == NULL)
1153                   emit_jump (c->label);
1154                 else
1155                   {
1156                     /* Need for one cmp/jump per type caught. Each type
1157                        list entry has a matching entry in the filter list
1158                        (see assign_filter_values).  */
1159                     tree tp_node = c->u.catch.type_list;
1160                     tree flt_node = c->u.catch.filter_list;
1161
1162                     for (; tp_node; )
1163                       {
1164                         emit_cmp_and_jump_insns
1165                           (cfun->eh->filter,
1166                            GEN_INT (tree_low_cst (TREE_VALUE (flt_node), 0)),
1167                            EQ, NULL_RTX, 
1168                            targetm.eh_return_filter_mode (), 0, c->label);
1169
1170                         tp_node = TREE_CHAIN (tp_node);
1171                         flt_node = TREE_CHAIN (flt_node);
1172                       }
1173                   }
1174               }
1175           }
1176
1177           /* We delay the generation of the _Unwind_Resume until we generate
1178              landing pads.  We emit a marker here so as to get good control
1179              flow data in the meantime.  */
1180           region->resume
1181             = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1182           emit_barrier ();
1183
1184           seq = get_insns ();
1185           end_sequence ();
1186
1187           emit_to_new_bb_before (seq, region->u.try.catch->label);
1188
1189           break;
1190
1191         case ERT_ALLOWED_EXCEPTIONS:
1192           region->post_landing_pad = gen_label_rtx ();
1193
1194           start_sequence ();
1195
1196           emit_label (region->post_landing_pad);
1197
1198           emit_cmp_and_jump_insns (cfun->eh->filter,
1199                                    GEN_INT (region->u.allowed.filter),
1200                                    EQ, NULL_RTX, 
1201                                    targetm.eh_return_filter_mode (), 0, region->label);
1202
1203           /* We delay the generation of the _Unwind_Resume until we generate
1204              landing pads.  We emit a marker here so as to get good control
1205              flow data in the meantime.  */
1206           region->resume
1207             = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1208           emit_barrier ();
1209
1210           seq = get_insns ();
1211           end_sequence ();
1212
1213           emit_to_new_bb_before (seq, region->label);
1214           break;
1215
1216         case ERT_CLEANUP:
1217         case ERT_MUST_NOT_THROW:
1218           region->post_landing_pad = region->label;
1219           break;
1220
1221         case ERT_CATCH:
1222         case ERT_THROW:
1223           /* Nothing to do.  */
1224           break;
1225
1226         default:
1227           gcc_unreachable ();
1228         }
1229     }
1230 }
1231
1232 /* Replace RESX patterns with jumps to the next handler if any, or calls to
1233    _Unwind_Resume otherwise.  */
1234
1235 static void
1236 connect_post_landing_pads (void)
1237 {
1238   int i;
1239
1240   for (i = cfun->eh->last_region_number; i > 0; --i)
1241     {
1242       struct eh_region *region = cfun->eh->region_array[i];
1243       struct eh_region *outer;
1244       rtx seq;
1245       rtx barrier;
1246
1247       /* Mind we don't process a region more than once.  */
1248       if (!region || region->region_number != i)
1249         continue;
1250
1251       /* If there is no RESX, or it has been deleted by flow, there's
1252          nothing to fix up.  */
1253       if (! region->resume || INSN_DELETED_P (region->resume))
1254         continue;
1255
1256       /* Search for another landing pad in this function.  */
1257       for (outer = region->outer; outer ; outer = outer->outer)
1258         if (outer->post_landing_pad)
1259           break;
1260
1261       start_sequence ();
1262
1263       if (outer)
1264         {
1265           edge e;
1266           basic_block src, dest;
1267
1268           emit_jump (outer->post_landing_pad);
1269           src = BLOCK_FOR_INSN (region->resume);
1270           dest = BLOCK_FOR_INSN (outer->post_landing_pad);
1271           while (EDGE_COUNT (src->succs) > 0)
1272             remove_edge (EDGE_SUCC (src, 0));
1273           e = make_edge (src, dest, 0);
1274           e->probability = REG_BR_PROB_BASE;
1275           e->count = src->count;
1276         }
1277       else
1278         {
1279           emit_library_call (unwind_resume_libfunc, LCT_THROW,
1280                              VOIDmode, 1, cfun->eh->exc_ptr, ptr_mode);
1281
1282           /* What we just emitted was a throwing libcall, so it got a
1283              barrier automatically added after it.  If the last insn in
1284              the libcall sequence isn't the barrier, it's because the
1285              target emits multiple insns for a call, and there are insns
1286              after the actual call insn (which are redundant and would be
1287              optimized away).  The barrier is inserted exactly after the
1288              call insn, so let's go get that and delete the insns after
1289              it, because below we need the barrier to be the last insn in
1290              the sequence.  */
1291           delete_insns_since (NEXT_INSN (last_call_insn ()));
1292         }
1293
1294       seq = get_insns ();
1295       end_sequence ();
1296       barrier = emit_insn_before (seq, region->resume);
1297       /* Avoid duplicate barrier.  */
1298       gcc_assert (BARRIER_P (barrier));
1299       delete_insn (barrier);
1300       delete_insn (region->resume);
1301
1302       /* ??? From tree-ssa we can wind up with catch regions whose
1303          label is not instantiated, but whose resx is present.  Now
1304          that we've dealt with the resx, kill the region.  */
1305       if (region->label == NULL && region->type == ERT_CLEANUP)
1306         remove_eh_handler (region);
1307     }
1308 }
1309
1310 \f
1311 static void
1312 dw2_build_landing_pads (void)
1313 {
1314   int i;
1315   unsigned int j;
1316
1317   for (i = cfun->eh->last_region_number; i > 0; --i)
1318     {
1319       struct eh_region *region = cfun->eh->region_array[i];
1320       rtx seq;
1321       basic_block bb;
1322       bool clobbers_hard_regs = false;
1323       edge e;
1324
1325       /* Mind we don't process a region more than once.  */
1326       if (!region || region->region_number != i)
1327         continue;
1328
1329       if (region->type != ERT_CLEANUP
1330           && region->type != ERT_TRY
1331           && region->type != ERT_ALLOWED_EXCEPTIONS)
1332         continue;
1333
1334       start_sequence ();
1335
1336       region->landing_pad = gen_label_rtx ();
1337       emit_label (region->landing_pad);
1338
1339 #ifdef HAVE_exception_receiver
1340       if (HAVE_exception_receiver)
1341         emit_insn (gen_exception_receiver ());
1342       else
1343 #endif
1344 #ifdef HAVE_nonlocal_goto_receiver
1345         if (HAVE_nonlocal_goto_receiver)
1346           emit_insn (gen_nonlocal_goto_receiver ());
1347         else
1348 #endif
1349           { /* Nothing */ }
1350
1351       /* If the eh_return data registers are call-saved, then we
1352          won't have considered them clobbered from the call that
1353          threw.  Kill them now.  */
1354       for (j = 0; ; ++j)
1355         {
1356           unsigned r = EH_RETURN_DATA_REGNO (j);
1357           if (r == INVALID_REGNUM)
1358             break;
1359           if (! call_used_regs[r])
1360             {
1361               emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, r)));
1362               clobbers_hard_regs = true;
1363             }
1364         }
1365
1366       if (clobbers_hard_regs)
1367         {
1368           /* @@@ This is a kludge.  Not all machine descriptions define a
1369              blockage insn, but we must not allow the code we just generated
1370              to be reordered by scheduling.  So emit an ASM_INPUT to act as
1371              blockage insn.  */
1372           emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
1373         }
1374
1375       emit_move_insn (cfun->eh->exc_ptr,
1376                       gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0)));
1377       emit_move_insn (cfun->eh->filter,
1378                       gen_rtx_REG (targetm.eh_return_filter_mode (), 
1379                                    EH_RETURN_DATA_REGNO (1)));
1380
1381       seq = get_insns ();
1382       end_sequence ();
1383
1384       bb = emit_to_new_bb_before (seq, region->post_landing_pad);
1385       e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
1386       e->count = bb->count;
1387       e->probability = REG_BR_PROB_BASE;
1388     }
1389 }
1390
1391 \f
1392 struct sjlj_lp_info
1393 {
1394   int directly_reachable;
1395   int action_index;
1396   int dispatch_index;
1397   int call_site_index;
1398 };
1399
1400 static bool
1401 sjlj_find_directly_reachable_regions (struct sjlj_lp_info *lp_info)
1402 {
1403   rtx insn;
1404   bool found_one = false;
1405
1406   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
1407     {
1408       struct eh_region *region;
1409       enum reachable_code rc;
1410       tree type_thrown;
1411       rtx note;
1412
1413       if (! INSN_P (insn))
1414         continue;
1415
1416       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1417       if (!note || INTVAL (XEXP (note, 0)) <= 0)
1418         continue;
1419
1420       region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
1421
1422       type_thrown = NULL_TREE;
1423       if (region->type == ERT_THROW)
1424         {
1425           type_thrown = region->u.throw.type;
1426           region = region->outer;
1427         }
1428
1429       /* Find the first containing region that might handle the exception.
1430          That's the landing pad to which we will transfer control.  */
1431       rc = RNL_NOT_CAUGHT;
1432       for (; region; region = region->outer)
1433         {
1434           rc = reachable_next_level (region, type_thrown, NULL);
1435           if (rc != RNL_NOT_CAUGHT)
1436             break;
1437         }
1438       if (rc == RNL_MAYBE_CAUGHT || rc == RNL_CAUGHT)
1439         {
1440           lp_info[region->region_number].directly_reachable = 1;
1441           found_one = true;
1442         }
1443     }
1444
1445   return found_one;
1446 }
1447
1448 static void
1449 sjlj_assign_call_site_values (rtx dispatch_label, struct sjlj_lp_info *lp_info)
1450 {
1451   htab_t ar_hash;
1452   int i, index;
1453
1454   /* First task: build the action table.  */
1455
1456   VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
1457   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
1458
1459   for (i = cfun->eh->last_region_number; i > 0; --i)
1460     if (lp_info[i].directly_reachable)
1461       {
1462         struct eh_region *r = cfun->eh->region_array[i];
1463         r->landing_pad = dispatch_label;
1464         lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
1465         if (lp_info[i].action_index != -1)
1466           cfun->uses_eh_lsda = 1;
1467       }
1468
1469   htab_delete (ar_hash);
1470
1471   /* Next: assign dispatch values.  In dwarf2 terms, this would be the
1472      landing pad label for the region.  For sjlj though, there is one
1473      common landing pad from which we dispatch to the post-landing pads.
1474
1475      A region receives a dispatch index if it is directly reachable
1476      and requires in-function processing.  Regions that share post-landing
1477      pads may share dispatch indices.  */
1478   /* ??? Post-landing pad sharing doesn't actually happen at the moment
1479      (see build_post_landing_pads) so we don't bother checking for it.  */
1480
1481   index = 0;
1482   for (i = cfun->eh->last_region_number; i > 0; --i)
1483     if (lp_info[i].directly_reachable)
1484       lp_info[i].dispatch_index = index++;
1485
1486   /* Finally: assign call-site values.  If dwarf2 terms, this would be
1487      the region number assigned by convert_to_eh_region_ranges, but
1488      handles no-action and must-not-throw differently.  */
1489
1490   call_site_base = 1;
1491   for (i = cfun->eh->last_region_number; i > 0; --i)
1492     if (lp_info[i].directly_reachable)
1493       {
1494         int action = lp_info[i].action_index;
1495
1496         /* Map must-not-throw to otherwise unused call-site index 0.  */
1497         if (action == -2)
1498           index = 0;
1499         /* Map no-action to otherwise unused call-site index -1.  */
1500         else if (action == -1)
1501           index = -1;
1502         /* Otherwise, look it up in the table.  */
1503         else
1504           index = add_call_site (GEN_INT (lp_info[i].dispatch_index), action);
1505
1506         lp_info[i].call_site_index = index;
1507       }
1508 }
1509
1510 static void
1511 sjlj_mark_call_sites (struct sjlj_lp_info *lp_info)
1512 {
1513   int last_call_site = -2;
1514   rtx insn, mem;
1515
1516   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
1517     {
1518       struct eh_region *region;
1519       int this_call_site;
1520       rtx note, before, p;
1521
1522       /* Reset value tracking at extended basic block boundaries.  */
1523       if (LABEL_P (insn))
1524         last_call_site = -2;
1525
1526       if (! INSN_P (insn))
1527         continue;
1528
1529       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1530       if (!note)
1531         {
1532           /* Calls (and trapping insns) without notes are outside any
1533              exception handling region in this function.  Mark them as
1534              no action.  */
1535           if (CALL_P (insn)
1536               || (flag_non_call_exceptions
1537                   && may_trap_p (PATTERN (insn))))
1538             this_call_site = -1;
1539           else
1540             continue;
1541         }
1542       else
1543         {
1544           /* Calls that are known to not throw need not be marked.  */
1545           if (INTVAL (XEXP (note, 0)) <= 0)
1546             continue;
1547
1548           region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
1549           this_call_site = lp_info[region->region_number].call_site_index;
1550         }
1551
1552       if (this_call_site == last_call_site)
1553         continue;
1554
1555       /* Don't separate a call from it's argument loads.  */
1556       before = insn;
1557       if (CALL_P (insn))
1558         before = find_first_parameter_load (insn, NULL_RTX);
1559
1560       start_sequence ();
1561       mem = adjust_address (cfun->eh->sjlj_fc, TYPE_MODE (integer_type_node),
1562                             sjlj_fc_call_site_ofs);
1563       emit_move_insn (mem, GEN_INT (this_call_site));
1564       p = get_insns ();
1565       end_sequence ();
1566
1567       emit_insn_before (p, before);
1568       last_call_site = this_call_site;
1569     }
1570 }
1571
1572 /* Construct the SjLj_Function_Context.  */
1573
1574 static void
1575 sjlj_emit_function_enter (rtx dispatch_label)
1576 {
1577   rtx fn_begin, fc, mem, seq;
1578
1579   fc = cfun->eh->sjlj_fc;
1580
1581   start_sequence ();
1582
1583   /* We're storing this libcall's address into memory instead of
1584      calling it directly.  Thus, we must call assemble_external_libcall
1585      here, as we can not depend on emit_library_call to do it for us.  */
1586   assemble_external_libcall (eh_personality_libfunc);
1587   mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
1588   emit_move_insn (mem, eh_personality_libfunc);
1589
1590   mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
1591   if (cfun->uses_eh_lsda)
1592     {
1593       char buf[20];
1594       rtx sym;
1595
1596       ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", current_function_funcdef_no);
1597       sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1598       SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_LOCAL;
1599       emit_move_insn (mem, sym);
1600     }
1601   else
1602     emit_move_insn (mem, const0_rtx);
1603
1604 #ifdef DONT_USE_BUILTIN_SETJMP
1605   {
1606     rtx x, note;
1607     x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
1608                                  TYPE_MODE (integer_type_node), 1,
1609                                  plus_constant (XEXP (fc, 0),
1610                                                 sjlj_fc_jbuf_ofs), Pmode);
1611
1612     note = emit_note (NOTE_INSN_EXPECTED_VALUE);
1613     NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, x, const0_rtx);
1614
1615     emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
1616                              TYPE_MODE (integer_type_node), 0, dispatch_label);
1617   }
1618 #else
1619   expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
1620                                dispatch_label);
1621 #endif
1622
1623   emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
1624                      1, XEXP (fc, 0), Pmode);
1625
1626   seq = get_insns ();
1627   end_sequence ();
1628
1629   /* ??? Instead of doing this at the beginning of the function,
1630      do this in a block that is at loop level 0 and dominates all
1631      can_throw_internal instructions.  */
1632
1633   for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
1634     if (NOTE_P (fn_begin)
1635         && (NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG
1636             || NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_BASIC_BLOCK))
1637       break;
1638   if (NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
1639     insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));
1640   else
1641     {
1642       rtx last = BB_END (single_succ (ENTRY_BLOCK_PTR));
1643       for (; ; fn_begin = NEXT_INSN (fn_begin))
1644         if ((NOTE_P (fn_begin)
1645              && NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
1646             || fn_begin == last)
1647           break;
1648       emit_insn_after (seq, fn_begin);
1649     }
1650 }
1651
1652 /* Call back from expand_function_end to know where we should put
1653    the call to unwind_sjlj_unregister_libfunc if needed.  */
1654
1655 void
1656 sjlj_emit_function_exit_after (rtx after)
1657 {
1658   cfun->eh->sjlj_exit_after = after;
1659 }
1660
1661 static void
1662 sjlj_emit_function_exit (void)
1663 {
1664   rtx seq;
1665   edge e;
1666   edge_iterator ei;
1667
1668   start_sequence ();
1669
1670   emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode,
1671                      1, XEXP (cfun->eh->sjlj_fc, 0), Pmode);
1672
1673   seq = get_insns ();
1674   end_sequence ();
1675
1676   /* ??? Really this can be done in any block at loop level 0 that
1677      post-dominates all can_throw_internal instructions.  This is
1678      the last possible moment.  */
1679
1680   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
1681     if (e->flags & EDGE_FALLTHRU)
1682       break;
1683   if (e)
1684     {
1685       rtx insn;
1686
1687       /* Figure out whether the place we are supposed to insert libcall
1688          is inside the last basic block or after it.  In the other case
1689          we need to emit to edge.  */
1690       gcc_assert (e->src->next_bb == EXIT_BLOCK_PTR);
1691       for (insn = BB_HEAD (e->src); ; insn = NEXT_INSN (insn))
1692         {
1693           if (insn == cfun->eh->sjlj_exit_after)
1694             {
1695               if (LABEL_P (insn))
1696                 insn = NEXT_INSN (insn);
1697               emit_insn_after (seq, insn);
1698               return;
1699             }
1700           if (insn == BB_END (e->src))
1701             break;
1702         }
1703       insert_insn_on_edge (seq, e);
1704     }
1705 }
1706
1707 static void
1708 sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info)
1709 {
1710   int i, first_reachable;
1711   rtx mem, dispatch, seq, fc;
1712   rtx before;
1713   basic_block bb;
1714   edge e;
1715
1716   fc = cfun->eh->sjlj_fc;
1717
1718   start_sequence ();
1719
1720   emit_label (dispatch_label);
1721
1722 #ifndef DONT_USE_BUILTIN_SETJMP
1723   expand_builtin_setjmp_receiver (dispatch_label);
1724 #endif
1725
1726   /* Load up dispatch index, exc_ptr and filter values from the
1727      function context.  */
1728   mem = adjust_address (fc, TYPE_MODE (integer_type_node),
1729                         sjlj_fc_call_site_ofs);
1730   dispatch = copy_to_reg (mem);
1731
1732   mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs);
1733   if (word_mode != ptr_mode)
1734     {
1735 #ifdef POINTERS_EXTEND_UNSIGNED
1736       mem = convert_memory_address (ptr_mode, mem);
1737 #else
1738       mem = convert_to_mode (ptr_mode, mem, 0);
1739 #endif
1740     }
1741   emit_move_insn (cfun->eh->exc_ptr, mem);
1742
1743   mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs + UNITS_PER_WORD);
1744   emit_move_insn (cfun->eh->filter, mem);
1745
1746   /* Jump to one of the directly reachable regions.  */
1747   /* ??? This really ought to be using a switch statement.  */
1748
1749   first_reachable = 0;
1750   for (i = cfun->eh->last_region_number; i > 0; --i)
1751     {
1752       if (! lp_info[i].directly_reachable)
1753         continue;
1754
1755       if (! first_reachable)
1756         {
1757           first_reachable = i;
1758           continue;
1759         }
1760
1761       emit_cmp_and_jump_insns (dispatch, GEN_INT (lp_info[i].dispatch_index),
1762                                EQ, NULL_RTX, TYPE_MODE (integer_type_node), 0,
1763                                cfun->eh->region_array[i]->post_landing_pad);
1764     }
1765
1766   seq = get_insns ();
1767   end_sequence ();
1768
1769   before = cfun->eh->region_array[first_reachable]->post_landing_pad;
1770
1771   bb = emit_to_new_bb_before (seq, before);
1772   e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
1773   e->count = bb->count;
1774   e->probability = REG_BR_PROB_BASE;
1775 }
1776
1777 static void
1778 sjlj_build_landing_pads (void)
1779 {
1780   struct sjlj_lp_info *lp_info;
1781
1782   lp_info = xcalloc (cfun->eh->last_region_number + 1,
1783                      sizeof (struct sjlj_lp_info));
1784
1785   if (sjlj_find_directly_reachable_regions (lp_info))
1786     {
1787       rtx dispatch_label = gen_label_rtx ();
1788
1789       cfun->eh->sjlj_fc
1790         = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
1791                               int_size_in_bytes (sjlj_fc_type_node),
1792                               TYPE_ALIGN (sjlj_fc_type_node));
1793
1794       sjlj_assign_call_site_values (dispatch_label, lp_info);
1795       sjlj_mark_call_sites (lp_info);
1796
1797       sjlj_emit_function_enter (dispatch_label);
1798       sjlj_emit_dispatch_table (dispatch_label, lp_info);
1799       sjlj_emit_function_exit ();
1800     }
1801
1802   free (lp_info);
1803 }
1804
1805 void
1806 finish_eh_generation (void)
1807 {
1808   basic_block bb;
1809
1810   /* Nothing to do if no regions created.  */
1811   if (cfun->eh->region_tree == NULL)
1812     return;
1813
1814   /* The object here is to provide find_basic_blocks with detailed
1815      information (via reachable_handlers) on how exception control
1816      flows within the function.  In this first pass, we can include
1817      type information garnered from ERT_THROW and ERT_ALLOWED_EXCEPTIONS
1818      regions, and hope that it will be useful in deleting unreachable
1819      handlers.  Subsequently, we will generate landing pads which will
1820      connect many of the handlers, and then type information will not
1821      be effective.  Still, this is a win over previous implementations.  */
1822
1823   /* These registers are used by the landing pads.  Make sure they
1824      have been generated.  */
1825   get_exception_pointer (cfun);
1826   get_exception_filter (cfun);
1827
1828   /* Construct the landing pads.  */
1829
1830   assign_filter_values ();
1831   build_post_landing_pads ();
1832   connect_post_landing_pads ();
1833   if (USING_SJLJ_EXCEPTIONS)
1834     sjlj_build_landing_pads ();
1835   else
1836     dw2_build_landing_pads ();
1837
1838   cfun->eh->built_landing_pads = 1;
1839
1840   /* We've totally changed the CFG.  Start over.  */
1841   find_exception_handler_labels ();
1842   break_superblocks ();
1843   if (USING_SJLJ_EXCEPTIONS)
1844     commit_edge_insertions ();
1845   FOR_EACH_BB (bb)
1846     {
1847       edge e;
1848       edge_iterator ei;
1849       bool eh = false;
1850       for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
1851         {
1852           if (e->flags & EDGE_EH)
1853             {
1854               remove_edge (e);
1855               eh = true;
1856             }
1857           else
1858             ei_next (&ei);
1859         }
1860       if (eh)
1861         rtl_make_eh_edge (NULL, bb, BB_END (bb));
1862     }
1863 }
1864 \f
1865 static hashval_t
1866 ehl_hash (const void *pentry)
1867 {
1868   struct ehl_map_entry *entry = (struct ehl_map_entry *) pentry;
1869
1870   /* 2^32 * ((sqrt(5) - 1) / 2) */
1871   const hashval_t scaled_golden_ratio = 0x9e3779b9;
1872   return CODE_LABEL_NUMBER (entry->label) * scaled_golden_ratio;
1873 }
1874
1875 static int
1876 ehl_eq (const void *pentry, const void *pdata)
1877 {
1878   struct ehl_map_entry *entry = (struct ehl_map_entry *) pentry;
1879   struct ehl_map_entry *data = (struct ehl_map_entry *) pdata;
1880
1881   return entry->label == data->label;
1882 }
1883
1884 /* This section handles removing dead code for flow.  */
1885
1886 /* Remove LABEL from exception_handler_label_map.  */
1887
1888 static void
1889 remove_exception_handler_label (rtx label)
1890 {
1891   struct ehl_map_entry **slot, tmp;
1892
1893   /* If exception_handler_label_map was not built yet,
1894      there is nothing to do.  */
1895   if (cfun->eh->exception_handler_label_map == NULL)
1896     return;
1897
1898   tmp.label = label;
1899   slot = (struct ehl_map_entry **)
1900     htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT);
1901   gcc_assert (slot);
1902
1903   htab_clear_slot (cfun->eh->exception_handler_label_map, (void **) slot);
1904 }
1905
1906 /* Splice REGION from the region tree etc.  */
1907
1908 static void
1909 remove_eh_handler (struct eh_region *region)
1910 {
1911   struct eh_region **pp, **pp_start, *p, *outer, *inner;
1912   rtx lab;
1913
1914   /* For the benefit of efficiently handling REG_EH_REGION notes,
1915      replace this region in the region array with its containing
1916      region.  Note that previous region deletions may result in
1917      multiple copies of this region in the array, so we have a
1918      list of alternate numbers by which we are known.  */
1919
1920   outer = region->outer;
1921   cfun->eh->region_array[region->region_number] = outer;
1922   if (region->aka)
1923     {
1924       unsigned i;
1925       bitmap_iterator bi;
1926
1927       EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i, bi)
1928         {
1929           cfun->eh->region_array[i] = outer;
1930         }
1931     }
1932
1933   if (outer)
1934     {
1935       if (!outer->aka)
1936         outer->aka = BITMAP_GGC_ALLOC ();
1937       if (region->aka)
1938         bitmap_ior_into (outer->aka, region->aka);
1939       bitmap_set_bit (outer->aka, region->region_number);
1940     }
1941
1942   if (cfun->eh->built_landing_pads)
1943     lab = region->landing_pad;
1944   else
1945     lab = region->label;
1946   if (lab)
1947     remove_exception_handler_label (lab);
1948
1949   if (outer)
1950     pp_start = &outer->inner;
1951   else
1952     pp_start = &cfun->eh->region_tree;
1953   for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp)
1954     continue;
1955   *pp = region->next_peer;
1956
1957   inner = region->inner;
1958   if (inner)
1959     {
1960       for (p = inner; p->next_peer ; p = p->next_peer)
1961         p->outer = outer;
1962       p->outer = outer;
1963
1964       p->next_peer = *pp_start;
1965       *pp_start = inner;
1966     }
1967
1968   if (region->type == ERT_CATCH)
1969     {
1970       struct eh_region *try, *next, *prev;
1971
1972       for (try = region->next_peer;
1973            try->type == ERT_CATCH;
1974            try = try->next_peer)
1975         continue;
1976       gcc_assert (try->type == ERT_TRY);
1977
1978       next = region->u.catch.next_catch;
1979       prev = region->u.catch.prev_catch;
1980
1981       if (next)
1982         next->u.catch.prev_catch = prev;
1983       else
1984         try->u.try.last_catch = prev;
1985       if (prev)
1986         prev->u.catch.next_catch = next;
1987       else
1988         {
1989           try->u.try.catch = next;
1990           if (! next)
1991             remove_eh_handler (try);
1992         }
1993     }
1994 }
1995
1996 /* LABEL heads a basic block that is about to be deleted.  If this
1997    label corresponds to an exception region, we may be able to
1998    delete the region.  */
1999
2000 void
2001 maybe_remove_eh_handler (rtx label)
2002 {
2003   struct ehl_map_entry **slot, tmp;
2004   struct eh_region *region;
2005
2006   /* ??? After generating landing pads, it's not so simple to determine
2007      if the region data is completely unused.  One must examine the
2008      landing pad and the post landing pad, and whether an inner try block
2009      is referencing the catch handlers directly.  */
2010   if (cfun->eh->built_landing_pads)
2011     return;
2012
2013   tmp.label = label;
2014   slot = (struct ehl_map_entry **)
2015     htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT);
2016   if (! slot)
2017     return;
2018   region = (*slot)->region;
2019   if (! region)
2020     return;
2021
2022   /* Flow will want to remove MUST_NOT_THROW regions as unreachable
2023      because there is no path to the fallback call to terminate.
2024      But the region continues to affect call-site data until there
2025      are no more contained calls, which we don't see here.  */
2026   if (region->type == ERT_MUST_NOT_THROW)
2027     {
2028       htab_clear_slot (cfun->eh->exception_handler_label_map, (void **) slot);
2029       region->label = NULL_RTX;
2030     }
2031   else
2032     remove_eh_handler (region);
2033 }
2034
2035 /* Invokes CALLBACK for every exception handler label.  Only used by old
2036    loop hackery; should not be used by new code.  */
2037
2038 void
2039 for_each_eh_label (void (*callback) (rtx))
2040 {
2041   htab_traverse (cfun->eh->exception_handler_label_map, for_each_eh_label_1,
2042                  (void *) &callback);
2043 }
2044
2045 static int
2046 for_each_eh_label_1 (void **pentry, void *data)
2047 {
2048   struct ehl_map_entry *entry = *(struct ehl_map_entry **)pentry;
2049   void (*callback) (rtx) = *(void (**) (rtx)) data;
2050
2051   (*callback) (entry->label);
2052   return 1;
2053 }
2054
2055 /* Invoke CALLBACK for every exception region in the current function.  */
2056
2057 void
2058 for_each_eh_region (void (*callback) (struct eh_region *))
2059 {
2060   int i, n = cfun->eh->last_region_number;
2061   for (i = 1; i <= n; ++i)
2062     {
2063       struct eh_region *region = cfun->eh->region_array[i];
2064       if (region)
2065         (*callback) (region);
2066     }
2067 }
2068 \f
2069 /* This section describes CFG exception edges for flow.  */
2070
2071 /* For communicating between calls to reachable_next_level.  */
2072 struct reachable_info
2073 {
2074   tree types_caught;
2075   tree types_allowed;
2076   void (*callback) (struct eh_region *, void *);
2077   void *callback_data;
2078   bool saw_any_handlers;
2079 };
2080
2081 /* A subroutine of reachable_next_level.  Return true if TYPE, or a
2082    base class of TYPE, is in HANDLED.  */
2083
2084 static int
2085 check_handled (tree handled, tree type)
2086 {
2087   tree t;
2088
2089   /* We can check for exact matches without front-end help.  */
2090   if (! lang_eh_type_covers)
2091     {
2092       for (t = handled; t ; t = TREE_CHAIN (t))
2093         if (TREE_VALUE (t) == type)
2094           return 1;
2095     }
2096   else
2097     {
2098       for (t = handled; t ; t = TREE_CHAIN (t))
2099         if ((*lang_eh_type_covers) (TREE_VALUE (t), type))
2100           return 1;
2101     }
2102
2103   return 0;
2104 }
2105
2106 /* A subroutine of reachable_next_level.  If we are collecting a list
2107    of handlers, add one.  After landing pad generation, reference
2108    it instead of the handlers themselves.  Further, the handlers are
2109    all wired together, so by referencing one, we've got them all.
2110    Before landing pad generation we reference each handler individually.
2111
2112    LP_REGION contains the landing pad; REGION is the handler.  */
2113
2114 static void
2115 add_reachable_handler (struct reachable_info *info,
2116                        struct eh_region *lp_region, struct eh_region *region)
2117 {
2118   if (! info)
2119     return;
2120
2121   info->saw_any_handlers = true;
2122
2123   if (cfun->eh->built_landing_pads)
2124     info->callback (lp_region, info->callback_data);
2125   else
2126     info->callback (region, info->callback_data);
2127 }
2128
2129 /* Process one level of exception regions for reachability.
2130    If TYPE_THROWN is non-null, then it is the *exact* type being
2131    propagated.  If INFO is non-null, then collect handler labels
2132    and caught/allowed type information between invocations.  */
2133
2134 static enum reachable_code
2135 reachable_next_level (struct eh_region *region, tree type_thrown,
2136                       struct reachable_info *info)
2137 {
2138   switch (region->type)
2139     {
2140     case ERT_CLEANUP:
2141       /* Before landing-pad generation, we model control flow
2142          directly to the individual handlers.  In this way we can
2143          see that catch handler types may shadow one another.  */
2144       add_reachable_handler (info, region, region);
2145       return RNL_MAYBE_CAUGHT;
2146
2147     case ERT_TRY:
2148       {
2149         struct eh_region *c;
2150         enum reachable_code ret = RNL_NOT_CAUGHT;
2151
2152         for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
2153           {
2154             /* A catch-all handler ends the search.  */
2155             if (c->u.catch.type_list == NULL)
2156               {
2157                 add_reachable_handler (info, region, c);
2158                 return RNL_CAUGHT;
2159               }
2160
2161             if (type_thrown)
2162               {
2163                 /* If we have at least one type match, end the search.  */
2164                 tree tp_node = c->u.catch.type_list;
2165
2166                 for (; tp_node; tp_node = TREE_CHAIN (tp_node))
2167                   {
2168                     tree type = TREE_VALUE (tp_node);
2169
2170                     if (type == type_thrown
2171                         || (lang_eh_type_covers
2172                             && (*lang_eh_type_covers) (type, type_thrown)))
2173                       {
2174                         add_reachable_handler (info, region, c);
2175                         return RNL_CAUGHT;
2176                       }
2177                   }
2178
2179                 /* If we have definitive information of a match failure,
2180                    the catch won't trigger.  */
2181                 if (lang_eh_type_covers)
2182                   return RNL_NOT_CAUGHT;
2183               }
2184
2185             /* At this point, we either don't know what type is thrown or
2186                don't have front-end assistance to help deciding if it is
2187                covered by one of the types in the list for this region.
2188
2189                We'd then like to add this region to the list of reachable
2190                handlers since it is indeed potentially reachable based on the
2191                information we have.
2192
2193                Actually, this handler is for sure not reachable if all the
2194                types it matches have already been caught. That is, it is only
2195                potentially reachable if at least one of the types it catches
2196                has not been previously caught.  */
2197
2198             if (! info)
2199               ret = RNL_MAYBE_CAUGHT;
2200             else
2201               {
2202                 tree tp_node = c->u.catch.type_list;
2203                 bool maybe_reachable = false;
2204
2205                 /* Compute the potential reachability of this handler and
2206                    update the list of types caught at the same time.  */
2207                 for (; tp_node; tp_node = TREE_CHAIN (tp_node))
2208                   {
2209                     tree type = TREE_VALUE (tp_node);
2210
2211                     if (! check_handled (info->types_caught, type))
2212                       {
2213                         info->types_caught
2214                           = tree_cons (NULL, type, info->types_caught);
2215
2216                         maybe_reachable = true;
2217                       }
2218                   }
2219
2220                 if (maybe_reachable)
2221                   {
2222                     add_reachable_handler (info, region, c);
2223
2224                     /* ??? If the catch type is a base class of every allowed
2225                        type, then we know we can stop the search.  */
2226                     ret = RNL_MAYBE_CAUGHT;
2227                   }
2228               }
2229           }
2230
2231         return ret;
2232       }
2233
2234     case ERT_ALLOWED_EXCEPTIONS:
2235       /* An empty list of types definitely ends the search.  */
2236       if (region->u.allowed.type_list == NULL_TREE)
2237         {
2238           add_reachable_handler (info, region, region);
2239           return RNL_CAUGHT;
2240         }
2241
2242       /* Collect a list of lists of allowed types for use in detecting
2243          when a catch may be transformed into a catch-all.  */
2244       if (info)
2245         info->types_allowed = tree_cons (NULL_TREE,
2246                                          region->u.allowed.type_list,
2247                                          info->types_allowed);
2248
2249       /* If we have definitive information about the type hierarchy,
2250          then we can tell if the thrown type will pass through the
2251          filter.  */
2252       if (type_thrown && lang_eh_type_covers)
2253         {
2254           if (check_handled (region->u.allowed.type_list, type_thrown))
2255             return RNL_NOT_CAUGHT;
2256           else
2257             {
2258               add_reachable_handler (info, region, region);
2259               return RNL_CAUGHT;
2260             }
2261         }
2262
2263       add_reachable_handler (info, region, region);
2264       return RNL_MAYBE_CAUGHT;
2265
2266     case ERT_CATCH:
2267       /* Catch regions are handled by their controlling try region.  */
2268       return RNL_NOT_CAUGHT;
2269
2270     case ERT_MUST_NOT_THROW:
2271       /* Here we end our search, since no exceptions may propagate.
2272          If we've touched down at some landing pad previous, then the
2273          explicit function call we generated may be used.  Otherwise
2274          the call is made by the runtime.  */
2275       if (info && info->saw_any_handlers)
2276         {
2277           add_reachable_handler (info, region, region);
2278           return RNL_CAUGHT;
2279         }
2280       else
2281         return RNL_BLOCKED;
2282
2283     case ERT_THROW:
2284     case ERT_FIXUP:
2285     case ERT_UNKNOWN:
2286       /* Shouldn't see these here.  */
2287       gcc_unreachable ();
2288       break;
2289     default:
2290       gcc_unreachable ();
2291     }
2292 }
2293
2294 /* Invoke CALLBACK on each region reachable from REGION_NUMBER.  */
2295
2296 void
2297 foreach_reachable_handler (int region_number, bool is_resx,
2298                            void (*callback) (struct eh_region *, void *),
2299                            void *callback_data)
2300 {
2301   struct reachable_info info;
2302   struct eh_region *region;
2303   tree type_thrown;
2304
2305   memset (&info, 0, sizeof (info));
2306   info.callback = callback;
2307   info.callback_data = callback_data;
2308
2309   region = cfun->eh->region_array[region_number];
2310
2311   type_thrown = NULL_TREE;
2312   if (is_resx)
2313     {
2314       /* A RESX leaves a region instead of entering it.  Thus the
2315          region itself may have been deleted out from under us.  */
2316       if (region == NULL)
2317         return;
2318       region = region->outer;
2319     }
2320   else if (region->type == ERT_THROW)
2321     {
2322       type_thrown = region->u.throw.type;
2323       region = region->outer;
2324     }
2325
2326   while (region)
2327     {
2328       if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT)
2329         break;
2330       /* If we have processed one cleanup, there is no point in
2331          processing any more of them.  Each cleanup will have an edge
2332          to the next outer cleanup region, so the flow graph will be
2333          accurate.  */
2334       if (region->type == ERT_CLEANUP)
2335         region = region->u.cleanup.prev_try;
2336       else
2337         region = region->outer;
2338     }
2339 }
2340
2341 /* Retrieve a list of labels of exception handlers which can be
2342    reached by a given insn.  */
2343
2344 static void
2345 arh_to_landing_pad (struct eh_region *region, void *data)
2346 {
2347   rtx *p_handlers = data;
2348   if (! *p_handlers)
2349     *p_handlers = alloc_INSN_LIST (region->landing_pad, NULL_RTX);
2350 }
2351
2352 static void
2353 arh_to_label (struct eh_region *region, void *data)
2354 {
2355   rtx *p_handlers = data;
2356   *p_handlers = alloc_INSN_LIST (region->label, *p_handlers);
2357 }
2358
2359 rtx
2360 reachable_handlers (rtx insn)
2361 {
2362   bool is_resx = false;
2363   rtx handlers = NULL;
2364   int region_number;
2365
2366   if (JUMP_P (insn)
2367       && GET_CODE (PATTERN (insn)) == RESX)
2368     {
2369       region_number = XINT (PATTERN (insn), 0);
2370       is_resx = true;
2371     }
2372   else
2373     {
2374       rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2375       if (!note || INTVAL (XEXP (note, 0)) <= 0)
2376         return NULL;
2377       region_number = INTVAL (XEXP (note, 0));
2378     }
2379
2380   foreach_reachable_handler (region_number, is_resx,
2381                              (cfun->eh->built_landing_pads
2382                               ? arh_to_landing_pad
2383                               : arh_to_label),
2384                              &handlers);
2385
2386   return handlers;
2387 }
2388
2389 /* Determine if the given INSN can throw an exception that is caught
2390    within the function.  */
2391
2392 bool
2393 can_throw_internal_1 (int region_number)
2394 {
2395   struct eh_region *region;
2396   tree type_thrown;
2397
2398   region = cfun->eh->region_array[region_number];
2399
2400   type_thrown = NULL_TREE;
2401   if (region->type == ERT_THROW)
2402     {
2403       type_thrown = region->u.throw.type;
2404       region = region->outer;
2405     }
2406
2407   /* If this exception is ignored by each and every containing region,
2408      then control passes straight out.  The runtime may handle some
2409      regions, which also do not require processing internally.  */
2410   for (; region; region = region->outer)
2411     {
2412       enum reachable_code how = reachable_next_level (region, type_thrown, 0);
2413       if (how == RNL_BLOCKED)
2414         return false;
2415       if (how != RNL_NOT_CAUGHT)
2416         return true;
2417     }
2418
2419   return false;
2420 }
2421
2422 bool
2423 can_throw_internal (rtx insn)
2424 {
2425   rtx note;
2426
2427   if (! INSN_P (insn))
2428     return false;
2429
2430   if (JUMP_P (insn)
2431       && GET_CODE (PATTERN (insn)) == RESX
2432       && XINT (PATTERN (insn), 0) > 0)
2433     return can_throw_internal_1 (XINT (PATTERN (insn), 0));
2434
2435   if (NONJUMP_INSN_P (insn)
2436       && GET_CODE (PATTERN (insn)) == SEQUENCE)
2437     insn = XVECEXP (PATTERN (insn), 0, 0);
2438
2439   /* Every insn that might throw has an EH_REGION note.  */
2440   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2441   if (!note || INTVAL (XEXP (note, 0)) <= 0)
2442     return false;
2443
2444   return can_throw_internal_1 (INTVAL (XEXP (note, 0)));
2445 }
2446
2447 /* Determine if the given INSN can throw an exception that is
2448    visible outside the function.  */
2449
2450 bool
2451 can_throw_external_1 (int region_number)
2452 {
2453   struct eh_region *region;
2454   tree type_thrown;
2455
2456   region = cfun->eh->region_array[region_number];
2457
2458   type_thrown = NULL_TREE;
2459   if (region->type == ERT_THROW)
2460     {
2461       type_thrown = region->u.throw.type;
2462       region = region->outer;
2463     }
2464
2465   /* If the exception is caught or blocked by any containing region,
2466      then it is not seen by any calling function.  */
2467   for (; region ; region = region->outer)
2468     if (reachable_next_level (region, type_thrown, NULL) >= RNL_CAUGHT)
2469       return false;
2470
2471   return true;
2472 }
2473
2474 bool
2475 can_throw_external (rtx insn)
2476 {
2477   rtx note;
2478
2479   if (! INSN_P (insn))
2480     return false;
2481
2482   if (NONJUMP_INSN_P (insn)
2483       && GET_CODE (PATTERN (insn)) == SEQUENCE)
2484     insn = XVECEXP (PATTERN (insn), 0, 0);
2485
2486   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2487   if (!note)
2488     {
2489       /* Calls (and trapping insns) without notes are outside any
2490          exception handling region in this function.  We have to
2491          assume it might throw.  Given that the front end and middle
2492          ends mark known NOTHROW functions, this isn't so wildly
2493          inaccurate.  */
2494       return (CALL_P (insn)
2495               || (flag_non_call_exceptions
2496                   && may_trap_p (PATTERN (insn))));
2497     }
2498   if (INTVAL (XEXP (note, 0)) <= 0)
2499     return false;
2500
2501   return can_throw_external_1 (INTVAL (XEXP (note, 0)));
2502 }
2503
2504 /* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls.  */
2505
2506 void
2507 set_nothrow_function_flags (void)
2508 {
2509   rtx insn;
2510
2511   TREE_NOTHROW (current_function_decl) = 1;
2512
2513   /* Assume cfun->all_throwers_are_sibcalls until we encounter
2514      something that can throw an exception.  We specifically exempt
2515      CALL_INSNs that are SIBLING_CALL_P, as these are really jumps,
2516      and can't throw.  Most CALL_INSNs are not SIBLING_CALL_P, so this
2517      is optimistic.  */
2518
2519   cfun->all_throwers_are_sibcalls = 1;
2520
2521   if (! flag_exceptions)
2522     return;
2523
2524   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2525     if (can_throw_external (insn))
2526       {
2527         TREE_NOTHROW (current_function_decl) = 0;
2528
2529         if (!CALL_P (insn) || !SIBLING_CALL_P (insn))
2530           {
2531             cfun->all_throwers_are_sibcalls = 0;
2532             return;
2533           }
2534       }
2535
2536   for (insn = current_function_epilogue_delay_list; insn;
2537        insn = XEXP (insn, 1))
2538     if (can_throw_external (insn))
2539       {
2540         TREE_NOTHROW (current_function_decl) = 0;
2541
2542         if (!CALL_P (insn) || !SIBLING_CALL_P (insn))
2543           {
2544             cfun->all_throwers_are_sibcalls = 0;
2545             return;
2546           }
2547       }
2548 }
2549
2550 \f
2551 /* Various hooks for unwind library.  */
2552
2553 /* Do any necessary initialization to access arbitrary stack frames.
2554    On the SPARC, this means flushing the register windows.  */
2555
2556 void
2557 expand_builtin_unwind_init (void)
2558 {
2559   /* Set this so all the registers get saved in our frame; we need to be
2560      able to copy the saved values for any registers from frames we unwind.  */
2561   current_function_has_nonlocal_label = 1;
2562
2563 #ifdef SETUP_FRAME_ADDRESSES
2564   SETUP_FRAME_ADDRESSES ();
2565 #endif
2566 }
2567
2568 rtx
2569 expand_builtin_eh_return_data_regno (tree arglist)
2570 {
2571   tree which = TREE_VALUE (arglist);
2572   unsigned HOST_WIDE_INT iwhich;
2573
2574   if (TREE_CODE (which) != INTEGER_CST)
2575     {
2576       error ("argument of %<__builtin_eh_return_regno%> must be constant");
2577       return constm1_rtx;
2578     }
2579
2580   iwhich = tree_low_cst (which, 1);
2581   iwhich = EH_RETURN_DATA_REGNO (iwhich);
2582   if (iwhich == INVALID_REGNUM)
2583     return constm1_rtx;
2584
2585 #ifdef DWARF_FRAME_REGNUM
2586   iwhich = DWARF_FRAME_REGNUM (iwhich);
2587 #else
2588   iwhich = DBX_REGISTER_NUMBER (iwhich);
2589 #endif
2590
2591   return GEN_INT (iwhich);
2592 }
2593
2594 /* Given a value extracted from the return address register or stack slot,
2595    return the actual address encoded in that value.  */
2596
2597 rtx
2598 expand_builtin_extract_return_addr (tree addr_tree)
2599 {
2600   rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
2601
2602   if (GET_MODE (addr) != Pmode
2603       && GET_MODE (addr) != VOIDmode)
2604     {
2605 #ifdef POINTERS_EXTEND_UNSIGNED
2606       addr = convert_memory_address (Pmode, addr);
2607 #else
2608       addr = convert_to_mode (Pmode, addr, 0);
2609 #endif
2610     }
2611
2612   /* First mask out any unwanted bits.  */
2613 #ifdef MASK_RETURN_ADDR
2614   expand_and (Pmode, addr, MASK_RETURN_ADDR, addr);
2615 #endif
2616
2617   /* Then adjust to find the real return address.  */
2618 #if defined (RETURN_ADDR_OFFSET)
2619   addr = plus_constant (addr, RETURN_ADDR_OFFSET);
2620 #endif
2621
2622   return addr;
2623 }
2624
2625 /* Given an actual address in addr_tree, do any necessary encoding
2626    and return the value to be stored in the return address register or
2627    stack slot so the epilogue will return to that address.  */
2628
2629 rtx
2630 expand_builtin_frob_return_addr (tree addr_tree)
2631 {
2632   rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, 0);
2633
2634   addr = convert_memory_address (Pmode, addr);
2635
2636 #ifdef RETURN_ADDR_OFFSET
2637   addr = force_reg (Pmode, addr);
2638   addr = plus_constant (addr, -RETURN_ADDR_OFFSET);
2639 #endif
2640
2641   return addr;
2642 }
2643
2644 /* Set up the epilogue with the magic bits we'll need to return to the
2645    exception handler.  */
2646
2647 void
2648 expand_builtin_eh_return (tree stackadj_tree ATTRIBUTE_UNUSED,
2649                           tree handler_tree)
2650 {
2651   rtx tmp;
2652
2653 #ifdef EH_RETURN_STACKADJ_RTX
2654   tmp = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0);
2655   tmp = convert_memory_address (Pmode, tmp);
2656   if (!cfun->eh->ehr_stackadj)
2657     cfun->eh->ehr_stackadj = copy_to_reg (tmp);
2658   else if (tmp != cfun->eh->ehr_stackadj)
2659     emit_move_insn (cfun->eh->ehr_stackadj, tmp);
2660 #endif
2661
2662   tmp = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0);
2663   tmp = convert_memory_address (Pmode, tmp);
2664   if (!cfun->eh->ehr_handler)
2665     cfun->eh->ehr_handler = copy_to_reg (tmp);
2666   else if (tmp != cfun->eh->ehr_handler)
2667     emit_move_insn (cfun->eh->ehr_handler, tmp);
2668
2669   if (!cfun->eh->ehr_label)
2670     cfun->eh->ehr_label = gen_label_rtx ();
2671   emit_jump (cfun->eh->ehr_label);
2672 }
2673
2674 void
2675 expand_eh_return (void)
2676 {
2677   rtx around_label;
2678
2679   if (! cfun->eh->ehr_label)
2680     return;
2681
2682   current_function_calls_eh_return = 1;
2683
2684 #ifdef EH_RETURN_STACKADJ_RTX
2685   emit_move_insn (EH_RETURN_STACKADJ_RTX, const0_rtx);
2686 #endif
2687
2688   around_label = gen_label_rtx ();
2689   emit_jump (around_label);
2690
2691   emit_label (cfun->eh->ehr_label);
2692   clobber_return_register ();
2693
2694 #ifdef EH_RETURN_STACKADJ_RTX
2695   emit_move_insn (EH_RETURN_STACKADJ_RTX, cfun->eh->ehr_stackadj);
2696 #endif
2697
2698 #ifdef HAVE_eh_return
2699   if (HAVE_eh_return)
2700     emit_insn (gen_eh_return (cfun->eh->ehr_handler));
2701   else
2702 #endif
2703     {
2704 #ifdef EH_RETURN_HANDLER_RTX
2705       emit_move_insn (EH_RETURN_HANDLER_RTX, cfun->eh->ehr_handler);
2706 #else
2707       error ("__builtin_eh_return not supported on this target");
2708 #endif
2709     }
2710
2711   emit_label (around_label);
2712 }
2713
2714 /* Convert a ptr_mode address ADDR_TREE to a Pmode address controlled by
2715    POINTERS_EXTEND_UNSIGNED and return it.  */
2716
2717 rtx
2718 expand_builtin_extend_pointer (tree addr_tree)
2719 {
2720   rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, 0);
2721   int extend;
2722
2723 #ifdef POINTERS_EXTEND_UNSIGNED
2724   extend = POINTERS_EXTEND_UNSIGNED;
2725 #else
2726   /* The previous EH code did an unsigned extend by default, so we do this also
2727      for consistency.  */
2728   extend = 1;
2729 #endif
2730
2731   return convert_modes (word_mode, ptr_mode, addr, extend);
2732 }
2733 \f
2734 /* In the following functions, we represent entries in the action table
2735    as 1-based indices.  Special cases are:
2736
2737          0:     null action record, non-null landing pad; implies cleanups
2738         -1:     null action record, null landing pad; implies no action
2739         -2:     no call-site entry; implies must_not_throw
2740         -3:     we have yet to process outer regions
2741
2742    Further, no special cases apply to the "next" field of the record.
2743    For next, 0 means end of list.  */
2744
2745 struct action_record
2746 {
2747   int offset;
2748   int filter;
2749   int next;
2750 };
2751
2752 static int
2753 action_record_eq (const void *pentry, const void *pdata)
2754 {
2755   const struct action_record *entry = (const struct action_record *) pentry;
2756   const struct action_record *data = (const struct action_record *) pdata;
2757   return entry->filter == data->filter && entry->next == data->next;
2758 }
2759
2760 static hashval_t
2761 action_record_hash (const void *pentry)
2762 {
2763   const struct action_record *entry = (const struct action_record *) pentry;
2764   return entry->next * 1009 + entry->filter;
2765 }
2766
2767 static int
2768 add_action_record (htab_t ar_hash, int filter, int next)
2769 {
2770   struct action_record **slot, *new, tmp;
2771
2772   tmp.filter = filter;
2773   tmp.next = next;
2774   slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT);
2775
2776   if ((new = *slot) == NULL)
2777     {
2778       new = xmalloc (sizeof (*new));
2779       new->offset = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
2780       new->filter = filter;
2781       new->next = next;
2782       *slot = new;
2783
2784       /* The filter value goes in untouched.  The link to the next
2785          record is a "self-relative" byte offset, or zero to indicate
2786          that there is no next record.  So convert the absolute 1 based
2787          indices we've been carrying around into a displacement.  */
2788
2789       push_sleb128 (&cfun->eh->action_record_data, filter);
2790       if (next)
2791         next -= VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
2792       push_sleb128 (&cfun->eh->action_record_data, next);
2793     }
2794
2795   return new->offset;
2796 }
2797
2798 static int
2799 collect_one_action_chain (htab_t ar_hash, struct eh_region *region)
2800 {
2801   struct eh_region *c;
2802   int next;
2803
2804   /* If we've reached the top of the region chain, then we have
2805      no actions, and require no landing pad.  */
2806   if (region == NULL)
2807     return -1;
2808
2809   switch (region->type)
2810     {
2811     case ERT_CLEANUP:
2812       /* A cleanup adds a zero filter to the beginning of the chain, but
2813          there are special cases to look out for.  If there are *only*
2814          cleanups along a path, then it compresses to a zero action.
2815          Further, if there are multiple cleanups along a path, we only
2816          need to represent one of them, as that is enough to trigger
2817          entry to the landing pad at runtime.  */
2818       next = collect_one_action_chain (ar_hash, region->outer);
2819       if (next <= 0)
2820         return 0;
2821       for (c = region->outer; c ; c = c->outer)
2822         if (c->type == ERT_CLEANUP)
2823           return next;
2824       return add_action_record (ar_hash, 0, next);
2825
2826     case ERT_TRY:
2827       /* Process the associated catch regions in reverse order.
2828          If there's a catch-all handler, then we don't need to
2829          search outer regions.  Use a magic -3 value to record
2830          that we haven't done the outer search.  */
2831       next = -3;
2832       for (c = region->u.try.last_catch; c ; c = c->u.catch.prev_catch)
2833         {
2834           if (c->u.catch.type_list == NULL)
2835             {
2836               /* Retrieve the filter from the head of the filter list
2837                  where we have stored it (see assign_filter_values).  */
2838               int filter
2839                 = TREE_INT_CST_LOW (TREE_VALUE (c->u.catch.filter_list));
2840
2841               next = add_action_record (ar_hash, filter, 0);
2842             }
2843           else
2844             {
2845               /* Once the outer search is done, trigger an action record for
2846                  each filter we have.  */
2847               tree flt_node;
2848
2849               if (next == -3)
2850                 {
2851                   next = collect_one_action_chain (ar_hash, region->outer);
2852
2853                   /* If there is no next action, terminate the chain.  */
2854                   if (next == -1)
2855                     next = 0;
2856                   /* If all outer actions are cleanups or must_not_throw,
2857                      we'll have no action record for it, since we had wanted
2858                      to encode these states in the call-site record directly.
2859                      Add a cleanup action to the chain to catch these.  */
2860                   else if (next <= 0)
2861                     next = add_action_record (ar_hash, 0, 0);
2862                 }
2863
2864               flt_node = c->u.catch.filter_list;
2865               for (; flt_node; flt_node = TREE_CHAIN (flt_node))
2866                 {
2867                   int filter = TREE_INT_CST_LOW (TREE_VALUE (flt_node));
2868                   next = add_action_record (ar_hash, filter, next);
2869                 }
2870             }
2871         }
2872       return next;
2873
2874     case ERT_ALLOWED_EXCEPTIONS:
2875       /* An exception specification adds its filter to the
2876          beginning of the chain.  */
2877       next = collect_one_action_chain (ar_hash, region->outer);
2878
2879       /* If there is no next action, terminate the chain.  */
2880       if (next == -1)
2881         next = 0;
2882       /* If all outer actions are cleanups or must_not_throw,
2883          we'll have no action record for it, since we had wanted
2884          to encode these states in the call-site record directly.
2885          Add a cleanup action to the chain to catch these.  */
2886       else if (next <= 0)
2887         next = add_action_record (ar_hash, 0, 0);
2888       
2889       return add_action_record (ar_hash, region->u.allowed.filter, next);
2890
2891     case ERT_MUST_NOT_THROW:
2892       /* A must-not-throw region with no inner handlers or cleanups
2893          requires no call-site entry.  Note that this differs from
2894          the no handler or cleanup case in that we do require an lsda
2895          to be generated.  Return a magic -2 value to record this.  */
2896       return -2;
2897
2898     case ERT_CATCH:
2899     case ERT_THROW:
2900       /* CATCH regions are handled in TRY above.  THROW regions are
2901          for optimization information only and produce no output.  */
2902       return collect_one_action_chain (ar_hash, region->outer);
2903
2904     default:
2905       gcc_unreachable ();
2906     }
2907 }
2908
2909 static int
2910 add_call_site (rtx landing_pad, int action)
2911 {
2912   struct call_site_record *data = cfun->eh->call_site_data;
2913   int used = cfun->eh->call_site_data_used;
2914   int size = cfun->eh->call_site_data_size;
2915
2916   if (used >= size)
2917     {
2918       size = (size ? size * 2 : 64);
2919       data = ggc_realloc (data, sizeof (*data) * size);
2920       cfun->eh->call_site_data = data;
2921       cfun->eh->call_site_data_size = size;
2922     }
2923
2924   data[used].landing_pad = landing_pad;
2925   data[used].action = action;
2926
2927   cfun->eh->call_site_data_used = used + 1;
2928
2929   return used + call_site_base;
2930 }
2931
2932 /* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
2933    The new note numbers will not refer to region numbers, but
2934    instead to call site entries.  */
2935
2936 void
2937 convert_to_eh_region_ranges (void)
2938 {
2939   rtx insn, iter, note;
2940   htab_t ar_hash;
2941   int last_action = -3;
2942   rtx last_action_insn = NULL_RTX;
2943   rtx last_landing_pad = NULL_RTX;
2944   rtx first_no_action_insn = NULL_RTX;
2945   int call_site = 0;
2946
2947   if (USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL)
2948     return;
2949
2950   VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
2951
2952   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
2953
2954   for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
2955     if (INSN_P (iter))
2956       {
2957         struct eh_region *region;
2958         int this_action;
2959         rtx this_landing_pad;
2960
2961         insn = iter;
2962         if (NONJUMP_INSN_P (insn)
2963             && GET_CODE (PATTERN (insn)) == SEQUENCE)
2964           insn = XVECEXP (PATTERN (insn), 0, 0);
2965
2966         note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2967         if (!note)
2968           {
2969             if (! (CALL_P (insn)
2970                    || (flag_non_call_exceptions
2971                        && may_trap_p (PATTERN (insn)))))
2972               continue;
2973             this_action = -1;
2974             region = NULL;
2975           }
2976         else
2977           {
2978             if (INTVAL (XEXP (note, 0)) <= 0)
2979               continue;
2980             region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2981             this_action = collect_one_action_chain (ar_hash, region);
2982           }
2983
2984         /* Existence of catch handlers, or must-not-throw regions
2985            implies that an lsda is needed (even if empty).  */
2986         if (this_action != -1)
2987           cfun->uses_eh_lsda = 1;
2988
2989         /* Delay creation of region notes for no-action regions
2990            until we're sure that an lsda will be required.  */
2991         else if (last_action == -3)
2992           {
2993             first_no_action_insn = iter;
2994             last_action = -1;
2995           }
2996
2997         /* Cleanups and handlers may share action chains but not
2998            landing pads.  Collect the landing pad for this region.  */
2999         if (this_action >= 0)
3000           {
3001             struct eh_region *o;
3002             for (o = region; ! o->landing_pad ; o = o->outer)
3003               continue;
3004             this_landing_pad = o->landing_pad;
3005           }
3006         else
3007           this_landing_pad = NULL_RTX;
3008
3009         /* Differing actions or landing pads implies a change in call-site
3010            info, which implies some EH_REGION note should be emitted.  */
3011         if (last_action != this_action
3012             || last_landing_pad != this_landing_pad)
3013           {
3014             /* If we'd not seen a previous action (-3) or the previous
3015                action was must-not-throw (-2), then we do not need an
3016                end note.  */
3017             if (last_action >= -1)
3018               {
3019                 /* If we delayed the creation of the begin, do it now.  */
3020                 if (first_no_action_insn)
3021                   {
3022                     call_site = add_call_site (NULL_RTX, 0);
3023                     note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
3024                                              first_no_action_insn);
3025                     NOTE_EH_HANDLER (note) = call_site;
3026                     first_no_action_insn = NULL_RTX;
3027                   }
3028
3029                 note = emit_note_after (NOTE_INSN_EH_REGION_END,
3030                                         last_action_insn);
3031                 NOTE_EH_HANDLER (note) = call_site;
3032               }
3033
3034             /* If the new action is must-not-throw, then no region notes
3035                are created.  */
3036             if (this_action >= -1)
3037               {
3038                 call_site = add_call_site (this_landing_pad,
3039                                            this_action < 0 ? 0 : this_action);
3040                 note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter);
3041                 NOTE_EH_HANDLER (note) = call_site;
3042               }
3043
3044             last_action = this_action;
3045             last_landing_pad = this_landing_pad;
3046           }
3047         last_action_insn = iter;
3048       }
3049
3050   if (last_action >= -1 && ! first_no_action_insn)
3051     {
3052       note = emit_note_after (NOTE_INSN_EH_REGION_END, last_action_insn);
3053       NOTE_EH_HANDLER (note) = call_site;
3054     }
3055
3056   htab_delete (ar_hash);
3057 }
3058
3059 \f
3060 static void
3061 push_uleb128 (varray_type *data_area, unsigned int value)
3062 {
3063   do
3064     {
3065       unsigned char byte = value & 0x7f;
3066       value >>= 7;
3067       if (value)
3068         byte |= 0x80;
3069       VARRAY_PUSH_UCHAR (*data_area, byte);
3070     }
3071   while (value);
3072 }
3073
3074 static void
3075 push_sleb128 (varray_type *data_area, int value)
3076 {
3077   unsigned char byte;
3078   int more;
3079
3080   do
3081     {
3082       byte = value & 0x7f;
3083       value >>= 7;
3084       more = ! ((value == 0 && (byte & 0x40) == 0)
3085                 || (value == -1 && (byte & 0x40) != 0));
3086       if (more)
3087         byte |= 0x80;
3088       VARRAY_PUSH_UCHAR (*data_area, byte);
3089     }
3090   while (more);
3091 }
3092
3093 \f
3094 #ifndef HAVE_AS_LEB128
3095 static int
3096 dw2_size_of_call_site_table (void)
3097 {
3098   int n = cfun->eh->call_site_data_used;
3099   int size = n * (4 + 4 + 4);
3100   int i;
3101
3102   for (i = 0; i < n; ++i)
3103     {
3104       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3105       size += size_of_uleb128 (cs->action);
3106     }
3107
3108   return size;
3109 }
3110
3111 static int
3112 sjlj_size_of_call_site_table (void)
3113 {
3114   int n = cfun->eh->call_site_data_used;
3115   int size = 0;
3116   int i;
3117
3118   for (i = 0; i < n; ++i)
3119     {
3120       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3121       size += size_of_uleb128 (INTVAL (cs->landing_pad));
3122       size += size_of_uleb128 (cs->action);
3123     }
3124
3125   return size;
3126 }
3127 #endif
3128
3129 static void
3130 dw2_output_call_site_table (void)
3131 {
3132   int n = cfun->eh->call_site_data_used;
3133   int i;
3134
3135   for (i = 0; i < n; ++i)
3136     {
3137       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3138       char reg_start_lab[32];
3139       char reg_end_lab[32];
3140       char landing_pad_lab[32];
3141
3142       ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i);
3143       ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i);
3144
3145       if (cs->landing_pad)
3146         ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L",
3147                                      CODE_LABEL_NUMBER (cs->landing_pad));
3148
3149       /* ??? Perhaps use insn length scaling if the assembler supports
3150          generic arithmetic.  */
3151       /* ??? Perhaps use attr_length to choose data1 or data2 instead of
3152          data4 if the function is small enough.  */
3153 #ifdef HAVE_AS_LEB128
3154       dw2_asm_output_delta_uleb128 (reg_start_lab,
3155                                     current_function_func_begin_label,
3156                                     "region %d start", i);
3157       dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab,
3158                                     "length");
3159       if (cs->landing_pad)
3160         dw2_asm_output_delta_uleb128 (landing_pad_lab,
3161                                       current_function_func_begin_label,
3162                                       "landing pad");
3163       else
3164         dw2_asm_output_data_uleb128 (0, "landing pad");
3165 #else
3166       dw2_asm_output_delta (4, reg_start_lab,
3167                             current_function_func_begin_label,
3168                             "region %d start", i);
3169       dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
3170       if (cs->landing_pad)
3171         dw2_asm_output_delta (4, landing_pad_lab,
3172                               current_function_func_begin_label,
3173                               "landing pad");
3174       else
3175         dw2_asm_output_data (4, 0, "landing pad");
3176 #endif
3177       dw2_asm_output_data_uleb128 (cs->action, "action");
3178     }
3179
3180   call_site_base += n;
3181 }
3182
3183 static void
3184 sjlj_output_call_site_table (void)
3185 {
3186   int n = cfun->eh->call_site_data_used;
3187   int i;
3188
3189   for (i = 0; i < n; ++i)
3190     {
3191       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3192
3193       dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad),
3194                                    "region %d landing pad", i);
3195       dw2_asm_output_data_uleb128 (cs->action, "action");
3196     }
3197
3198   call_site_base += n;
3199 }
3200
3201 /* Tell assembler to switch to the section for the exception handling
3202    table.  */
3203
3204 void
3205 default_exception_section (void)
3206 {
3207   if (targetm.have_named_sections)
3208     {
3209       int flags;
3210
3211       if (EH_TABLES_CAN_BE_READ_ONLY)
3212         {
3213           int tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
3214           
3215           flags = (! flag_pic
3216                    || ((tt_format & 0x70) != DW_EH_PE_absptr
3217                        && (tt_format & 0x70) != DW_EH_PE_aligned))
3218             ? 0 : SECTION_WRITE;
3219         }
3220       else
3221         flags = SECTION_WRITE;
3222       named_section_flags (".gcc_except_table", flags);
3223     }
3224   else if (flag_pic)
3225     data_section ();
3226   else
3227     readonly_data_section ();
3228 }
3229
3230 void
3231 output_function_exception_table (void)
3232 {
3233   int tt_format, cs_format, lp_format, i, n;
3234 #ifdef HAVE_AS_LEB128
3235   char ttype_label[32];
3236   char cs_after_size_label[32];
3237   char cs_end_label[32];
3238 #else
3239   int call_site_len;
3240 #endif
3241   int have_tt_data;
3242   int tt_format_size = 0;
3243
3244   /* Not all functions need anything.  */
3245   if (! cfun->uses_eh_lsda)
3246     return;
3247
3248 #ifdef TARGET_UNWIND_INFO
3249   /* TODO: Move this into target file.  */
3250   assemble_external_libcall (eh_personality_libfunc);
3251   fputs ("\t.personality\t", asm_out_file);
3252   output_addr_const (asm_out_file, eh_personality_libfunc);
3253   fputs ("\n\t.handlerdata\n", asm_out_file);
3254   /* Note that varasm still thinks we're in the function's code section.
3255      The ".endp" directive that will immediately follow will take us back.  */
3256 #else
3257   targetm.asm_out.exception_section ();
3258 #endif
3259
3260   have_tt_data = (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) > 0
3261                   || VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) > 0);
3262
3263   /* Indicate the format of the @TType entries.  */
3264   if (! have_tt_data)
3265     tt_format = DW_EH_PE_omit;
3266   else
3267     {
3268       tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
3269 #ifdef HAVE_AS_LEB128
3270       ASM_GENERATE_INTERNAL_LABEL (ttype_label, "LLSDATT",
3271                                    current_function_funcdef_no);
3272 #endif
3273       tt_format_size = size_of_encoded_value (tt_format);
3274
3275       assemble_align (tt_format_size * BITS_PER_UNIT);
3276     }
3277
3278   targetm.asm_out.internal_label (asm_out_file, "LLSDA",
3279                              current_function_funcdef_no);
3280
3281   /* The LSDA header.  */
3282
3283   /* Indicate the format of the landing pad start pointer.  An omitted
3284      field implies @LPStart == @Start.  */
3285   /* Currently we always put @LPStart == @Start.  This field would
3286      be most useful in moving the landing pads completely out of
3287      line to another section, but it could also be used to minimize
3288      the size of uleb128 landing pad offsets.  */
3289   lp_format = DW_EH_PE_omit;
3290   dw2_asm_output_data (1, lp_format, "@LPStart format (%s)",
3291                        eh_data_format_name (lp_format));
3292
3293   /* @LPStart pointer would go here.  */
3294
3295   dw2_asm_output_data (1, tt_format, "@TType format (%s)",
3296                        eh_data_format_name (tt_format));
3297
3298 #ifndef HAVE_AS_LEB128
3299   if (USING_SJLJ_EXCEPTIONS)
3300     call_site_len = sjlj_size_of_call_site_table ();
3301   else
3302     call_site_len = dw2_size_of_call_site_table ();
3303 #endif
3304
3305   /* A pc-relative 4-byte displacement to the @TType data.  */
3306   if (have_tt_data)
3307     {
3308 #ifdef HAVE_AS_LEB128
3309       char ttype_after_disp_label[32];
3310       ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label, "LLSDATTD",
3311                                    current_function_funcdef_no);
3312       dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label,
3313                                     "@TType base offset");
3314       ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label);
3315 #else
3316       /* Ug.  Alignment queers things.  */
3317       unsigned int before_disp, after_disp, last_disp, disp;
3318
3319       before_disp = 1 + 1;
3320       after_disp = (1 + size_of_uleb128 (call_site_len)
3321                     + call_site_len
3322                     + VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data)
3323                     + (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data)
3324                        * tt_format_size));
3325
3326       disp = after_disp;
3327       do
3328         {
3329           unsigned int disp_size, pad;
3330
3331           last_disp = disp;
3332           disp_size = size_of_uleb128 (disp);
3333           pad = before_disp + disp_size + after_disp;
3334           if (pad % tt_format_size)
3335             pad = tt_format_size - (pad % tt_format_size);
3336           else
3337             pad = 0;
3338           disp = after_disp + pad;
3339         }
3340       while (disp != last_disp);
3341
3342       dw2_asm_output_data_uleb128 (disp, "@TType base offset");
3343 #endif
3344     }
3345
3346   /* Indicate the format of the call-site offsets.  */
3347 #ifdef HAVE_AS_LEB128
3348   cs_format = DW_EH_PE_uleb128;
3349 #else
3350   cs_format = DW_EH_PE_udata4;
3351 #endif
3352   dw2_asm_output_data (1, cs_format, "call-site format (%s)",
3353                        eh_data_format_name (cs_format));
3354
3355 #ifdef HAVE_AS_LEB128
3356   ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label, "LLSDACSB",
3357                                current_function_funcdef_no);
3358   ASM_GENERATE_INTERNAL_LABEL (cs_end_label, "LLSDACSE",
3359                                current_function_funcdef_no);
3360   dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label,
3361                                 "Call-site table length");
3362   ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label);
3363   if (USING_SJLJ_EXCEPTIONS)
3364     sjlj_output_call_site_table ();
3365   else
3366     dw2_output_call_site_table ();
3367   ASM_OUTPUT_LABEL (asm_out_file, cs_end_label);
3368 #else
3369   dw2_asm_output_data_uleb128 (call_site_len,"Call-site table length");
3370   if (USING_SJLJ_EXCEPTIONS)
3371     sjlj_output_call_site_table ();
3372   else
3373     dw2_output_call_site_table ();
3374 #endif
3375
3376   /* ??? Decode and interpret the data for flag_debug_asm.  */
3377   n = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data);
3378   for (i = 0; i < n; ++i)
3379     dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->action_record_data, i),
3380                          (i ? NULL : "Action record table"));
3381
3382   if (have_tt_data)
3383     assemble_align (tt_format_size * BITS_PER_UNIT);
3384
3385   i = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data);
3386   while (i-- > 0)
3387     {
3388       tree type = VARRAY_TREE (cfun->eh->ttype_data, i);
3389       rtx value;
3390
3391       if (type == NULL_TREE)
3392         value = const0_rtx;
3393       else
3394         {
3395           struct cgraph_varpool_node *node;
3396
3397           type = lookup_type_for_runtime (type);
3398           value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
3399
3400           /* Let cgraph know that the rtti decl is used.  Not all of the
3401              paths below go through assemble_integer, which would take
3402              care of this for us.  */
3403           STRIP_NOPS (type);
3404           if (TREE_CODE (type) == ADDR_EXPR)
3405             {
3406               type = TREE_OPERAND (type, 0);
3407               if (TREE_CODE (type) == VAR_DECL)
3408                 {
3409                   node = cgraph_varpool_node (type);
3410                   if (node)
3411                     cgraph_varpool_mark_needed_node (node);
3412                 }
3413             }
3414           else
3415             gcc_assert (TREE_CODE (type) == INTEGER_CST);
3416         }
3417
3418       if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
3419         assemble_integer (value, tt_format_size,
3420                           tt_format_size * BITS_PER_UNIT, 1);
3421       else
3422         dw2_asm_output_encoded_addr_rtx (tt_format, value, NULL);
3423     }
3424
3425 #ifdef HAVE_AS_LEB128
3426   if (have_tt_data)
3427       ASM_OUTPUT_LABEL (asm_out_file, ttype_label);
3428 #endif
3429
3430   /* ??? Decode and interpret the data for flag_debug_asm.  */
3431   n = VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data);
3432   for (i = 0; i < n; ++i)
3433     dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->ehspec_data, i),
3434                          (i ? NULL : "Exception specification table"));
3435
3436   current_function_section (current_function_decl);
3437 }
3438
3439 /* Dump EH information to OUT.  */
3440 void 
3441 dump_eh_tree (FILE *out, struct function *fun)
3442 {
3443   struct eh_region *i;
3444   int depth = 0;
3445   static const char * const type_name[] = {"unknown", "cleanup", "try", "catch",
3446                                            "allowed_exceptions", "must_not_throw",
3447                                            "throw", "fixup"};
3448
3449   i = fun->eh->region_tree;
3450   if (! i)
3451     return;
3452
3453   fprintf (out, "Eh tree:\n");
3454   while (1)
3455     {
3456       fprintf (out, "  %*s %i %s", depth * 2, "",
3457                i->region_number, type_name [(int)i->type]);
3458       if (i->tree_label)
3459         {
3460           fprintf (out, " tree_label:");
3461           print_generic_expr (out, i->tree_label, 0);
3462         }
3463       fprintf (out, "\n");
3464       /* If there are sub-regions, process them.  */
3465       if (i->inner)
3466         i = i->inner, depth++;
3467       /* If there are peers, process them.  */
3468       else if (i->next_peer)
3469         i = i->next_peer;
3470       /* Otherwise, step back up the tree to the next peer.  */
3471       else
3472         {
3473           do {
3474             i = i->outer;
3475             depth--;
3476             if (i == NULL)
3477               return;
3478           } while (i->next_peer == NULL);
3479           i = i->next_peer;
3480         }
3481     }
3482 }
3483
3484 /* Verify some basic invariants on EH datastructures.  Could be extended to
3485    catch more.  */
3486 void 
3487 verify_eh_tree (struct function *fun)
3488 {
3489   struct eh_region *i, *outer = NULL;
3490   bool err = false;
3491   int nvisited = 0;
3492   int count = 0;
3493   int j;
3494   int depth = 0;
3495
3496   i = fun->eh->region_tree;
3497   if (! i)
3498     return;
3499   for (j = fun->eh->last_region_number; j > 0; --j)
3500     if (fun->eh->region_array[j])
3501       {
3502         count++;
3503         if (fun->eh->region_array[j]->region_number != j)
3504           {
3505             error ("region_array is corrupted for region %i", i->region_number);
3506             err = true;
3507           }
3508       }
3509
3510   while (1)
3511     {
3512       if (fun->eh->region_array[i->region_number] != i)
3513         {
3514           error ("region_array is corrupted for region %i", i->region_number);
3515           err = true;
3516         }
3517       if (i->outer != outer)
3518         {
3519           error ("outer block of region %i is wrong", i->region_number);
3520           err = true;
3521         }
3522       if (i->may_contain_throw && outer && !outer->may_contain_throw)
3523         {
3524           error ("region %i may contain throw and is contained in region that may not",
3525                  i->region_number);
3526           err = true;
3527         }
3528       if (depth < 0)
3529         {
3530           error ("negative nesting depth of region %i", i->region_number);
3531           err = true;
3532         }
3533       nvisited ++;
3534       /* If there are sub-regions, process them.  */
3535       if (i->inner)
3536         outer = i, i = i->inner, depth++;
3537       /* If there are peers, process them.  */
3538       else if (i->next_peer)
3539         i = i->next_peer;
3540       /* Otherwise, step back up the tree to the next peer.  */
3541       else
3542         {
3543           do {
3544             i = i->outer;
3545             depth--;
3546             if (i == NULL)
3547               {
3548                 if (depth != -1)
3549                   {
3550                     error ("Tree list ends on depth %i", depth + 1);
3551                     err = true;
3552                   }
3553                 if (count != nvisited)
3554                   {
3555                     error ("array does not match the region tree");
3556                     err = true;
3557                   }
3558                 if (err)
3559                   {
3560                     dump_eh_tree (stderr, fun);
3561                     internal_error ("verify_eh_tree failed.");
3562                   }
3563                 return;
3564               }
3565             outer = i->outer;
3566           } while (i->next_peer == NULL);
3567           i = i->next_peer;
3568         }
3569     }
3570 }
3571 #include "gt-except.h"