]> gcc.gnu.org Git - gcc.git/blame - gcc/except.c
[multiple changes]
[gcc.git] / gcc / except.c
CommitLineData
12670d88 1/* Implements exception handling.
e5e809f4 2 Copyright (C) 1989, 92-97, 1998 Free Software Foundation, Inc.
4956d07c
MS
3 Contributed by Mike Stump <mrs@cygnus.com>.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22
12670d88
RK
23/* An exception is an event that can be signaled from within a
24 function. This event can then be "caught" or "trapped" by the
25 callers of this function. This potentially allows program flow to
956d6950 26 be transferred to any arbitrary code associated with a function call
12670d88
RK
27 several levels up the stack.
28
29 The intended use for this mechanism is for signaling "exceptional
30 events" in an out-of-band fashion, hence its name. The C++ language
31 (and many other OO-styled or functional languages) practically
32 requires such a mechanism, as otherwise it becomes very difficult
33 or even impossible to signal failure conditions in complex
34 situations. The traditional C++ example is when an error occurs in
35 the process of constructing an object; without such a mechanism, it
36 is impossible to signal that the error occurs without adding global
37 state variables and error checks around every object construction.
38
39 The act of causing this event to occur is referred to as "throwing
40 an exception". (Alternate terms include "raising an exception" or
41 "signaling an exception".) The term "throw" is used because control
42 is returned to the callers of the function that is signaling the
43 exception, and thus there is the concept of "throwing" the
44 exception up the call stack.
45
27a36778
MS
46 There are two major codegen options for exception handling. The
47 flag -fsjlj-exceptions can be used to select the setjmp/longjmp
e9a25f70 48 approach, which is the default. -fno-sjlj-exceptions can be used to
27a36778
MS
49 get the PC range table approach. While this is a compile time
50 flag, an entire application must be compiled with the same codegen
51 option. The first is a PC range table approach, the second is a
52 setjmp/longjmp based scheme. We will first discuss the PC range
53 table approach, after that, we will discuss the setjmp/longjmp
54 based approach.
55
12670d88
RK
56 It is appropriate to speak of the "context of a throw". This
57 context refers to the address where the exception is thrown from,
58 and is used to determine which exception region will handle the
59 exception.
60
61 Regions of code within a function can be marked such that if it
62 contains the context of a throw, control will be passed to a
63 designated "exception handler". These areas are known as "exception
64 regions". Exception regions cannot overlap, but they can be nested
65 to any arbitrary depth. Also, exception regions cannot cross
66 function boundaries.
67
2ed18e63
MS
68 Exception handlers can either be specified by the user (which we
69 will call a "user-defined handler") or generated by the compiler
70 (which we will designate as a "cleanup"). Cleanups are used to
71 perform tasks such as destruction of objects allocated on the
72 stack.
73
956d6950 74 In the current implementation, cleanups are handled by allocating an
2ed18e63
MS
75 exception region for the area that the cleanup is designated for,
76 and the handler for the region performs the cleanup and then
77 rethrows the exception to the outer exception region. From the
78 standpoint of the current implementation, there is little
79 distinction made between a cleanup and a user-defined handler, and
80 the phrase "exception handler" can be used to refer to either one
81 equally well. (The section "Future Directions" below discusses how
82 this will change).
83
84 Each object file that is compiled with exception handling contains
85 a static array of exception handlers named __EXCEPTION_TABLE__.
86 Each entry contains the starting and ending addresses of the
87 exception region, and the address of the handler designated for
88 that region.
12670d88 89
ca55abae
JM
90 If the target does not use the DWARF 2 frame unwind information, at
91 program startup each object file invokes a function named
12670d88 92 __register_exceptions with the address of its local
ca55abae
JM
93 __EXCEPTION_TABLE__. __register_exceptions is defined in libgcc2.c, and
94 is responsible for recording all of the exception regions into one list
95 (which is kept in a static variable named exception_table_list).
96
97 On targets that support crtstuff.c, the unwind information
98 is stored in a section named .eh_frame and the information for the
99 entire shared object or program is registered with a call to
6d8ccdbb 100 __register_frame_info. On other targets, the information for each
d1485032 101 translation unit is registered from the file generated by collect2.
6d8ccdbb 102 __register_frame_info is defined in frame.c, and is responsible for
ca55abae
JM
103 recording all of the unwind regions into one list (which is kept in a
104 static variable named unwind_table_list).
12670d88 105
27a36778 106 The function __throw is actually responsible for doing the
ca55abae
JM
107 throw. On machines that have unwind info support, __throw is generated
108 by code in libgcc2.c, otherwise __throw is generated on a
12670d88 109 per-object-file basis for each source file compiled with
38e01259 110 -fexceptions by the C++ frontend. Before __throw is invoked,
ca55abae
JM
111 the current context of the throw needs to be placed in the global
112 variable __eh_pc.
12670d88 113
27a36778 114 __throw attempts to find the appropriate exception handler for the
12670d88 115 PC value stored in __eh_pc by calling __find_first_exception_table_match
2ed18e63 116 (which is defined in libgcc2.c). If __find_first_exception_table_match
ca55abae
JM
117 finds a relevant handler, __throw transfers control directly to it.
118
119 If a handler for the context being thrown from can't be found, __throw
120 walks (see Walking the stack below) the stack up the dynamic call chain to
121 continue searching for an appropriate exception handler based upon the
122 caller of the function it last sought a exception handler for. It stops
123 then either an exception handler is found, or when the top of the
124 call chain is reached.
125
126 If no handler is found, an external library function named
127 __terminate is called. If a handler is found, then we restart
128 our search for a handler at the end of the call chain, and repeat
129 the search process, but instead of just walking up the call chain,
130 we unwind the call chain as we walk up it.
12670d88
RK
131
132 Internal implementation details:
133
12670d88 134 To associate a user-defined handler with a block of statements, the
27a36778 135 function expand_start_try_stmts is used to mark the start of the
12670d88 136 block of statements with which the handler is to be associated
2ed18e63
MS
137 (which is known as a "try block"). All statements that appear
138 afterwards will be associated with the try block.
139
27a36778 140 A call to expand_start_all_catch marks the end of the try block,
2ed18e63
MS
141 and also marks the start of the "catch block" (the user-defined
142 handler) associated with the try block.
143
144 This user-defined handler will be invoked for *every* exception
145 thrown with the context of the try block. It is up to the handler
146 to decide whether or not it wishes to handle any given exception,
147 as there is currently no mechanism in this implementation for doing
148 this. (There are plans for conditionally processing an exception
149 based on its "type", which will provide a language-independent
150 mechanism).
151
152 If the handler chooses not to process the exception (perhaps by
153 looking at an "exception type" or some other additional data
154 supplied with the exception), it can fall through to the end of the
27a36778 155 handler. expand_end_all_catch and expand_leftover_cleanups
2ed18e63
MS
156 add additional code to the end of each handler to take care of
157 rethrowing to the outer exception handler.
158
159 The handler also has the option to continue with "normal flow of
160 code", or in other words to resume executing at the statement
161 immediately after the end of the exception region. The variable
162 caught_return_label_stack contains a stack of labels, and jumping
27a36778 163 to the topmost entry's label via expand_goto will resume normal
2ed18e63
MS
164 flow to the statement immediately after the end of the exception
165 region. If the handler falls through to the end, the exception will
166 be rethrown to the outer exception region.
167
168 The instructions for the catch block are kept as a separate
169 sequence, and will be emitted at the end of the function along with
27a36778
MS
170 the handlers specified via expand_eh_region_end. The end of the
171 catch block is marked with expand_end_all_catch.
12670d88
RK
172
173 Any data associated with the exception must currently be handled by
174 some external mechanism maintained in the frontend. For example,
175 the C++ exception mechanism passes an arbitrary value along with
176 the exception, and this is handled in the C++ frontend by using a
2ed18e63
MS
177 global variable to hold the value. (This will be changing in the
178 future.)
179
180 The mechanism in C++ for handling data associated with the
181 exception is clearly not thread-safe. For a thread-based
182 environment, another mechanism must be used (possibly using a
183 per-thread allocation mechanism if the size of the area that needs
184 to be allocated isn't known at compile time.)
185
186 Internally-generated exception regions (cleanups) are marked by
27a36778 187 calling expand_eh_region_start to mark the start of the region,
2ed18e63
MS
188 and expand_eh_region_end (handler) is used to both designate the
189 end of the region and to associate a specified handler/cleanup with
190 the region. The rtl code in HANDLER will be invoked whenever an
191 exception occurs in the region between the calls to
192 expand_eh_region_start and expand_eh_region_end. After HANDLER is
193 executed, additional code is emitted to handle rethrowing the
194 exception to the outer exception handler. The code for HANDLER will
195 be emitted at the end of the function.
12670d88
RK
196
197 TARGET_EXPRs can also be used to designate exception regions. A
198 TARGET_EXPR gives an unwind-protect style interface commonly used
199 in functional languages such as LISP. The associated expression is
2ed18e63
MS
200 evaluated, and whether or not it (or any of the functions that it
201 calls) throws an exception, the protect expression is always
202 invoked. This implementation takes care of the details of
203 associating an exception table entry with the expression and
204 generating the necessary code (it actually emits the protect
205 expression twice, once for normal flow and once for the exception
206 case). As for the other handlers, the code for the exception case
207 will be emitted at the end of the function.
208
209 Cleanups can also be specified by using add_partial_entry (handler)
27a36778 210 and end_protect_partials. add_partial_entry creates the start of
2ed18e63
MS
211 a new exception region; HANDLER will be invoked if an exception is
212 thrown with the context of the region between the calls to
213 add_partial_entry and end_protect_partials. end_protect_partials is
214 used to mark the end of these regions. add_partial_entry can be
215 called as many times as needed before calling end_protect_partials.
216 However, end_protect_partials should only be invoked once for each
27a36778 217 group of calls to add_partial_entry as the entries are queued
2ed18e63
MS
218 and all of the outstanding entries are processed simultaneously
219 when end_protect_partials is invoked. Similarly to the other
220 handlers, the code for HANDLER will be emitted at the end of the
221 function.
12670d88
RK
222
223 The generated RTL for an exception region includes
224 NOTE_INSN_EH_REGION_BEG and NOTE_INSN_EH_REGION_END notes that mark
225 the start and end of the exception region. A unique label is also
2ed18e63
MS
226 generated at the start of the exception region, which is available
227 by looking at the ehstack variable. The topmost entry corresponds
228 to the current region.
12670d88
RK
229
230 In the current implementation, an exception can only be thrown from
231 a function call (since the mechanism used to actually throw an
232 exception involves calling __throw). If an exception region is
233 created but no function calls occur within that region, the region
2ed18e63 234 can be safely optimized away (along with its exception handlers)
27a36778
MS
235 since no exceptions can ever be caught in that region. This
236 optimization is performed unless -fasynchronous-exceptions is
237 given. If the user wishes to throw from a signal handler, or other
238 asynchronous place, -fasynchronous-exceptions should be used when
239 compiling for maximally correct code, at the cost of additional
240 exception regions. Using -fasynchronous-exceptions only produces
241 code that is reasonably safe in such situations, but a correct
242 program cannot rely upon this working. It can be used in failsafe
243 code, where trying to continue on, and proceeding with potentially
244 incorrect results is better than halting the program.
245
12670d88 246
ca55abae 247 Walking the stack:
12670d88 248
ca55abae
JM
249 The stack is walked by starting with a pointer to the current
250 frame, and finding the pointer to the callers frame. The unwind info
251 tells __throw how to find it.
12670d88 252
ca55abae 253 Unwinding the stack:
12670d88 254
ca55abae
JM
255 When we use the term unwinding the stack, we mean undoing the
256 effects of the function prologue in a controlled fashion so that we
257 still have the flow of control. Otherwise, we could just return
258 (jump to the normal end of function epilogue).
259
260 This is done in __throw in libgcc2.c when we know that a handler exists
261 in a frame higher up the call stack than its immediate caller.
262
263 To unwind, we find the unwind data associated with the frame, if any.
264 If we don't find any, we call the library routine __terminate. If we do
265 find it, we use the information to copy the saved register values from
266 that frame into the register save area in the frame for __throw, return
267 into a stub which updates the stack pointer, and jump to the handler.
268 The normal function epilogue for __throw handles restoring the saved
269 values into registers.
270
271 When unwinding, we use this method if we know it will
272 work (if DWARF2_UNWIND_INFO is defined). Otherwise, we know that
273 an inline unwinder will have been emitted for any function that
274 __unwind_function cannot unwind. The inline unwinder appears as a
275 normal exception handler for the entire function, for any function
276 that we know cannot be unwound by __unwind_function. We inform the
277 compiler of whether a function can be unwound with
278 __unwind_function by having DOESNT_NEED_UNWINDER evaluate to true
279 when the unwinder isn't needed. __unwind_function is used as an
280 action of last resort. If no other method can be used for
281 unwinding, __unwind_function is used. If it cannot unwind, it
956d6950 282 should call __terminate.
ca55abae
JM
283
284 By default, if the target-specific backend doesn't supply a definition
285 for __unwind_function and doesn't support DWARF2_UNWIND_INFO, inlined
286 unwinders will be used instead. The main tradeoff here is in text space
287 utilization. Obviously, if inline unwinders have to be generated
288 repeatedly, this uses much more space than if a single routine is used.
2ed18e63
MS
289
290 However, it is simply not possible on some platforms to write a
291 generalized routine for doing stack unwinding without having some
ca55abae
JM
292 form of additional data associated with each function. The current
293 implementation can encode this data in the form of additional
294 machine instructions or as static data in tabular form. The later
295 is called the unwind data.
12670d88 296
ca55abae
JM
297 The backend macro DOESNT_NEED_UNWINDER is used to conditionalize whether
298 or not per-function unwinders are needed. If DOESNT_NEED_UNWINDER is
299 defined and has a non-zero value, a per-function unwinder is not emitted
300 for the current function. If the static unwind data is supported, then
301 a per-function unwinder is not emitted.
12670d88 302
27a36778 303 On some platforms it is possible that neither __unwind_function
12670d88 304 nor inlined unwinders are available. For these platforms it is not
27a36778 305 possible to throw through a function call, and abort will be
2ed18e63
MS
306 invoked instead of performing the throw.
307
ca55abae
JM
308 The reason the unwind data may be needed is that on some platforms
309 the order and types of data stored on the stack can vary depending
310 on the type of function, its arguments and returned values, and the
311 compilation options used (optimization versus non-optimization,
312 -fomit-frame-pointer, processor variations, etc).
313
314 Unfortunately, this also means that throwing through functions that
315 aren't compiled with exception handling support will still not be
316 possible on some platforms. This problem is currently being
317 investigated, but no solutions have been found that do not imply
318 some unacceptable performance penalties.
319
2ed18e63
MS
320 Future directions:
321
27a36778 322 Currently __throw makes no differentiation between cleanups and
2ed18e63
MS
323 user-defined exception regions. While this makes the implementation
324 simple, it also implies that it is impossible to determine if a
325 user-defined exception handler exists for a given exception without
326 completely unwinding the stack in the process. This is undesirable
327 from the standpoint of debugging, as ideally it would be possible
328 to trap unhandled exceptions in the debugger before the process of
329 unwinding has even started.
330
331 This problem can be solved by marking user-defined handlers in a
332 special way (probably by adding additional bits to exception_table_list).
27a36778 333 A two-pass scheme could then be used by __throw to iterate
2ed18e63
MS
334 through the table. The first pass would search for a relevant
335 user-defined handler for the current context of the throw, and if
336 one is found, the second pass would then invoke all needed cleanups
337 before jumping to the user-defined handler.
338
339 Many languages (including C++ and Ada) make execution of a
340 user-defined handler conditional on the "type" of the exception
341 thrown. (The type of the exception is actually the type of the data
342 that is thrown with the exception.) It will thus be necessary for
27a36778 343 __throw to be able to determine if a given user-defined
2ed18e63
MS
344 exception handler will actually be executed, given the type of
345 exception.
346
347 One scheme is to add additional information to exception_table_list
27a36778 348 as to the types of exceptions accepted by each handler. __throw
2ed18e63
MS
349 can do the type comparisons and then determine if the handler is
350 actually going to be executed.
351
352 There is currently no significant level of debugging support
27a36778 353 available, other than to place a breakpoint on __throw. While
2ed18e63
MS
354 this is sufficient in most cases, it would be helpful to be able to
355 know where a given exception was going to be thrown to before it is
356 actually thrown, and to be able to choose between stopping before
357 every exception region (including cleanups), or just user-defined
358 exception regions. This should be possible to do in the two-pass
27a36778 359 scheme by adding additional labels to __throw for appropriate
2ed18e63
MS
360 breakpoints, and additional debugger commands could be added to
361 query various state variables to determine what actions are to be
362 performed next.
363
ca55abae
JM
364 Another major problem that is being worked on is the issue with stack
365 unwinding on various platforms. Currently the only platforms that have
366 support for the generation of a generic unwinder are the SPARC and MIPS.
367 All other ports require per-function unwinders, which produce large
368 amounts of code bloat.
27a36778
MS
369
370 For setjmp/longjmp based exception handling, some of the details
371 are as above, but there are some additional details. This section
372 discusses the details.
373
374 We don't use NOTE_INSN_EH_REGION_{BEG,END} pairs. We don't
375 optimize EH regions yet. We don't have to worry about machine
376 specific issues with unwinding the stack, as we rely upon longjmp
377 for all the machine specific details. There is no variable context
378 of a throw, just the one implied by the dynamic handler stack
379 pointed to by the dynamic handler chain. There is no exception
956d6950 380 table, and no calls to __register_exceptions. __sjthrow is used
27a36778
MS
381 instead of __throw, and it works by using the dynamic handler
382 chain, and longjmp. -fasynchronous-exceptions has no effect, as
383 the elimination of trivial exception regions is not yet performed.
384
385 A frontend can set protect_cleanup_actions_with_terminate when all
386 the cleanup actions should be protected with an EH region that
387 calls terminate when an unhandled exception is throw. C++ does
388 this, Ada does not. */
4956d07c
MS
389
390
391#include "config.h"
ca55abae 392#include "defaults.h"
9a0d1e1b 393#include "eh-common.h"
670ee920 394#include "system.h"
4956d07c
MS
395#include "rtl.h"
396#include "tree.h"
397#include "flags.h"
398#include "except.h"
399#include "function.h"
400#include "insn-flags.h"
401#include "expr.h"
402#include "insn-codes.h"
403#include "regs.h"
404#include "hard-reg-set.h"
405#include "insn-config.h"
406#include "recog.h"
407#include "output.h"
10f0ad3d 408#include "toplev.h"
4956d07c 409
27a36778
MS
410/* One to use setjmp/longjmp method of generating code for exception
411 handling. */
412
d1485032 413int exceptions_via_longjmp = 2;
27a36778
MS
414
415/* One to enable asynchronous exception support. */
416
417int asynchronous_exceptions = 0;
418
419/* One to protect cleanup actions with a handler that calls
420 __terminate, zero otherwise. */
421
e701eb4d 422int protect_cleanup_actions_with_terminate;
27a36778 423
12670d88 424/* A list of labels used for exception handlers. Created by
4956d07c
MS
425 find_exception_handler_labels for the optimization passes. */
426
427rtx exception_handler_labels;
428
154bba13
TT
429/* The EH context. Nonzero if the function has already
430 fetched a pointer to the EH context for exception handling. */
27a36778 431
154bba13 432rtx current_function_ehc;
27a36778 433
956d6950 434/* A stack used for keeping track of the currently active exception
12670d88 435 handling region. As each exception region is started, an entry
4956d07c
MS
436 describing the region is pushed onto this stack. The current
437 region can be found by looking at the top of the stack, and as we
12670d88
RK
438 exit regions, the corresponding entries are popped.
439
27a36778 440 Entries cannot overlap; they can be nested. So there is only one
12670d88
RK
441 entry at most that corresponds to the current instruction, and that
442 is the entry on the top of the stack. */
4956d07c 443
27a36778 444static struct eh_stack ehstack;
4956d07c 445
9a0d1e1b
AM
446
447/* This stack is used to represent what the current eh region is
448 for the catch blocks beings processed */
449
450static struct eh_stack catchstack;
451
12670d88
RK
452/* A queue used for tracking which exception regions have closed but
453 whose handlers have not yet been expanded. Regions are emitted in
454 groups in an attempt to improve paging performance.
455
456 As we exit a region, we enqueue a new entry. The entries are then
27a36778 457 dequeued during expand_leftover_cleanups and expand_start_all_catch,
12670d88
RK
458
459 We should redo things so that we either take RTL for the handler,
460 or we expand the handler expressed as a tree immediately at region
461 end time. */
4956d07c 462
27a36778 463static struct eh_queue ehqueue;
4956d07c 464
12670d88 465/* Insns for all of the exception handlers for the current function.
abeeec2a 466 They are currently emitted by the frontend code. */
4956d07c
MS
467
468rtx catch_clauses;
469
12670d88
RK
470/* A TREE_CHAINed list of handlers for regions that are not yet
471 closed. The TREE_VALUE of each entry contains the handler for the
abeeec2a 472 corresponding entry on the ehstack. */
4956d07c 473
12670d88 474static tree protect_list;
4956d07c
MS
475
476/* Stacks to keep track of various labels. */
477
12670d88
RK
478/* Keeps track of the label to resume to should one want to resume
479 normal control flow out of a handler (instead of, say, returning to
1418bb67 480 the caller of the current function or exiting the program). */
4956d07c
MS
481
482struct label_node *caught_return_label_stack = NULL;
483
956d6950
JL
484/* Keeps track of the label used as the context of a throw to rethrow an
485 exception to the outer exception region. */
486
487struct label_node *outer_context_label_stack = NULL;
488
12670d88 489/* A random data area for the front end's own use. */
4956d07c
MS
490
491struct label_node *false_label_stack = NULL;
492
242c13b0
JL
493static void push_eh_entry PROTO((struct eh_stack *));
494static struct eh_entry * pop_eh_entry PROTO((struct eh_stack *));
495static void enqueue_eh_entry PROTO((struct eh_queue *, struct eh_entry *));
496static struct eh_entry * dequeue_eh_entry PROTO((struct eh_queue *));
497static rtx call_get_eh_context PROTO((void));
498static void start_dynamic_cleanup PROTO((tree, tree));
499static void start_dynamic_handler PROTO((void));
e701eb4d 500static void expand_rethrow PROTO((rtx));
242c13b0
JL
501static void output_exception_table_entry PROTO((FILE *, int));
502static int can_throw PROTO((rtx));
503static rtx scan_region PROTO((rtx, int, int *));
504static void eh_regs PROTO((rtx *, rtx *, int));
505static void set_insn_eh_region PROTO((rtx *, int));
e701eb4d 506
242c13b0 507rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx));
4956d07c
MS
508\f
509/* Various support routines to manipulate the various data structures
510 used by the exception handling code. */
511
512/* Push a label entry onto the given STACK. */
513
514void
515push_label_entry (stack, rlabel, tlabel)
516 struct label_node **stack;
517 rtx rlabel;
518 tree tlabel;
519{
520 struct label_node *newnode
521 = (struct label_node *) xmalloc (sizeof (struct label_node));
522
523 if (rlabel)
524 newnode->u.rlabel = rlabel;
525 else
526 newnode->u.tlabel = tlabel;
527 newnode->chain = *stack;
528 *stack = newnode;
529}
530
531/* Pop a label entry from the given STACK. */
532
533rtx
534pop_label_entry (stack)
535 struct label_node **stack;
536{
537 rtx label;
538 struct label_node *tempnode;
539
540 if (! *stack)
541 return NULL_RTX;
542
543 tempnode = *stack;
544 label = tempnode->u.rlabel;
545 *stack = (*stack)->chain;
546 free (tempnode);
547
548 return label;
549}
550
551/* Return the top element of the given STACK. */
552
553tree
554top_label_entry (stack)
555 struct label_node **stack;
556{
557 if (! *stack)
558 return NULL_TREE;
559
560 return (*stack)->u.tlabel;
561}
562
9a0d1e1b
AM
563/* get an exception label. These must be on the permanent obstack */
564
565rtx
566gen_exception_label ()
567{
568 rtx lab;
569
570 push_obstacks_nochange ();
571 end_temporary_allocation ();
572 lab = gen_label_rtx ();
573 pop_obstacks ();
574 return lab;
575}
576
478b0752 577/* Push a new eh_node entry onto STACK. */
4956d07c 578
478b0752 579static void
4956d07c
MS
580push_eh_entry (stack)
581 struct eh_stack *stack;
582{
583 struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
584 struct eh_entry *entry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry));
585
478b0752 586 entry->outer_context = gen_label_rtx ();
4956d07c 587 entry->finalization = NULL_TREE;
9a0d1e1b
AM
588 entry->label_used = 0;
589 entry->exception_handler_label = gen_exception_label ();
590
591 node->entry = entry;
592 node->chain = stack->top;
593 stack->top = node;
594}
4956d07c 595
9a0d1e1b
AM
596/* push an existing entry onto a stack. */
597static void
598push_entry (stack, entry)
599 struct eh_stack *stack;
600 struct eh_entry *entry;
601{
602 struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
4956d07c
MS
603 node->entry = entry;
604 node->chain = stack->top;
605 stack->top = node;
4956d07c
MS
606}
607
608/* Pop an entry from the given STACK. */
609
610static struct eh_entry *
611pop_eh_entry (stack)
612 struct eh_stack *stack;
613{
614 struct eh_node *tempnode;
615 struct eh_entry *tempentry;
616
617 tempnode = stack->top;
618 tempentry = tempnode->entry;
619 stack->top = stack->top->chain;
620 free (tempnode);
621
622 return tempentry;
623}
624
625/* Enqueue an ENTRY onto the given QUEUE. */
626
627static void
628enqueue_eh_entry (queue, entry)
629 struct eh_queue *queue;
630 struct eh_entry *entry;
631{
632 struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
633
634 node->entry = entry;
635 node->chain = NULL;
636
637 if (queue->head == NULL)
638 {
639 queue->head = node;
640 }
641 else
642 {
643 queue->tail->chain = node;
644 }
645 queue->tail = node;
646}
647
648/* Dequeue an entry from the given QUEUE. */
649
650static struct eh_entry *
651dequeue_eh_entry (queue)
652 struct eh_queue *queue;
653{
654 struct eh_node *tempnode;
655 struct eh_entry *tempentry;
656
657 if (queue->head == NULL)
658 return NULL;
659
660 tempnode = queue->head;
661 queue->head = queue->head->chain;
662
663 tempentry = tempnode->entry;
664 free (tempnode);
665
666 return tempentry;
667}
9a0d1e1b
AM
668
669static void
670receive_exception_label (handler_label)
671 rtx handler_label;
672{
673 emit_label (handler_label);
674
675#ifdef HAVE_exception_receiver
676 if (! exceptions_via_longjmp)
677 if (HAVE_exception_receiver)
678 emit_insn (gen_exception_receiver ());
679#endif
680
681#ifdef HAVE_nonlocal_goto_receiver
682 if (! exceptions_via_longjmp)
683 if (HAVE_nonlocal_goto_receiver)
684 emit_insn (gen_nonlocal_goto_receiver ());
685#endif
686}
687
688
689struct func_eh_entry
690{
691 int range_number; /* EH region number from EH NOTE insn's */
692 struct handler_info *handlers;
693};
694
695
696/* table of function eh regions */
697static struct func_eh_entry *function_eh_regions = NULL;
698static int num_func_eh_entries = 0;
699static int current_func_eh_entry = 0;
700
701#define SIZE_FUNC_EH(X) (sizeof (struct func_eh_entry) * X)
702
703/* Add a new eh_entry for this function, and base it off of the information
704 in the EH_ENTRY parameter. A NULL parameter is invalid. The number
705 returned is an number which uniquely identifies this exception range. */
706
707int
708new_eh_region_entry (note_eh_region)
709 int note_eh_region;
710{
711 if (current_func_eh_entry == num_func_eh_entries)
712 {
713 if (num_func_eh_entries == 0)
714 {
715 function_eh_regions =
716 (struct func_eh_entry *) malloc (SIZE_FUNC_EH (50));
717 num_func_eh_entries = 50;
718 }
719 else
720 {
721 num_func_eh_entries = num_func_eh_entries * 3 / 2;
722 function_eh_regions = (struct func_eh_entry *)
723 realloc (function_eh_regions, SIZE_FUNC_EH (num_func_eh_entries));
724 }
725 }
726 function_eh_regions[current_func_eh_entry].range_number = note_eh_region;
727 function_eh_regions[current_func_eh_entry].handlers = NULL;
728
729 return current_func_eh_entry++;
730}
731
732/* Add new handler information to an exception range. The first parameter
733 specifies the range number (returned from new_eh_entry()). The second
734 parameter specifies the handler. By default the handler is inserted at
735 the end of the list. A handler list may contain only ONE NULL_TREE
736 typeinfo entry. Regardless where it is positioned, a NULL_TREE entry
737 is always output as the LAST handler in the exception table for a region. */
738
739void
740add_new_handler (region, newhandler)
741 int region;
742 struct handler_info *newhandler;
743{
744 struct handler_info *last;
745
746 newhandler->next = NULL;
747 last = function_eh_regions[region].handlers;
748 if (last == NULL)
749 function_eh_regions[region].handlers = newhandler;
750 else
751 {
752 for ( ; last->next != NULL; last = last->next)
753 last->next = newhandler;
754 }
755}
756
9f8e6243
AM
757/* Remove a handler label. The handler label is being deleted, so all
758 regions which reference this handler should have it removed from their
759 list of possible handlers. Any region which has the final handler
760 removed can be deleted. */
761
762void remove_handler (removing_label)
763 rtx removing_label;
764{
765 struct handler_info *handler, *last;
766 int x;
767 for (x = 0 ; x < current_func_eh_entry; ++x)
768 {
769 last = NULL;
770 handler = function_eh_regions[x].handlers;
771 for ( ; handler; last = handler, handler = handler->next)
772 if (handler->handler_label == removing_label)
773 {
774 if (last)
775 {
776 last->next = handler->next;
777 handler = last;
778 }
779 else
780 function_eh_regions[x].handlers = handler->next;
781 }
782 }
783}
784
9a0d1e1b
AM
785/* Create a new handler structure initialized with the handler label and
786 typeinfo fields passed in. */
787
788struct handler_info *
789get_new_handler (handler, typeinfo)
790 rtx handler;
791 void *typeinfo;
792{
793 struct handler_info* ptr;
794 ptr = (struct handler_info *) malloc (sizeof (struct handler_info));
795 ptr->handler_label = handler;
796 ptr->type_info = typeinfo;
797 ptr->next = NULL;
798
799 return ptr;
800}
801
802
803
804/* Find the index in function_eh_regions associated with a NOTE region. If
805 the region cannot be found, a -1 is returned. This should never happen! */
806
807int
808find_func_region (insn_region)
809 int insn_region;
810{
811 int x;
812 for (x = 0; x < current_func_eh_entry; x++)
813 if (function_eh_regions[x].range_number == insn_region)
814 return x;
815
816 return -1;
817}
818
819/* Get a pointer to the first handler in an exception region's list. */
820
821struct handler_info *
822get_first_handler (region)
823 int region;
824{
825 return function_eh_regions[find_func_region (region)].handlers;
826}
827
828/* Clean out the function_eh_region table and free all memory */
829
830static void
831clear_function_eh_region ()
832{
833 int x;
834 struct handler_info *ptr, *next;
835 for (x = 0; x < current_func_eh_entry; x++)
836 for (ptr = function_eh_regions[x].handlers; ptr != NULL; ptr = next)
837 {
838 next = ptr->next;
839 free (ptr);
840 }
841 free (function_eh_regions);
842 num_func_eh_entries = 0;
843 current_func_eh_entry = 0;
844}
845
846/* Make a duplicate of an exception region by copying all the handlers
847 for an exception region. Return the new handler index. */
848
849int
850duplicate_handlers (old_note_eh_region, new_note_eh_region)
851 int old_note_eh_region, new_note_eh_region;
852{
853 struct handler_info *ptr, *new_ptr;
854 int new_region, region;
855
856 region = find_func_region (old_note_eh_region);
857 if (region == -1)
858 error ("Cannot duplicate non-existant exception region.");
859
860 if (find_func_region (new_note_eh_region) != -1)
861 error ("Cannot duplicate EH region because new note region already exists");
862
863 new_region = new_eh_region_entry (new_note_eh_region);
864 ptr = function_eh_regions[region].handlers;
865
866 for ( ; ptr; ptr = ptr->next)
867 {
868 new_ptr = get_new_handler (ptr->handler_label, ptr->type_info);
869 add_new_handler (new_region, new_ptr);
870 }
871
872 return new_region;
873}
874
4956d07c 875\f
38e01259 876/* Routine to see if exception handling is turned on.
4956d07c 877 DO_WARN is non-zero if we want to inform the user that exception
12670d88
RK
878 handling is turned off.
879
880 This is used to ensure that -fexceptions has been specified if the
abeeec2a 881 compiler tries to use any exception-specific functions. */
4956d07c
MS
882
883int
884doing_eh (do_warn)
885 int do_warn;
886{
887 if (! flag_exceptions)
888 {
889 static int warned = 0;
890 if (! warned && do_warn)
891 {
892 error ("exception handling disabled, use -fexceptions to enable");
893 warned = 1;
894 }
895 return 0;
896 }
897 return 1;
898}
899
12670d88 900/* Given a return address in ADDR, determine the address we should use
abeeec2a 901 to find the corresponding EH region. */
4956d07c
MS
902
903rtx
904eh_outer_context (addr)
905 rtx addr;
906{
907 /* First mask out any unwanted bits. */
908#ifdef MASK_RETURN_ADDR
ca55abae 909 expand_and (addr, MASK_RETURN_ADDR, addr);
4956d07c
MS
910#endif
911
ca55abae
JM
912 /* Then adjust to find the real return address. */
913#if defined (RETURN_ADDR_OFFSET)
914 addr = plus_constant (addr, RETURN_ADDR_OFFSET);
4956d07c
MS
915#endif
916
917 return addr;
918}
919
27a36778
MS
920/* Start a new exception region for a region of code that has a
921 cleanup action and push the HANDLER for the region onto
922 protect_list. All of the regions created with add_partial_entry
923 will be ended when end_protect_partials is invoked. */
12670d88
RK
924
925void
926add_partial_entry (handler)
927 tree handler;
928{
929 expand_eh_region_start ();
930
abeeec2a 931 /* Make sure the entry is on the correct obstack. */
12670d88
RK
932 push_obstacks_nochange ();
933 resume_temporary_allocation ();
27a36778
MS
934
935 /* Because this is a cleanup action, we may have to protect the handler
936 with __terminate. */
937 handler = protect_with_terminate (handler);
938
12670d88
RK
939 protect_list = tree_cons (NULL_TREE, handler, protect_list);
940 pop_obstacks ();
941}
942
100d81d4 943/* Emit code to get EH context to current function. */
27a36778 944
154bba13 945static rtx
01eb7f9a 946call_get_eh_context ()
27a36778 947{
bb727b5a
JM
948 static tree fn;
949 tree expr;
950
951 if (fn == NULL_TREE)
952 {
953 tree fntype;
154bba13 954 fn = get_identifier ("__get_eh_context");
bb727b5a
JM
955 push_obstacks_nochange ();
956 end_temporary_allocation ();
957 fntype = build_pointer_type (build_pointer_type
958 (build_pointer_type (void_type_node)));
959 fntype = build_function_type (fntype, NULL_TREE);
960 fn = build_decl (FUNCTION_DECL, fn, fntype);
961 DECL_EXTERNAL (fn) = 1;
962 TREE_PUBLIC (fn) = 1;
963 DECL_ARTIFICIAL (fn) = 1;
964 TREE_READONLY (fn) = 1;
965 make_decl_rtl (fn, NULL_PTR, 1);
966 assemble_external (fn);
967 pop_obstacks ();
968 }
969
970 expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
971 expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
972 expr, NULL_TREE, NULL_TREE);
973 TREE_SIDE_EFFECTS (expr) = 1;
bb727b5a 974
100d81d4 975 return copy_to_reg (expand_expr (expr, NULL_RTX, VOIDmode, 0));
154bba13
TT
976}
977
978/* Get a reference to the EH context.
979 We will only generate a register for the current function EH context here,
980 and emit a USE insn to mark that this is a EH context register.
981
982 Later, emit_eh_context will emit needed call to __get_eh_context
983 in libgcc2, and copy the value to the register we have generated. */
984
985rtx
01eb7f9a 986get_eh_context ()
154bba13
TT
987{
988 if (current_function_ehc == 0)
989 {
990 rtx insn;
991
992 current_function_ehc = gen_reg_rtx (Pmode);
993
38a448ca
RH
994 insn = gen_rtx_USE (GET_MODE (current_function_ehc),
995 current_function_ehc);
154bba13
TT
996 insn = emit_insn_before (insn, get_first_nonparm_insn ());
997
998 REG_NOTES (insn)
38a448ca
RH
999 = gen_rtx_EXPR_LIST (REG_EH_CONTEXT, current_function_ehc,
1000 REG_NOTES (insn));
154bba13
TT
1001 }
1002 return current_function_ehc;
1003}
1004
154bba13
TT
1005/* Get a reference to the dynamic handler chain. It points to the
1006 pointer to the next element in the dynamic handler chain. It ends
1007 when there are no more elements in the dynamic handler chain, when
1008 the value is &top_elt from libgcc2.c. Immediately after the
1009 pointer, is an area suitable for setjmp/longjmp when
1010 DONT_USE_BUILTIN_SETJMP is defined, and an area suitable for
1011 __builtin_setjmp/__builtin_longjmp when DONT_USE_BUILTIN_SETJMP
1012 isn't defined. */
1013
1014rtx
1015get_dynamic_handler_chain ()
1016{
1017 rtx ehc, dhc, result;
1018
01eb7f9a 1019 ehc = get_eh_context ();
154bba13
TT
1020 dhc = ehc;
1021
1022 result = copy_to_reg (dhc);
1023
1024 /* We don't want a copy of the dcc, but rather, the single dcc. */
38a448ca 1025 return gen_rtx_MEM (Pmode, result);
27a36778
MS
1026}
1027
1028/* Get a reference to the dynamic cleanup chain. It points to the
1029 pointer to the next element in the dynamic cleanup chain.
1030 Immediately after the pointer, are two Pmode variables, one for a
1031 pointer to a function that performs the cleanup action, and the
1032 second, the argument to pass to that function. */
1033
1034rtx
1035get_dynamic_cleanup_chain ()
1036{
154bba13 1037 rtx dhc, dcc, result;
27a36778
MS
1038
1039 dhc = get_dynamic_handler_chain ();
1040 dcc = plus_constant (dhc, GET_MODE_SIZE (Pmode));
1041
154bba13 1042 result = copy_to_reg (dcc);
27a36778
MS
1043
1044 /* We don't want a copy of the dcc, but rather, the single dcc. */
38a448ca 1045 return gen_rtx_MEM (Pmode, result);
154bba13
TT
1046}
1047
27a36778
MS
1048/* Generate code to evaluate X and jump to LABEL if the value is nonzero.
1049 LABEL is an rtx of code CODE_LABEL, in this function. */
1050
1051void
1052jumpif_rtx (x, label)
1053 rtx x;
1054 rtx label;
1055{
1056 jumpif (make_tree (type_for_mode (GET_MODE (x), 0), x), label);
1057}
1058
1059/* Generate code to evaluate X and jump to LABEL if the value is zero.
1060 LABEL is an rtx of code CODE_LABEL, in this function. */
1061
1062void
1063jumpifnot_rtx (x, label)
1064 rtx x;
1065 rtx label;
1066{
1067 jumpifnot (make_tree (type_for_mode (GET_MODE (x), 0), x), label);
1068}
1069
1070/* Start a dynamic cleanup on the EH runtime dynamic cleanup stack.
1071 We just need to create an element for the cleanup list, and push it
1072 into the chain.
1073
1074 A dynamic cleanup is a cleanup action implied by the presence of an
1075 element on the EH runtime dynamic cleanup stack that is to be
1076 performed when an exception is thrown. The cleanup action is
1077 performed by __sjthrow when an exception is thrown. Only certain
1078 actions can be optimized into dynamic cleanup actions. For the
1079 restrictions on what actions can be performed using this routine,
1080 see expand_eh_region_start_tree. */
1081
1082static void
1083start_dynamic_cleanup (func, arg)
1084 tree func;
1085 tree arg;
1086{
381127e8 1087 rtx dcc;
27a36778
MS
1088 rtx new_func, new_arg;
1089 rtx x, buf;
1090 int size;
1091
1092 /* We allocate enough room for a pointer to the function, and
1093 one argument. */
1094 size = 2;
1095
1096 /* XXX, FIXME: The stack space allocated this way is too long lived,
1097 but there is no allocation routine that allocates at the level of
1098 the last binding contour. */
1099 buf = assign_stack_local (BLKmode,
1100 GET_MODE_SIZE (Pmode)*(size+1),
1101 0);
1102
1103 buf = change_address (buf, Pmode, NULL_RTX);
1104
1105 /* Store dcc into the first word of the newly allocated buffer. */
1106
1107 dcc = get_dynamic_cleanup_chain ();
1108 emit_move_insn (buf, dcc);
1109
1110 /* Store func and arg into the cleanup list element. */
1111
38a448ca
RH
1112 new_func = gen_rtx_MEM (Pmode, plus_constant (XEXP (buf, 0),
1113 GET_MODE_SIZE (Pmode)));
1114 new_arg = gen_rtx_MEM (Pmode, plus_constant (XEXP (buf, 0),
1115 GET_MODE_SIZE (Pmode)*2));
27a36778
MS
1116 x = expand_expr (func, new_func, Pmode, 0);
1117 if (x != new_func)
1118 emit_move_insn (new_func, x);
1119
1120 x = expand_expr (arg, new_arg, Pmode, 0);
1121 if (x != new_arg)
1122 emit_move_insn (new_arg, x);
1123
1124 /* Update the cleanup chain. */
1125
1126 emit_move_insn (dcc, XEXP (buf, 0));
1127}
1128
1129/* Emit RTL to start a dynamic handler on the EH runtime dynamic
1130 handler stack. This should only be used by expand_eh_region_start
1131 or expand_eh_region_start_tree. */
1132
1133static void
1134start_dynamic_handler ()
1135{
1136 rtx dhc, dcc;
6e6a07d2 1137 rtx x, arg, buf;
27a36778
MS
1138 int size;
1139
6e6a07d2 1140#ifndef DONT_USE_BUILTIN_SETJMP
27a36778
MS
1141 /* The number of Pmode words for the setjmp buffer, when using the
1142 builtin setjmp/longjmp, see expand_builtin, case
1143 BUILT_IN_LONGJMP. */
1144 size = 5;
1145#else
1146#ifdef JMP_BUF_SIZE
1147 size = JMP_BUF_SIZE;
1148#else
1149 /* Should be large enough for most systems, if it is not,
1150 JMP_BUF_SIZE should be defined with the proper value. It will
1151 also tend to be larger than necessary for most systems, a more
1152 optimal port will define JMP_BUF_SIZE. */
1153 size = FIRST_PSEUDO_REGISTER+2;
1154#endif
1155#endif
1156 /* XXX, FIXME: The stack space allocated this way is too long lived,
1157 but there is no allocation routine that allocates at the level of
1158 the last binding contour. */
1159 arg = assign_stack_local (BLKmode,
1160 GET_MODE_SIZE (Pmode)*(size+1),
1161 0);
1162
1163 arg = change_address (arg, Pmode, NULL_RTX);
1164
1165 /* Store dhc into the first word of the newly allocated buffer. */
1166
1167 dhc = get_dynamic_handler_chain ();
38a448ca
RH
1168 dcc = gen_rtx_MEM (Pmode, plus_constant (XEXP (arg, 0),
1169 GET_MODE_SIZE (Pmode)));
27a36778
MS
1170 emit_move_insn (arg, dhc);
1171
1172 /* Zero out the start of the cleanup chain. */
1173 emit_move_insn (dcc, const0_rtx);
1174
1175 /* The jmpbuf starts two words into the area allocated. */
6e6a07d2 1176 buf = plus_constant (XEXP (arg, 0), GET_MODE_SIZE (Pmode)*2);
27a36778 1177
6e6a07d2 1178#ifdef DONT_USE_BUILTIN_SETJMP
27a36778 1179 x = emit_library_call_value (setjmp_libfunc, NULL_RTX, 1, SImode, 1,
6e6a07d2 1180 buf, Pmode);
6fd1c67b
RH
1181 /* If we come back here for a catch, transfer control to the handler. */
1182 jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
6e6a07d2 1183#else
6fd1c67b
RH
1184 {
1185 /* A label to continue execution for the no exception case. */
1186 rtx noex = gen_label_rtx();
1187 x = expand_builtin_setjmp (buf, NULL_RTX, noex,
1188 ehstack.top->entry->exception_handler_label);
1189 emit_label (noex);
1190 }
6e6a07d2 1191#endif
27a36778 1192
27a36778
MS
1193 /* We are committed to this, so update the handler chain. */
1194
1195 emit_move_insn (dhc, XEXP (arg, 0));
1196}
1197
1198/* Start an exception handling region for the given cleanup action.
12670d88 1199 All instructions emitted after this point are considered to be part
27a36778
MS
1200 of the region until expand_eh_region_end is invoked. CLEANUP is
1201 the cleanup action to perform. The return value is true if the
1202 exception region was optimized away. If that case,
1203 expand_eh_region_end does not need to be called for this cleanup,
1204 nor should it be.
1205
1206 This routine notices one particular common case in C++ code
1207 generation, and optimizes it so as to not need the exception
1208 region. It works by creating a dynamic cleanup action, instead of
38e01259 1209 a using an exception region. */
27a36778
MS
1210
1211int
4c581243
MS
1212expand_eh_region_start_tree (decl, cleanup)
1213 tree decl;
27a36778
MS
1214 tree cleanup;
1215{
27a36778
MS
1216 /* This is the old code. */
1217 if (! doing_eh (0))
1218 return 0;
1219
1220 /* The optimization only applies to actions protected with
1221 terminate, and only applies if we are using the setjmp/longjmp
1222 codegen method. */
1223 if (exceptions_via_longjmp
1224 && protect_cleanup_actions_with_terminate)
1225 {
1226 tree func, arg;
1227 tree args;
1228
1229 /* Ignore any UNSAVE_EXPR. */
1230 if (TREE_CODE (cleanup) == UNSAVE_EXPR)
1231 cleanup = TREE_OPERAND (cleanup, 0);
1232
1233 /* Further, it only applies if the action is a call, if there
1234 are 2 arguments, and if the second argument is 2. */
1235
1236 if (TREE_CODE (cleanup) == CALL_EXPR
1237 && (args = TREE_OPERAND (cleanup, 1))
1238 && (func = TREE_OPERAND (cleanup, 0))
1239 && (arg = TREE_VALUE (args))
1240 && (args = TREE_CHAIN (args))
1241
1242 /* is the second argument 2? */
1243 && TREE_CODE (TREE_VALUE (args)) == INTEGER_CST
1244 && TREE_INT_CST_LOW (TREE_VALUE (args)) == 2
1245 && TREE_INT_CST_HIGH (TREE_VALUE (args)) == 0
1246
1247 /* Make sure there are no other arguments. */
1248 && TREE_CHAIN (args) == NULL_TREE)
1249 {
1250 /* Arrange for returns and gotos to pop the entry we make on the
1251 dynamic cleanup stack. */
4c581243 1252 expand_dcc_cleanup (decl);
27a36778
MS
1253 start_dynamic_cleanup (func, arg);
1254 return 1;
1255 }
1256 }
1257
4c581243 1258 expand_eh_region_start_for_decl (decl);
9762d48d 1259 ehstack.top->entry->finalization = cleanup;
27a36778
MS
1260
1261 return 0;
1262}
1263
4c581243
MS
1264/* Just like expand_eh_region_start, except if a cleanup action is
1265 entered on the cleanup chain, the TREE_PURPOSE of the element put
1266 on the chain is DECL. DECL should be the associated VAR_DECL, if
1267 any, otherwise it should be NULL_TREE. */
4956d07c
MS
1268
1269void
4c581243
MS
1270expand_eh_region_start_for_decl (decl)
1271 tree decl;
4956d07c
MS
1272{
1273 rtx note;
1274
1275 /* This is the old code. */
1276 if (! doing_eh (0))
1277 return;
1278
27a36778
MS
1279 if (exceptions_via_longjmp)
1280 {
1281 /* We need a new block to record the start and end of the
1282 dynamic handler chain. We could always do this, but we
1283 really want to permit jumping into such a block, and we want
1284 to avoid any errors or performance impact in the SJ EH code
1285 for now. */
1286 expand_start_bindings (0);
1287
1288 /* But we don't need or want a new temporary level. */
1289 pop_temp_slots ();
1290
1291 /* Mark this block as created by expand_eh_region_start. This
1292 is so that we can pop the block with expand_end_bindings
1293 automatically. */
1294 mark_block_as_eh_region ();
1295
1296 /* Arrange for returns and gotos to pop the entry we make on the
1297 dynamic handler stack. */
4c581243 1298 expand_dhc_cleanup (decl);
27a36778 1299 }
4956d07c 1300
478b0752 1301 push_eh_entry (&ehstack);
9ad8a5f0
MS
1302 note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_BEG);
1303 NOTE_BLOCK_NUMBER (note)
1304 = CODE_LABEL_NUMBER (ehstack.top->entry->exception_handler_label);
27a36778
MS
1305 if (exceptions_via_longjmp)
1306 start_dynamic_handler ();
4956d07c
MS
1307}
1308
4c581243
MS
1309/* Start an exception handling region. All instructions emitted after
1310 this point are considered to be part of the region until
1311 expand_eh_region_end is invoked. */
1312
1313void
1314expand_eh_region_start ()
1315{
1316 expand_eh_region_start_for_decl (NULL_TREE);
1317}
1318
27a36778
MS
1319/* End an exception handling region. The information about the region
1320 is found on the top of ehstack.
12670d88
RK
1321
1322 HANDLER is either the cleanup for the exception region, or if we're
1323 marking the end of a try block, HANDLER is integer_zero_node.
1324
27a36778 1325 HANDLER will be transformed to rtl when expand_leftover_cleanups
abeeec2a 1326 is invoked. */
4956d07c
MS
1327
1328void
1329expand_eh_region_end (handler)
1330 tree handler;
1331{
4956d07c 1332 struct eh_entry *entry;
9ad8a5f0 1333 rtx note;
4956d07c
MS
1334
1335 if (! doing_eh (0))
1336 return;
1337
1338 entry = pop_eh_entry (&ehstack);
1339
9ad8a5f0
MS
1340 note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END);
1341 NOTE_BLOCK_NUMBER (note)
1342 = CODE_LABEL_NUMBER (entry->exception_handler_label);
e701eb4d
JM
1343 if (exceptions_via_longjmp == 0
1344 /* We share outer_context between regions; only emit it once. */
1345 && INSN_UID (entry->outer_context) == 0)
27a36778 1346 {
478b0752 1347 rtx label;
4956d07c 1348
478b0752
MS
1349 label = gen_label_rtx ();
1350 emit_jump (label);
1351
1352 /* Emit a label marking the end of this exception region that
1353 is used for rethrowing into the outer context. */
1354 emit_label (entry->outer_context);
e701eb4d 1355 expand_internal_throw ();
4956d07c 1356
478b0752 1357 emit_label (label);
27a36778 1358 }
4956d07c
MS
1359
1360 entry->finalization = handler;
1361
9a0d1e1b
AM
1362 /* create region entry in final exception table */
1363 new_eh_region_entry (NOTE_BLOCK_NUMBER (note));
1364
4956d07c
MS
1365 enqueue_eh_entry (&ehqueue, entry);
1366
27a36778
MS
1367 /* If we have already started ending the bindings, don't recurse.
1368 This only happens when exceptions_via_longjmp is true. */
1369 if (is_eh_region ())
1370 {
1371 /* Because we don't need or want a new temporary level and
1372 because we didn't create one in expand_eh_region_start,
1373 create a fake one now to avoid removing one in
1374 expand_end_bindings. */
1375 push_temp_slots ();
1376
1377 mark_block_as_not_eh_region ();
1378
1379 /* Maybe do this to prevent jumping in and so on... */
1380 expand_end_bindings (NULL_TREE, 0, 0);
1381 }
4956d07c
MS
1382}
1383
9762d48d
JM
1384/* End the EH region for a goto fixup. We only need them in the region-based
1385 EH scheme. */
1386
1387void
1388expand_fixup_region_start ()
1389{
1390 if (! doing_eh (0) || exceptions_via_longjmp)
1391 return;
1392
1393 expand_eh_region_start ();
1394}
1395
1396/* End the EH region for a goto fixup. CLEANUP is the cleanup we just
1397 expanded; to avoid running it twice if it throws, we look through the
1398 ehqueue for a matching region and rethrow from its outer_context. */
1399
1400void
1401expand_fixup_region_end (cleanup)
1402 tree cleanup;
1403{
9762d48d 1404 struct eh_node *node;
9762d48d
JM
1405
1406 if (! doing_eh (0) || exceptions_via_longjmp)
1407 return;
1408
1409 for (node = ehstack.top; node && node->entry->finalization != cleanup; )
1410 node = node->chain;
1411 if (node == 0)
1412 for (node = ehqueue.head; node && node->entry->finalization != cleanup; )
1413 node = node->chain;
1414 if (node == 0)
1415 abort ();
1416
e701eb4d 1417 ehstack.top->entry->outer_context = node->entry->outer_context;
9762d48d 1418
e701eb4d
JM
1419 /* Just rethrow. size_zero_node is just a NOP. */
1420 expand_eh_region_end (size_zero_node);
9762d48d
JM
1421}
1422
27a36778
MS
1423/* If we are using the setjmp/longjmp EH codegen method, we emit a
1424 call to __sjthrow.
1425
1426 Otherwise, we emit a call to __throw and note that we threw
1427 something, so we know we need to generate the necessary code for
1428 __throw.
12670d88
RK
1429
1430 Before invoking throw, the __eh_pc variable must have been set up
1431 to contain the PC being thrown from. This address is used by
27a36778 1432 __throw to determine which exception region (if any) is
abeeec2a 1433 responsible for handling the exception. */
4956d07c 1434
27a36778 1435void
4956d07c
MS
1436emit_throw ()
1437{
27a36778
MS
1438 if (exceptions_via_longjmp)
1439 {
1440 emit_library_call (sjthrow_libfunc, 0, VOIDmode, 0);
1441 }
1442 else
1443 {
4956d07c 1444#ifdef JUMP_TO_THROW
27a36778 1445 emit_indirect_jump (throw_libfunc);
4956d07c 1446#else
27a36778 1447 emit_library_call (throw_libfunc, 0, VOIDmode, 0);
4956d07c 1448#endif
27a36778 1449 }
4956d07c
MS
1450 emit_barrier ();
1451}
1452
e701eb4d
JM
1453/* Throw the current exception. If appropriate, this is done by jumping
1454 to the next handler. */
4956d07c
MS
1455
1456void
e701eb4d 1457expand_internal_throw ()
4956d07c 1458{
e701eb4d 1459 emit_throw ();
4956d07c
MS
1460}
1461
1462/* Called from expand_exception_blocks and expand_end_catch_block to
27a36778 1463 emit any pending handlers/cleanups queued from expand_eh_region_end. */
4956d07c
MS
1464
1465void
1466expand_leftover_cleanups ()
1467{
1468 struct eh_entry *entry;
1469
1470 while ((entry = dequeue_eh_entry (&ehqueue)) != 0)
1471 {
1472 rtx prev;
1473
12670d88
RK
1474 /* A leftover try block. Shouldn't be one here. */
1475 if (entry->finalization == integer_zero_node)
1476 abort ();
1477
abeeec2a 1478 /* Output the label for the start of the exception handler. */
4956d07c 1479
9a0d1e1b 1480 receive_exception_label (entry->exception_handler_label);
f51430ed 1481
9a0d1e1b
AM
1482 /* register a handler for this cleanup region */
1483 add_new_handler (
1484 find_func_region (CODE_LABEL_NUMBER (entry->exception_handler_label)),
1485 get_new_handler (entry->exception_handler_label, NULL));
05f5b2cd 1486
abeeec2a 1487 /* And now generate the insns for the handler. */
4956d07c
MS
1488 expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
1489
1490 prev = get_last_insn ();
27a36778 1491 if (prev == NULL || GET_CODE (prev) != BARRIER)
e701eb4d
JM
1492 /* Emit code to throw to the outer context if we fall off
1493 the end of the handler. */
1494 expand_rethrow (entry->outer_context);
4956d07c 1495
c7ae64f2 1496 do_pending_stack_adjust ();
4956d07c
MS
1497 free (entry);
1498 }
1499}
1500
abeeec2a 1501/* Called at the start of a block of try statements. */
12670d88
RK
1502void
1503expand_start_try_stmts ()
1504{
1505 if (! doing_eh (1))
1506 return;
1507
1508 expand_eh_region_start ();
1509}
1510
9a0d1e1b
AM
1511/* Called to begin a catch clause. The parameter is the object which
1512 will be passed to the runtime type check routine. */
1513void
1514expand_start_catch (rtime)
1515 tree rtime;
1516{
1517 rtx handler_label = catchstack.top->entry->exception_handler_label;
1518 int insn_region_num = CODE_LABEL_NUMBER (handler_label);
1519 int eh_region_entry = find_func_region (insn_region_num);
1520
1521 /* If we've already issued this label, pick a new one */
7ecb5d27 1522 if (catchstack.top->entry->label_used)
9a0d1e1b
AM
1523 handler_label = gen_exception_label ();
1524 else
1525 catchstack.top->entry->label_used = 1;
1526
1527 receive_exception_label (handler_label);
1528
1529 add_new_handler (eh_region_entry, get_new_handler (handler_label, rtime));
1530}
1531
1532/* End a catch clause by dequeuing the current region */
1533
1534void
1535expand_end_catch ()
1536{
1537 struct eh_entry *entry;
1538 entry = pop_eh_entry (&catchstack);
1539 free (entry);
1540}
1541
12670d88
RK
1542/* Generate RTL for the start of a group of catch clauses.
1543
1544 It is responsible for starting a new instruction sequence for the
1545 instructions in the catch block, and expanding the handlers for the
1546 internally-generated exception regions nested within the try block
abeeec2a 1547 corresponding to this catch block. */
4956d07c
MS
1548
1549void
1550expand_start_all_catch ()
1551{
1552 struct eh_entry *entry;
1553 tree label;
e701eb4d 1554 rtx outer_context;
4956d07c
MS
1555
1556 if (! doing_eh (1))
1557 return;
1558
e701eb4d 1559 outer_context = ehstack.top->entry->outer_context;
1418bb67 1560
abeeec2a 1561 /* End the try block. */
12670d88
RK
1562 expand_eh_region_end (integer_zero_node);
1563
4956d07c
MS
1564 emit_line_note (input_filename, lineno);
1565 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1566
12670d88 1567 /* The label for the exception handling block that we will save.
956d6950 1568 This is Lresume in the documentation. */
4956d07c
MS
1569 expand_label (label);
1570
12670d88 1571 /* Push the label that points to where normal flow is resumed onto
abeeec2a 1572 the top of the label stack. */
4956d07c
MS
1573 push_label_entry (&caught_return_label_stack, NULL_RTX, label);
1574
1575 /* Start a new sequence for all the catch blocks. We will add this
12670d88 1576 to the global sequence catch_clauses when we have completed all
4956d07c
MS
1577 the handlers in this handler-seq. */
1578 start_sequence ();
1579
9a0d1e1b
AM
1580 entry = dequeue_eh_entry (&ehqueue);
1581 for ( ; entry->finalization != integer_zero_node;
1582 entry = dequeue_eh_entry (&ehqueue))
4956d07c
MS
1583 {
1584 rtx prev;
1585
9a0d1e1b 1586 /* Emit the label for the cleanup handler for this region, and
12670d88
RK
1587 expand the code for the handler.
1588
1589 Note that a catch region is handled as a side-effect here;
1590 for a try block, entry->finalization will contain
1591 integer_zero_node, so no code will be generated in the
1592 expand_expr call below. But, the label for the handler will
1593 still be emitted, so any code emitted after this point will
abeeec2a 1594 end up being the handler. */
9a0d1e1b
AM
1595
1596 receive_exception_label (entry->exception_handler_label);
05f5b2cd 1597
9a0d1e1b
AM
1598 /* register a handler for this cleanup region */
1599 add_new_handler (
1600 find_func_region (CODE_LABEL_NUMBER (entry->exception_handler_label)),
1601 get_new_handler (entry->exception_handler_label, NULL));
4956d07c 1602
9a0d1e1b 1603 /* And now generate the insns for the cleanup handler. */
27a36778
MS
1604 expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
1605
4956d07c 1606 prev = get_last_insn ();
12670d88 1607 if (prev == NULL || GET_CODE (prev) != BARRIER)
e701eb4d
JM
1608 /* Code to throw out to outer context when we fall off end
1609 of the handler. We can't do this here for catch blocks,
1610 so it's done in expand_end_all_catch instead. */
1611 expand_rethrow (entry->outer_context);
12670d88 1612
f45ebe47 1613 do_pending_stack_adjust ();
4956d07c
MS
1614 free (entry);
1615 }
e701eb4d 1616
9a0d1e1b
AM
1617 /* At this point, all the cleanups are done, and the ehqueue now has
1618 the current exception region at its head. We dequeue it, and put it
1619 on the catch stack. */
1620
1621 push_entry (&catchstack, entry);
1622
e701eb4d
JM
1623 /* If we are not doing setjmp/longjmp EH, because we are reordered
1624 out of line, we arrange to rethrow in the outer context. We need to
1625 do this because we are not physically within the region, if any, that
1626 logically contains this catch block. */
1627 if (! exceptions_via_longjmp)
1628 {
1629 expand_eh_region_start ();
1630 ehstack.top->entry->outer_context = outer_context;
1631 }
4956d07c
MS
1632}
1633
12670d88
RK
1634/* Finish up the catch block. At this point all the insns for the
1635 catch clauses have already been generated, so we only have to add
1636 them to the catch_clauses list. We also want to make sure that if
1637 we fall off the end of the catch clauses that we rethrow to the
abeeec2a 1638 outer EH region. */
4956d07c
MS
1639
1640void
1641expand_end_all_catch ()
1642{
5dfa7520 1643 rtx new_catch_clause, outer_context = NULL_RTX;
4956d07c
MS
1644
1645 if (! doing_eh (1))
1646 return;
1647
e701eb4d 1648 if (! exceptions_via_longjmp)
5dfa7520
JM
1649 {
1650 outer_context = ehstack.top->entry->outer_context;
1651
1652 /* Finish the rethrow region. size_zero_node is just a NOP. */
1653 expand_eh_region_end (size_zero_node);
1654 }
1655
e701eb4d
JM
1656 /* Code to throw out to outer context, if we fall off end of catch
1657 handlers. This is rethrow (Lresume, same id, same obj) in the
1658 documentation. We use Lresume because we know that it will throw
1659 to the correct context.
12670d88 1660
e701eb4d
JM
1661 In other words, if the catch handler doesn't exit or return, we
1662 do a "throw" (using the address of Lresume as the point being
1663 thrown from) so that the outer EH region can then try to process
1664 the exception. */
1665 expand_rethrow (outer_context);
4956d07c
MS
1666
1667 /* Now we have the complete catch sequence. */
1668 new_catch_clause = get_insns ();
1669 end_sequence ();
1670
1671 /* This level of catch blocks is done, so set up the successful
1672 catch jump label for the next layer of catch blocks. */
1673 pop_label_entry (&caught_return_label_stack);
956d6950 1674 pop_label_entry (&outer_context_label_stack);
4956d07c
MS
1675
1676 /* Add the new sequence of catches to the main one for this function. */
1677 push_to_sequence (catch_clauses);
1678 emit_insns (new_catch_clause);
1679 catch_clauses = get_insns ();
1680 end_sequence ();
1681
1682 /* Here we fall through into the continuation code. */
1683}
1684
e701eb4d
JM
1685/* Rethrow from the outer context LABEL. */
1686
1687static void
1688expand_rethrow (label)
1689 rtx label;
1690{
1691 if (exceptions_via_longjmp)
1692 emit_throw ();
1693 else
1694 emit_jump (label);
1695}
1696
12670d88 1697/* End all the pending exception regions on protect_list. The handlers
27a36778 1698 will be emitted when expand_leftover_cleanups is invoked. */
4956d07c
MS
1699
1700void
1701end_protect_partials ()
1702{
1703 while (protect_list)
1704 {
1705 expand_eh_region_end (TREE_VALUE (protect_list));
1706 protect_list = TREE_CHAIN (protect_list);
1707 }
1708}
27a36778
MS
1709
1710/* Arrange for __terminate to be called if there is an unhandled throw
1711 from within E. */
1712
1713tree
1714protect_with_terminate (e)
1715 tree e;
1716{
1717 /* We only need to do this when using setjmp/longjmp EH and the
1718 language requires it, as otherwise we protect all of the handlers
1719 at once, if we need to. */
1720 if (exceptions_via_longjmp && protect_cleanup_actions_with_terminate)
1721 {
1722 tree handler, result;
1723
1724 /* All cleanups must be on the function_obstack. */
1725 push_obstacks_nochange ();
1726 resume_temporary_allocation ();
1727
1728 handler = make_node (RTL_EXPR);
1729 TREE_TYPE (handler) = void_type_node;
1730 RTL_EXPR_RTL (handler) = const0_rtx;
1731 TREE_SIDE_EFFECTS (handler) = 1;
1732 start_sequence_for_rtl_expr (handler);
1733
1734 emit_library_call (terminate_libfunc, 0, VOIDmode, 0);
1735 emit_barrier ();
1736
1737 RTL_EXPR_SEQUENCE (handler) = get_insns ();
1738 end_sequence ();
1739
1740 result = build (TRY_CATCH_EXPR, TREE_TYPE (e), e, handler);
1741 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e);
1742 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
1743 TREE_READONLY (result) = TREE_READONLY (e);
1744
1745 pop_obstacks ();
1746
1747 e = result;
1748 }
1749
1750 return e;
1751}
4956d07c
MS
1752\f
1753/* The exception table that we build that is used for looking up and
12670d88
RK
1754 dispatching exceptions, the current number of entries, and its
1755 maximum size before we have to extend it.
1756
1757 The number in eh_table is the code label number of the exception
27a36778
MS
1758 handler for the region. This is added by add_eh_table_entry and
1759 used by output_exception_table_entry. */
12670d88 1760
9a0d1e1b
AM
1761static int *eh_table = NULL;
1762static int eh_table_size = 0;
1763static int eh_table_max_size = 0;
4956d07c
MS
1764
1765/* Note the need for an exception table entry for region N. If we
12670d88
RK
1766 don't need to output an explicit exception table, avoid all of the
1767 extra work.
1768
1769 Called from final_scan_insn when a NOTE_INSN_EH_REGION_BEG is seen.
9a0d1e1b 1770 (Or NOTE_INSN_EH_REGION_END sometimes)
12670d88 1771 N is the NOTE_BLOCK_NUMBER of the note, which comes from the code
abeeec2a 1772 label number of the exception handler for the region. */
4956d07c
MS
1773
1774void
1775add_eh_table_entry (n)
1776 int n;
1777{
1778#ifndef OMIT_EH_TABLE
1779 if (eh_table_size >= eh_table_max_size)
1780 {
1781 if (eh_table)
1782 {
1783 eh_table_max_size += eh_table_max_size>>1;
1784
1785 if (eh_table_max_size < 0)
1786 abort ();
1787
ca55abae
JM
1788 eh_table = (int *) xrealloc (eh_table,
1789 eh_table_max_size * sizeof (int));
4956d07c
MS
1790 }
1791 else
1792 {
1793 eh_table_max_size = 252;
1794 eh_table = (int *) xmalloc (eh_table_max_size * sizeof (int));
1795 }
1796 }
1797 eh_table[eh_table_size++] = n;
1798#endif
1799}
1800
12670d88
RK
1801/* Return a non-zero value if we need to output an exception table.
1802
1803 On some platforms, we don't have to output a table explicitly.
1804 This routine doesn't mean we don't have one. */
4956d07c
MS
1805
1806int
1807exception_table_p ()
1808{
1809 if (eh_table)
1810 return 1;
1811
1812 return 0;
1813}
1814
38e01259 1815/* Output the entry of the exception table corresponding to the
12670d88
RK
1816 exception region numbered N to file FILE.
1817
1818 N is the code label number corresponding to the handler of the
abeeec2a 1819 region. */
4956d07c
MS
1820
1821static void
1822output_exception_table_entry (file, n)
1823 FILE *file;
1824 int n;
1825{
1826 char buf[256];
1827 rtx sym;
9a0d1e1b
AM
1828 struct handler_info *handler;
1829
1830 handler = get_first_handler (n);
4956d07c 1831
9a0d1e1b
AM
1832 for ( ; handler != NULL; handler = handler->next)
1833 {
1834 ASM_GENERATE_INTERNAL_LABEL (buf, "LEHB", n);
1835 sym = gen_rtx_SYMBOL_REF (Pmode, buf);
1836 assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
4956d07c 1837
9a0d1e1b
AM
1838 ASM_GENERATE_INTERNAL_LABEL (buf, "LEHE", n);
1839 sym = gen_rtx_SYMBOL_REF (Pmode, buf);
1840 assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
1841
1842 assemble_integer (handler->handler_label,
1843 POINTER_SIZE / BITS_PER_UNIT, 1);
4956d07c 1844
a1622f83
AM
1845 if (flag_new_exceptions)
1846 {
1847 if (handler->type_info == NULL)
1848 assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1849 else
1850 output_constant ((tree)(handler->type_info),
9a0d1e1b 1851 POINTER_SIZE / BITS_PER_UNIT);
a1622f83 1852 }
9a0d1e1b
AM
1853 putc ('\n', file); /* blank line */
1854 }
4956d07c
MS
1855}
1856
abeeec2a 1857/* Output the exception table if we have and need one. */
4956d07c 1858
9a0d1e1b
AM
1859static short language_code = 0;
1860static short version_code = 0;
1861
1862/* This routine will set the language code for exceptions. */
1863void set_exception_lang_code (code)
1864 short code;
1865{
1866 language_code = code;
1867}
1868
1869/* This routine will set the language version code for exceptions. */
1870void set_exception_version_code (code)
1871 short code;
1872{
1873 version_code = code;
1874}
1875
9a0d1e1b 1876
4956d07c
MS
1877void
1878output_exception_table ()
1879{
1880 int i;
1881 extern FILE *asm_out_file;
1882
ca55abae 1883 if (! doing_eh (0) || ! eh_table)
4956d07c
MS
1884 return;
1885
1886 exception_section ();
1887
1888 /* Beginning marker for table. */
1889 assemble_align (GET_MODE_ALIGNMENT (ptr_mode));
1890 assemble_label ("__EXCEPTION_TABLE__");
1891
a1622f83
AM
1892 if (flag_new_exceptions)
1893 {
1894 assemble_integer (GEN_INT (NEW_EH_RUNTIME),
1895 POINTER_SIZE / BITS_PER_UNIT, 1);
1896 assemble_integer (GEN_INT (language_code), 2 , 1);
1897 assemble_integer (GEN_INT (version_code), 2 , 1);
1898
1899 /* Add enough padding to make sure table aligns on a pointer boundry. */
1900 i = GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT - 4;
1901 for ( ; i < 0; i = i + GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT)
1902 ;
1903 if (i != 0)
1904 assemble_integer (const0_rtx, i , 1);
1905 }
9a0d1e1b 1906
4956d07c
MS
1907 for (i = 0; i < eh_table_size; ++i)
1908 output_exception_table_entry (asm_out_file, eh_table[i]);
1909
1910 free (eh_table);
9a0d1e1b 1911 clear_function_eh_region ();
4956d07c
MS
1912
1913 /* Ending marker for table. */
4956d07c 1914 assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
a1622f83 1915
9a0d1e1b
AM
1916 /* for binary compatability, the old __throw checked the second
1917 position for a -1, so we should output at least 2 -1's */
a1622f83
AM
1918 if (! flag_new_exceptions)
1919 assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1920
4956d07c
MS
1921 putc ('\n', asm_out_file); /* blank line */
1922}
4956d07c 1923\f
154bba13
TT
1924/* Emit code to get EH context.
1925
1926 We have to scan thru the code to find possible EH context registers.
1927 Inlined functions may use it too, and thus we'll have to be able
1928 to change them too.
1929
1930 This is done only if using exceptions_via_longjmp. */
1931
1932void
1933emit_eh_context ()
1934{
1935 rtx insn;
1936 rtx ehc = 0;
1937
1938 if (! doing_eh (0))
1939 return;
1940
1941 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1942 if (GET_CODE (insn) == INSN
1943 && GET_CODE (PATTERN (insn)) == USE)
1944 {
1945 rtx reg = find_reg_note (insn, REG_EH_CONTEXT, 0);
1946 if (reg)
1947 {
1948 rtx insns;
1949
100d81d4
JM
1950 start_sequence ();
1951
d9c92f32
JM
1952 /* If this is the first use insn, emit the call here. This
1953 will always be at the top of our function, because if
1954 expand_inline_function notices a REG_EH_CONTEXT note, it
1955 adds a use insn to this function as well. */
154bba13 1956 if (ehc == 0)
01eb7f9a 1957 ehc = call_get_eh_context ();
154bba13 1958
154bba13
TT
1959 emit_move_insn (XEXP (reg, 0), ehc);
1960 insns = get_insns ();
1961 end_sequence ();
1962
1963 emit_insns_before (insns, insn);
1964 }
1965 }
1966}
1967
12670d88
RK
1968/* Scan the current insns and build a list of handler labels. The
1969 resulting list is placed in the global variable exception_handler_labels.
1970
1971 It is called after the last exception handling region is added to
1972 the current function (when the rtl is almost all built for the
1973 current function) and before the jump optimization pass. */
4956d07c
MS
1974
1975void
1976find_exception_handler_labels ()
1977{
1978 rtx insn;
4956d07c
MS
1979
1980 exception_handler_labels = NULL_RTX;
1981
1982 /* If we aren't doing exception handling, there isn't much to check. */
1983 if (! doing_eh (0))
1984 return;
1985
12670d88
RK
1986 /* For each start of a region, add its label to the list. */
1987
4956d07c
MS
1988 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1989 {
9a0d1e1b 1990 struct handler_info* ptr;
4956d07c
MS
1991 if (GET_CODE (insn) == NOTE
1992 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
1993 {
9a0d1e1b
AM
1994 ptr = get_first_handler (NOTE_BLOCK_NUMBER (insn));
1995 for ( ; ptr; ptr = ptr->next)
1996 {
1997 /* make sure label isn't in the list already */
1998 rtx x;
1999 for (x = exception_handler_labels; x; x = XEXP (x, 1))
2000 if (XEXP (x, 0) == ptr->handler_label)
2001 break;
2002 if (! x)
2003 exception_handler_labels = gen_rtx_EXPR_LIST (VOIDmode,
2004 ptr->handler_label, exception_handler_labels);
2005 }
4956d07c
MS
2006 }
2007 }
9a0d1e1b
AM
2008}
2009
2010/* Return a value of 1 if the parameter label number is an exception handler
2011 label. Return 0 otherwise. */
988cea7d 2012
9a0d1e1b
AM
2013int
2014is_exception_handler_label (lab)
2015 int lab;
2016{
2017 rtx x;
2018 for (x = exception_handler_labels ; x ; x = XEXP (x, 1))
2019 if (lab == CODE_LABEL_NUMBER (XEXP (x, 0)))
2020 return 1;
2021 return 0;
4956d07c
MS
2022}
2023
12670d88
RK
2024/* Perform sanity checking on the exception_handler_labels list.
2025
2026 Can be called after find_exception_handler_labels is called to
2027 build the list of exception handlers for the current function and
2028 before we finish processing the current function. */
4956d07c
MS
2029
2030void
2031check_exception_handler_labels ()
2032{
9a0d1e1b 2033 rtx insn, insn2;
4956d07c
MS
2034
2035 /* If we aren't doing exception handling, there isn't much to check. */
2036 if (! doing_eh (0))
2037 return;
2038
9a0d1e1b
AM
2039 /* Make sure there is no more than 1 copy of a label */
2040 for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1))
4956d07c 2041 {
9a0d1e1b
AM
2042 int count = 0;
2043 for (insn2 = exception_handler_labels; insn2; insn2 = XEXP (insn2, 1))
2044 if (XEXP (insn, 0) == XEXP (insn2, 0))
2045 count++;
2046 if (count != 1)
2047 warning ("Counted %d copies of EH region %d in list.\n", count,
2048 CODE_LABEL_NUMBER (insn));
4956d07c
MS
2049 }
2050
4956d07c
MS
2051}
2052\f
2053/* This group of functions initializes the exception handling data
2054 structures at the start of the compilation, initializes the data
12670d88 2055 structures at the start of a function, and saves and restores the
4956d07c
MS
2056 exception handling data structures for the start/end of a nested
2057 function. */
2058
2059/* Toplevel initialization for EH things. */
2060
2061void
2062init_eh ()
2063{
4956d07c
MS
2064}
2065
abeeec2a 2066/* Initialize the per-function EH information. */
4956d07c
MS
2067
2068void
2069init_eh_for_function ()
2070{
2071 ehstack.top = 0;
9a0d1e1b 2072 catchstack.top = 0;
4956d07c
MS
2073 ehqueue.head = ehqueue.tail = 0;
2074 catch_clauses = NULL_RTX;
2075 false_label_stack = 0;
2076 caught_return_label_stack = 0;
2077 protect_list = NULL_TREE;
154bba13 2078 current_function_ehc = NULL_RTX;
4956d07c
MS
2079}
2080
12670d88
RK
2081/* Save some of the per-function EH info into the save area denoted by
2082 P.
2083
27a36778 2084 This is currently called from save_stmt_status. */
4956d07c
MS
2085
2086void
2087save_eh_status (p)
2088 struct function *p;
2089{
3a88cbd1
JL
2090 if (p == NULL)
2091 abort ();
12670d88 2092
4956d07c 2093 p->ehstack = ehstack;
9a0d1e1b 2094 p->catchstack = catchstack;
4956d07c
MS
2095 p->ehqueue = ehqueue;
2096 p->catch_clauses = catch_clauses;
2097 p->false_label_stack = false_label_stack;
2098 p->caught_return_label_stack = caught_return_label_stack;
2099 p->protect_list = protect_list;
154bba13 2100 p->ehc = current_function_ehc;
4956d07c 2101
6e1f1f93 2102 init_eh_for_function ();
4956d07c
MS
2103}
2104
12670d88
RK
2105/* Restore the per-function EH info saved into the area denoted by P.
2106
abeeec2a 2107 This is currently called from restore_stmt_status. */
4956d07c
MS
2108
2109void
2110restore_eh_status (p)
2111 struct function *p;
2112{
3a88cbd1
JL
2113 if (p == NULL)
2114 abort ();
12670d88 2115
4956d07c
MS
2116 protect_list = p->protect_list;
2117 caught_return_label_stack = p->caught_return_label_stack;
2118 false_label_stack = p->false_label_stack;
2119 catch_clauses = p->catch_clauses;
2120 ehqueue = p->ehqueue;
2121 ehstack = p->ehstack;
9a0d1e1b 2122 catchstack = p->catchstack;
154bba13 2123 current_function_ehc = p->ehc;
4956d07c
MS
2124}
2125\f
2126/* This section is for the exception handling specific optimization
2127 pass. First are the internal routines, and then the main
2128 optimization pass. */
2129
2130/* Determine if the given INSN can throw an exception. */
2131
2132static int
2133can_throw (insn)
2134 rtx insn;
2135{
abeeec2a 2136 /* Calls can always potentially throw exceptions. */
4956d07c
MS
2137 if (GET_CODE (insn) == CALL_INSN)
2138 return 1;
2139
27a36778
MS
2140 if (asynchronous_exceptions)
2141 {
2142 /* If we wanted asynchronous exceptions, then everything but NOTEs
2143 and CODE_LABELs could throw. */
2144 if (GET_CODE (insn) != NOTE && GET_CODE (insn) != CODE_LABEL)
2145 return 1;
2146 }
4956d07c
MS
2147
2148 return 0;
2149}
2150
12670d88
RK
2151/* Scan a exception region looking for the matching end and then
2152 remove it if possible. INSN is the start of the region, N is the
2153 region number, and DELETE_OUTER is to note if anything in this
2154 region can throw.
2155
2156 Regions are removed if they cannot possibly catch an exception.
27a36778 2157 This is determined by invoking can_throw on each insn within the
12670d88
RK
2158 region; if can_throw returns true for any of the instructions, the
2159 region can catch an exception, since there is an insn within the
2160 region that is capable of throwing an exception.
2161
2162 Returns the NOTE_INSN_EH_REGION_END corresponding to this region, or
27a36778 2163 calls abort if it can't find one.
12670d88
RK
2164
2165 Can abort if INSN is not a NOTE_INSN_EH_REGION_BEGIN, or if N doesn't
abeeec2a 2166 correspond to the region number, or if DELETE_OUTER is NULL. */
4956d07c
MS
2167
2168static rtx
2169scan_region (insn, n, delete_outer)
2170 rtx insn;
2171 int n;
2172 int *delete_outer;
2173{
2174 rtx start = insn;
2175
2176 /* Assume we can delete the region. */
2177 int delete = 1;
2178
3a88cbd1
JL
2179 if (insn == NULL_RTX
2180 || GET_CODE (insn) != NOTE
2181 || NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG
2182 || NOTE_BLOCK_NUMBER (insn) != n
2183 || delete_outer == NULL)
2184 abort ();
12670d88 2185
4956d07c
MS
2186 insn = NEXT_INSN (insn);
2187
2188 /* Look for the matching end. */
2189 while (! (GET_CODE (insn) == NOTE
2190 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
2191 {
2192 /* If anything can throw, we can't remove the region. */
2193 if (delete && can_throw (insn))
2194 {
2195 delete = 0;
2196 }
2197
2198 /* Watch out for and handle nested regions. */
2199 if (GET_CODE (insn) == NOTE
2200 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
2201 {
2202 insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &delete);
2203 }
2204
2205 insn = NEXT_INSN (insn);
2206 }
2207
2208 /* The _BEG/_END NOTEs must match and nest. */
2209 if (NOTE_BLOCK_NUMBER (insn) != n)
2210 abort ();
2211
12670d88 2212 /* If anything in this exception region can throw, we can throw. */
4956d07c
MS
2213 if (! delete)
2214 *delete_outer = 0;
2215 else
2216 {
2217 /* Delete the start and end of the region. */
2218 delete_insn (start);
2219 delete_insn (insn);
2220
9a0d1e1b
AM
2221/* We no longer removed labels here, since flow will now remove any
2222 handler which cannot be called any more. */
2223
2224#if 0
4956d07c
MS
2225 /* Only do this part if we have built the exception handler
2226 labels. */
2227 if (exception_handler_labels)
2228 {
2229 rtx x, *prev = &exception_handler_labels;
2230
2231 /* Find it in the list of handlers. */
2232 for (x = exception_handler_labels; x; x = XEXP (x, 1))
2233 {
2234 rtx label = XEXP (x, 0);
2235 if (CODE_LABEL_NUMBER (label) == n)
2236 {
2237 /* If we are the last reference to the handler,
2238 delete it. */
2239 if (--LABEL_NUSES (label) == 0)
2240 delete_insn (label);
2241
2242 if (optimize)
2243 {
2244 /* Remove it from the list of exception handler
2245 labels, if we are optimizing. If we are not, then
2246 leave it in the list, as we are not really going to
2247 remove the region. */
2248 *prev = XEXP (x, 1);
2249 XEXP (x, 1) = 0;
2250 XEXP (x, 0) = 0;
2251 }
2252
2253 break;
2254 }
2255 prev = &XEXP (x, 1);
2256 }
2257 }
9a0d1e1b 2258#endif
4956d07c
MS
2259 }
2260 return insn;
2261}
2262
2263/* Perform various interesting optimizations for exception handling
2264 code.
2265
12670d88
RK
2266 We look for empty exception regions and make them go (away). The
2267 jump optimization code will remove the handler if nothing else uses
abeeec2a 2268 it. */
4956d07c
MS
2269
2270void
2271exception_optimize ()
2272{
381127e8 2273 rtx insn;
4956d07c
MS
2274 int n;
2275
12670d88 2276 /* Remove empty regions. */
4956d07c
MS
2277 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2278 {
2279 if (GET_CODE (insn) == NOTE
2280 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
2281 {
27a36778 2282 /* Since scan_region will return the NOTE_INSN_EH_REGION_END
12670d88
RK
2283 insn, we will indirectly skip through all the insns
2284 inbetween. We are also guaranteed that the value of insn
27a36778 2285 returned will be valid, as otherwise scan_region won't
abeeec2a 2286 return. */
4956d07c
MS
2287 insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &n);
2288 }
2289 }
2290}
ca55abae
JM
2291\f
2292/* Various hooks for the DWARF 2 __throw routine. */
2293
2294/* Do any necessary initialization to access arbitrary stack frames.
2295 On the SPARC, this means flushing the register windows. */
2296
2297void
2298expand_builtin_unwind_init ()
2299{
2300 /* Set this so all the registers get saved in our frame; we need to be
2301 able to copy the saved values for any registers from frames we unwind. */
2302 current_function_has_nonlocal_label = 1;
2303
2304#ifdef SETUP_FRAME_ADDRESSES
2305 SETUP_FRAME_ADDRESSES ();
2306#endif
2307}
2308
2309/* Given a value extracted from the return address register or stack slot,
2310 return the actual address encoded in that value. */
2311
2312rtx
2313expand_builtin_extract_return_addr (addr_tree)
2314 tree addr_tree;
2315{
2316 rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
2317 return eh_outer_context (addr);
2318}
2319
2320/* Given an actual address in addr_tree, do any necessary encoding
2321 and return the value to be stored in the return address register or
2322 stack slot so the epilogue will return to that address. */
2323
2324rtx
2325expand_builtin_frob_return_addr (addr_tree)
2326 tree addr_tree;
2327{
2328 rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
2329#ifdef RETURN_ADDR_OFFSET
2330 addr = plus_constant (addr, -RETURN_ADDR_OFFSET);
2331#endif
2332 return addr;
2333}
2334
2335/* Given an actual address in addr_tree, set the return address register up
2336 so the epilogue will return to that address. If the return address is
2337 not in a register, do nothing. */
2338
2339void
2340expand_builtin_set_return_addr_reg (addr_tree)
2341 tree addr_tree;
2342{
4f870c04 2343 rtx tmp;
ca55abae
JM
2344 rtx ra = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
2345 0, hard_frame_pointer_rtx);
2346
2347 if (GET_CODE (ra) != REG || REGNO (ra) >= FIRST_PSEUDO_REGISTER)
2348 return;
2349
4f870c04
JM
2350 tmp = force_operand (expand_builtin_frob_return_addr (addr_tree), ra);
2351 if (tmp != ra)
2352 emit_move_insn (ra, tmp);
ca55abae
JM
2353}
2354
2355/* Choose two registers for communication between the main body of
2356 __throw and the stub for adjusting the stack pointer. The first register
2357 is used to pass the address of the exception handler; the second register
2358 is used to pass the stack pointer offset.
2359
2360 For register 1 we use the return value register for a void *.
2361 For register 2 we use the static chain register if it exists and is
2362 different from register 1, otherwise some arbitrary call-clobbered
2363 register. */
2364
2365static void
2366eh_regs (r1, r2, outgoing)
2367 rtx *r1, *r2;
2368 int outgoing;
2369{
2370 rtx reg1, reg2;
2371
2372#ifdef FUNCTION_OUTGOING_VALUE
2373 if (outgoing)
2374 reg1 = FUNCTION_OUTGOING_VALUE (build_pointer_type (void_type_node),
2375 current_function_decl);
2376 else
2377#endif
2378 reg1 = FUNCTION_VALUE (build_pointer_type (void_type_node),
2379 current_function_decl);
2380
2381#ifdef STATIC_CHAIN_REGNUM
2382 if (outgoing)
2383 reg2 = static_chain_incoming_rtx;
2384 else
2385 reg2 = static_chain_rtx;
2386 if (REGNO (reg2) == REGNO (reg1))
2387#endif /* STATIC_CHAIN_REGNUM */
2388 reg2 = NULL_RTX;
2389
2390 if (reg2 == NULL_RTX)
2391 {
2392 int i;
2393 for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
2394 if (call_used_regs[i] && ! fixed_regs[i] && i != REGNO (reg1))
2395 {
38a448ca 2396 reg2 = gen_rtx_REG (Pmode, i);
ca55abae
JM
2397 break;
2398 }
2399
2400 if (reg2 == NULL_RTX)
2401 abort ();
2402 }
2403
2404 *r1 = reg1;
2405 *r2 = reg2;
2406}
2407
9a0d1e1b
AM
2408
2409/* Retrieve the register which contains the pointer to the eh_context
2410 structure set the __throw. */
2411
2412rtx
2413get_reg_for_handler ()
2414{
2415 rtx reg1;
2416 reg1 = FUNCTION_VALUE (build_pointer_type (void_type_node),
2417 current_function_decl);
2418 return reg1;
2419}
2420
2421
ca55abae
JM
2422/* Emit inside of __throw a stub which adjusts the stack pointer and jumps
2423 to the exception handler. __throw will set up the necessary values
2424 and then return to the stub. */
2425
a1622f83
AM
2426rtx
2427expand_builtin_eh_stub_old ()
2428{
2429 rtx stub_start = gen_label_rtx ();
2430 rtx after_stub = gen_label_rtx ();
2431 rtx handler, offset;
2432
2433 emit_jump (after_stub);
2434 emit_label (stub_start);
2435
2436 eh_regs (&handler, &offset, 0);
2437
2438 adjust_stack (offset);
2439 emit_indirect_jump (handler);
2440 emit_label (after_stub);
2441 return gen_rtx_LABEL_REF (Pmode, stub_start);
2442}
2443
ca55abae
JM
2444rtx
2445expand_builtin_eh_stub ()
2446{
2447 rtx stub_start = gen_label_rtx ();
2448 rtx after_stub = gen_label_rtx ();
381127e8 2449 rtx handler, offset;
a1622f83 2450 rtx jump_to, temp;
ca55abae
JM
2451
2452 emit_jump (after_stub);
2453 emit_label (stub_start);
2454
2455 eh_regs (&handler, &offset, 0);
2456
2457 adjust_stack (offset);
9a0d1e1b
AM
2458
2459 /* Handler is in fact a pointer to the _eh_context structure, we need
2460 to pick out the handler field (first element), and jump to there,
2461 leaving the pointer to _eh_conext in the same hardware register. */
9a0d1e1b 2462
a1622f83
AM
2463 temp = gen_rtx_MEM (Pmode, handler);
2464 MEM_IN_STRUCT_P (temp) = 1;
2465 RTX_UNCHANGING_P (temp) = 1;
2466 emit_insn (gen_rtx_SET (Pmode, offset, temp));
2467 emit_insn (gen_rtx_USE (Pmode, handler));
9a0d1e1b 2468
a1622f83 2469 emit_indirect_jump (offset);
9a0d1e1b 2470
ca55abae 2471 emit_label (after_stub);
38a448ca 2472 return gen_rtx_LABEL_REF (Pmode, stub_start);
ca55abae
JM
2473}
2474
2475/* Set up the registers for passing the handler address and stack offset
2476 to the stub above. */
2477
2478void
2479expand_builtin_set_eh_regs (handler, offset)
2480 tree handler, offset;
2481{
2482 rtx reg1, reg2;
2483
2484 eh_regs (&reg1, &reg2, 1);
2485
2486 store_expr (offset, reg2, 0);
2487 store_expr (handler, reg1, 0);
2488
2489 /* These will be used by the stub. */
38a448ca
RH
2490 emit_insn (gen_rtx_USE (VOIDmode, reg1));
2491 emit_insn (gen_rtx_USE (VOIDmode, reg2));
ca55abae 2492}
77d33a84
AM
2493
2494\f
2495
2496/* This contains the code required to verify whether arbitrary instructions
2497 are in the same exception region. */
2498
2499static int *insn_eh_region = (int *)0;
2500static int maximum_uid;
2501
242c13b0
JL
2502static void
2503set_insn_eh_region (first, region_num)
77d33a84
AM
2504 rtx *first;
2505 int region_num;
2506{
2507 rtx insn;
2508 int rnum;
2509
2510 for (insn = *first; insn; insn = NEXT_INSN (insn))
2511 {
2512 if ((GET_CODE (insn) == NOTE) &&
2513 (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG))
2514 {
2515 rnum = NOTE_BLOCK_NUMBER (insn);
2516 insn_eh_region[INSN_UID (insn)] = rnum;
2517 insn = NEXT_INSN (insn);
2518 set_insn_eh_region (&insn, rnum);
2519 /* Upon return, insn points to the EH_REGION_END of nested region */
2520 continue;
2521 }
2522 insn_eh_region[INSN_UID (insn)] = region_num;
2523 if ((GET_CODE (insn) == NOTE) &&
2524 (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
2525 break;
2526 }
2527 *first = insn;
2528}
2529
2530/* Free the insn table, an make sure it cannot be used again. */
2531
9a0d1e1b
AM
2532void
2533free_insn_eh_region ()
77d33a84
AM
2534{
2535 if (!doing_eh (0))
2536 return;
2537
2538 if (insn_eh_region)
2539 {
2540 free (insn_eh_region);
2541 insn_eh_region = (int *)0;
2542 }
2543}
2544
2545/* Initialize the table. max_uid must be calculated and handed into
2546 this routine. If it is unavailable, passing a value of 0 will
2547 cause this routine to calculate it as well. */
2548
9a0d1e1b
AM
2549void
2550init_insn_eh_region (first, max_uid)
77d33a84
AM
2551 rtx first;
2552 int max_uid;
2553{
2554 rtx insn;
2555
2556 if (!doing_eh (0))
2557 return;
2558
2559 if (insn_eh_region)
2560 free_insn_eh_region();
2561
2562 if (max_uid == 0)
2563 for (insn = first; insn; insn = NEXT_INSN (insn))
2564 if (INSN_UID (insn) > max_uid) /* find largest UID */
2565 max_uid = INSN_UID (insn);
2566
2567 maximum_uid = max_uid;
2568 insn_eh_region = (int *) malloc ((max_uid + 1) * sizeof (int));
2569 insn = first;
2570 set_insn_eh_region (&insn, 0);
2571}
2572
2573
2574/* Check whether 2 instructions are within the same region. */
2575
9a0d1e1b
AM
2576int
2577in_same_eh_region (insn1, insn2)
2578 rtx insn1, insn2;
77d33a84
AM
2579{
2580 int ret, uid1, uid2;
2581
2582 /* If no exceptions, instructions are always in same region. */
2583 if (!doing_eh (0))
2584 return 1;
2585
2586 /* If the table isn't allocated, assume the worst. */
2587 if (!insn_eh_region)
2588 return 0;
2589
2590 uid1 = INSN_UID (insn1);
2591 uid2 = INSN_UID (insn2);
2592
2593 /* if instructions have been allocated beyond the end, either
2594 the table is out of date, or this is a late addition, or
2595 something... Assume the worst. */
2596 if (uid1 > maximum_uid || uid2 > maximum_uid)
2597 return 0;
2598
2599 ret = (insn_eh_region[uid1] == insn_eh_region[uid2]);
2600 return ret;
2601}
2602
This page took 0.478642 seconds and 5 git commands to generate.