1 /* Handle exceptional things in C++.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001 Free Software Foundation, Inc.
4 Contributed by Michael Tiemann <tiemann@cygnus.com>
5 Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
6 initial re-implementation courtesy Tad Hunt.
8 This file is part of GNU CC.
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GNU CC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING. If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
37 #include "eh-common.h"
39 static void push_eh_cleanup
PARAMS ((tree
));
40 static tree build_eh_type_type
PARAMS ((tree
));
41 static tree call_eh_info
PARAMS ((void));
42 static void push_eh_info
PARAMS ((void));
43 static tree get_eh_info
PARAMS ((void));
44 static tree get_eh_value
PARAMS ((void));
46 static tree get_eh_type
PARAMS ((void));
47 static tree get_eh_caught
PARAMS ((void));
48 static tree get_eh_handlers
PARAMS ((void));
50 static int dtor_nothrow
PARAMS ((tree
));
51 static tree do_pop_exception
PARAMS ((tree
));
52 static tree build_eh_type_type_ref
PARAMS ((tree
));
53 static tree build_terminate_handler
PARAMS ((void));
54 static tree alloc_eh_object
PARAMS ((tree
));
55 static int complete_ptr_ref_or_void_ptr_p
PARAMS ((tree
, tree
));
56 static bool is_admissible_throw_operand
PARAMS ((tree
));
57 static int can_convert_eh
PARAMS ((tree
, tree
));
58 static void check_handlers_1
PARAMS ((tree
, tree
));
59 static void initialize_handler_parm
PARAMS ((tree
));
60 static tree expand_throw
PARAMS ((tree
));
61 static int decl_is_java_type
PARAMS ((tree decl
, int err
));
66 /* In a given translation unit we are constrained to catch only C++
67 types or only Java types. `catch_language' holds the current type,
68 and `catch_language_init' registers whether `catch_language' has
71 static int catch_language_init
= 0;
72 static int catch_language
;
74 /* ======================================================================
75 Briefly the algorithm works like this:
77 When a constructor or start of a try block is encountered,
78 push_eh_entry (&eh_stack) is called. Push_eh_entry () creates a
79 new entry in the unwind protection stack and returns a label to
80 output to start the protection for that block.
82 When a destructor or end try block is encountered, pop_eh_entry
83 (&eh_stack) is called. Pop_eh_entry () returns the eh_entry it
84 created when push_eh_entry () was called. The eh_entry structure
85 contains three things at this point. The start protect label,
86 the end protect label, and the exception handler label. The end
87 protect label should be output before the call to the destructor
88 (if any). If it was a destructor, then its parse tree is stored
89 in the finalization variable in the eh_entry structure. Otherwise
90 the finalization variable is set to NULL to reflect the fact that
91 it is the end of a try block. Next, this modified eh_entry node
92 is enqueued in the finalizations queue by calling
93 enqueue_eh_entry (&queue,entry).
95 +---------------------------------------------------------------+
96 |XXX: Will need modification to deal with partially |
97 | constructed arrays of objects |
99 | Basically, this consists of keeping track of how many |
100 | of the objects have been constructed already (this |
101 | should be in a register though, so that shouldn't be a |
103 +---------------------------------------------------------------+
105 When a catch block is encountered, there is a lot of work to be
108 Since we don't want to generate the catch block inline with the
109 regular flow of the function, we need to have some way of doing
110 so. Luckily, we can use sequences to defer the catch sections.
111 When the start of a catch block is encountered, we start the
112 sequence. After the catch block is generated, we end the
115 Next we must insure that when the catch block is executed, all
116 finalizations for the matching try block have been completed. If
117 any of those finalizations throw an exception, we must call
118 terminate according to the ARM (section r.15.6.1). What this
119 means is that we need to dequeue and emit finalizations for each
120 entry in the eh_queue until we get to an entry with a NULL
121 finalization field. For any of the finalization entries, if it
122 is not a call to terminate (), we must protect it by giving it
123 another start label, end label, and exception handler label,
124 setting its finalization tree to be a call to terminate (), and
125 enqueue'ing this new eh_entry to be output at an outer level.
126 Finally, after all that is done, we can get around to outputting
127 the catch block which basically wraps all the "catch (...) {...}"
128 statements in a big if/then/else construct that matches the
129 correct block to call.
131 ===================================================================== */
133 /* ====================================================================== */
135 /* sets up all the global eh stuff that needs to be initialized at the
136 start of compilation. */
139 init_exception_processing ()
142 tree vtype
= build_function_type (void_type_node
, void_list_node
);
145 push_namespace (std_identifier
);
146 terminate_node
= build_cp_library_fn_ptr ("terminate", vtype
);
147 TREE_THIS_VOLATILE (terminate_node
) = 1;
148 TREE_NOTHROW (terminate_node
) = 1;
152 set_exception_lang_code (EH_LANG_C_plus_plus
);
153 set_exception_version_code (1);
155 /* If we use setjmp/longjmp EH, arrange for all cleanup actions to
156 be protected with __terminate. */
157 protect_cleanup_actions_with_terminate
= 1;
160 /* Retrieve a pointer to the cp_eh_info node for the current exception. */
167 fn
= get_identifier ("__start_cp_handler");
168 if (IDENTIFIER_GLOBAL_VALUE (fn
))
169 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
173 tree cleanup_fn_type
;
174 tree matcher_fn_type
;
175 tree cp_eh_info_type
;
176 tree exception_desc_type
;
179 eh_info_type
= make_aggr_type (RECORD_TYPE
);
180 exception_desc_type
= make_aggr_type (RECORD_TYPE
);
182 /* void * (*) (__eh_info *, void *, exception_descriptor *); */
183 matcher_fn_type
= tree_cons
184 (NULL_TREE
, build_pointer_type (eh_info_type
), tree_cons
185 (NULL_TREE
, ptr_type_node
, tree_cons
186 (NULL_TREE
, build_pointer_type (exception_desc_type
),
188 matcher_fn_type
= build_function_type (ptr_type_node
, matcher_fn_type
);
189 matcher_fn_type
= build_pointer_type (matcher_fn_type
);
191 /* void (*) (void *); */
192 cleanup_fn_type
= tree_cons
193 (NULL_TREE
, ptr_type_node
, void_list_node
);
194 cleanup_fn_type
= build_function_type (void_type_node
, cleanup_fn_type
);
195 cleanup_fn_type
= build_pointer_type (cleanup_fn_type
);
200 __eh_matcher match_function;
204 fields
[0] = build_decl (FIELD_DECL
,
205 get_identifier ("match_function"), ptr_type_node
);
206 fields
[1] = build_decl (FIELD_DECL
,
207 get_identifier ("language"), short_integer_type_node
);
208 fields
[2] = build_decl (FIELD_DECL
,
209 get_identifier ("version"), short_integer_type_node
);
210 /* N.B.: The fourth field LEN is expected to be
211 the number of fields - 1, not the total number of fields. */
212 finish_builtin_type (eh_info_type
, "__eh_info", fields
, 2, ptr_type_node
);
214 /* exception_support.h
224 void *original_value;
226 cp_eh_info_type
= make_aggr_type (RECORD_TYPE
);
227 fields
[0] = build_decl (FIELD_DECL
, get_identifier ("eh_info"),
229 fields
[1] = build_decl (FIELD_DECL
, get_identifier ("value"),
231 fields
[2] = build_decl (FIELD_DECL
, get_identifier ("type"),
233 fields
[3] = build_decl (FIELD_DECL
, get_identifier ("cleanup"),
235 fields
[4] = build_decl (FIELD_DECL
, get_identifier ("caught"),
237 fields
[5] = build_decl (FIELD_DECL
, get_identifier ("next"),
238 build_pointer_type (cp_eh_info_type
));
239 fields
[6] = build_decl (FIELD_DECL
, get_identifier ("handlers"),
240 long_integer_type_node
);
241 fields
[7] = build_decl (FIELD_DECL
, get_identifier ("original_value"),
243 /* N.B.: The fourth field LEN is expected to be
244 the number of fields - 1, not the total number of fields. */
245 finish_builtin_type (cp_eh_info_type
, "cp_eh_info", fields
, 7, ptr_type_node
);
247 /* And now the function. */
248 fn
= push_library_fn (fn
,
249 build_function_type (build_pointer_type (cp_eh_info_type
),
252 return build_function_call (fn
, NULL_TREE
);
255 /* Retrieve a pointer to the cp_eh_info node for the current exception
256 and save it in the current binding level. */
261 tree decl
, fn
= call_eh_info ();
263 /* Remember the pointer to the current exception info; it won't change
264 during this catch block. */
265 decl
= build_decl (VAR_DECL
, get_identifier ("__exception_info"),
267 DECL_ARTIFICIAL (decl
) = 1;
268 DECL_INITIAL (decl
) = fn
;
269 decl
= pushdecl (decl
);
270 cp_finish_decl (decl
, fn
, NULL_TREE
, 0);
273 /* Returns a reference to the cp_eh_info node for the current exception. */
278 /* Look for the pointer pushed in push_eh_info. */
279 tree t
= lookup_name (get_identifier ("__exception_info"), 0);
280 return build_indirect_ref (t
, NULL_PTR
);
283 /* Returns a reference to the current exception object. */
288 return build_component_ref (get_eh_info (), get_identifier ("value"),
292 /* Returns a reference to the current exception type. */
298 return build_component_ref (get_eh_info (), get_identifier ("type"),
302 /* Returns a reference to whether or not the current exception
308 return build_component_ref (get_eh_info (), get_identifier ("caught"),
312 /* Returns a reference to whether or not the current exception
318 return build_component_ref (get_eh_info (), get_identifier ("handlers"),
323 /* Build a type value for use at runtime for a type that is matched
324 against by the exception handling system. */
327 build_eh_type_type (type
)
330 if (type
== error_mark_node
)
331 return error_mark_node
;
333 /* peel back references, so they match. */
334 if (TREE_CODE (type
) == REFERENCE_TYPE
)
335 type
= TREE_TYPE (type
);
337 /* Peel off cv qualifiers. */
338 type
= TYPE_MAIN_VARIANT (type
);
340 return build1 (ADDR_EXPR
, ptr_type_node
, get_typeid_1 (type
));
343 /* Build the address of a typeinfo decl for use in the runtime
344 matching field of the new exception model */
347 build_eh_type_type_ref (type
)
352 if (type
== NULL_TREE
|| type
== error_mark_node
)
355 /* peel back references, so they match. */
356 if (TREE_CODE (type
) == REFERENCE_TYPE
)
357 type
= TREE_TYPE (type
);
359 /* Peel off cv qualifiers. */
360 type
= TYPE_MAIN_VARIANT (type
);
362 exp
= get_tinfo_decl (type
);
364 exp
= build1 (ADDR_EXPR
, ptr_type_node
, exp
);
369 /* This routine is called to mark all the symbols representing runtime
370 type functions in the exception table as having been referenced.
371 This will make sure code is emitted for them. Called from finish_file. */
374 mark_all_runtime_matches ()
380 num
= find_all_handler_type_matches (&ptr
);
381 if (num
== 0 || ptr
== NULL
)
384 for (x
=0; x
<num
; x
++)
387 if (TREE_CODE (exp
) == ADDR_EXPR
)
389 exp
= TREE_OPERAND (exp
, 0);
390 if (TREE_CODE (exp
) == FUNCTION_DECL
)
391 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (exp
)) = 1;
398 /* Returns nonzero if cleaning up an exception of type TYPE (which can be
399 NULL_TREE for a ... handler) will not throw an exception. */
407 if (type
== NULL_TREE
)
410 if (! TYPE_HAS_DESTRUCTOR (type
))
413 fn
= lookup_member (type
, dtor_identifier
, 0, 0);
414 fn
= TREE_VALUE (fn
);
415 return TREE_NOTHROW (fn
);
418 /* Build up a call to __cp_pop_exception, to destroy the exception object
419 for the current catch block if no others are currently using it. */
422 do_pop_exception (type
)
426 fn
= get_identifier ("__cp_pop_exception");
427 if (IDENTIFIER_GLOBAL_VALUE (fn
))
428 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
431 /* Declare void __cp_pop_exception (void *),
432 as defined in exception.cc. */
433 fn
= push_void_library_fn
434 (fn
, tree_cons (NULL_TREE
, ptr_type_node
, void_list_node
));
435 /* This can throw if the destructor for the exception throws. */
436 TREE_NOTHROW (fn
) = 0;
439 /* Arrange to do a dynamically scoped cleanup upon exit from this region. */
440 cleanup
= lookup_name (get_identifier ("__exception_info"), 0);
441 cleanup
= build_function_call (fn
, tree_cons
442 (NULL_TREE
, cleanup
, NULL_TREE
));
443 TREE_NOTHROW (cleanup
) = dtor_nothrow (type
);
447 /* This routine creates the cleanup for the current exception. */
450 push_eh_cleanup (type
)
453 finish_decl_cleanup (NULL_TREE
, do_pop_exception (type
));
456 /* Build up a call to terminate on the function obstack, for use as an
457 exception handler. */
460 build_terminate_handler ()
462 return build_function_call (terminate_node
, NULL_TREE
);
465 /* Return nonzero value if DECL is a Java type suitable for catch or
469 decl_is_java_type (decl
, err
)
473 int r
= (TREE_CODE (decl
) == POINTER_TYPE
474 && TREE_CODE (TREE_TYPE (decl
)) == RECORD_TYPE
475 && TYPE_FOR_JAVA (TREE_TYPE (decl
)));
479 if (TREE_CODE (decl
) == REFERENCE_TYPE
480 && TREE_CODE (TREE_TYPE (decl
)) == RECORD_TYPE
481 && TYPE_FOR_JAVA (TREE_TYPE (decl
)))
483 /* Can't throw a reference. */
484 cp_error ("type `%T' is disallowed in Java `throw' or `catch'",
491 = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jthrowable"));
493 if (jthrow_node
== NULL_TREE
)
495 ("call to Java `catch' or `throw' with `jthrowable' undefined");
497 jthrow_node
= TREE_TYPE (TREE_TYPE (jthrow_node
));
499 if (! DERIVED_FROM_P (jthrow_node
, TREE_TYPE (decl
)))
501 /* Thrown object must be a Throwable. */
502 cp_error ("type `%T' is not derived from `java::lang::Throwable'",
511 /* Initialize the catch parameter DECL. */
514 initialize_handler_parm (decl
)
522 /* Make sure we mark the catch param as used, otherwise we'll get a
523 warning about an unused ((anonymous)). */
524 TREE_USED (decl
) = 1;
526 /* Figure out the type that the initializer is. */
527 init_type
= TREE_TYPE (decl
);
528 if (TREE_CODE (init_type
) != REFERENCE_TYPE
529 && TREE_CODE (init_type
) != POINTER_TYPE
)
530 init_type
= build_reference_type (init_type
);
532 if (decl_is_java_type (init_type
, 0))
535 = builtin_function ("_Jv_exception_info",
536 build_function_type (ptr_type_node
,
537 tree_cons (NULL_TREE
,
540 0, NOT_BUILT_IN
, NULL_PTR
);
542 exp
= build (CALL_EXPR
, ptr_type_node
,
543 build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)),
545 NULL_TREE
, NULL_TREE
);
546 TREE_SIDE_EFFECTS (exp
) = 1;
549 set_exception_lang_code (EH_LANG_Java
);
550 set_exception_version_code (1);
554 exp
= get_eh_value ();
555 lang
= EH_LANG_C_plus_plus
;
558 if (catch_language_init
)
560 if (lang
!= catch_language
)
561 error ("mixing C++ and Java `catch'es in single translation unit");
565 catch_language_init
= 1;
566 catch_language
= lang
;
569 /* Since pointers are passed by value, initialize a reference to
570 pointer catch parm with the address of the value slot. */
571 if (TREE_CODE (init_type
) == REFERENCE_TYPE
572 && TREE_CODE (TREE_TYPE (init_type
)) == POINTER_TYPE
)
573 exp
= build_unary_op (ADDR_EXPR
, exp
, 1);
575 exp
= ocp_convert (init_type
, exp
, CONV_IMPLICIT
|CONV_FORCE_TEMP
, 0);
577 init
= convert_from_reference (exp
);
579 /* If the constructor for the catch parm exits via an exception, we
580 must call terminate. See eh23.C. */
581 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl
)))
583 /* Generate the copy constructor call directly so we can wrap it.
584 See also expand_default_init. */
585 init
= ocp_convert (TREE_TYPE (decl
), init
,
586 CONV_IMPLICIT
|CONV_FORCE_TEMP
, 0);
587 init
= build (TRY_CATCH_EXPR
, TREE_TYPE (init
), init
,
588 build_terminate_handler ());
591 /* Let `cp_finish_decl' know that this initializer is ok. */
592 DECL_INITIAL (decl
) = error_mark_node
;
593 decl
= pushdecl (decl
);
596 cp_finish_decl (decl
, init
, NULL_TREE
,
597 LOOKUP_ONLYCONVERTING
|DIRECT_BIND
);
600 /* Call this to start a catch block. DECL is the catch parameter. */
603 expand_start_catch_block (decl
)
606 tree compound_stmt_1
;
607 tree compound_stmt_2
;
612 /* Make sure this declaration is reasonable. */
613 if (decl
&& !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl
), NULL_TREE
))
616 /* Create a binding level for the eh_info and the exception object
618 compound_stmt_1
= begin_compound_stmt (/*has_no_scope=*/0);
620 if (! decl
|| ! decl_is_java_type (TREE_TYPE (decl
), 1))
622 /* The ordinary C++ case. */
626 type
= TREE_TYPE (decl
);
629 begin_catch_block (build_eh_type_type_ref (type
));
632 push_eh_cleanup (type
);
636 /* The Java case. In this case, the match_info is a pointer to
637 the Java class object. We assume that the class is a
639 tree ref
= build_java_class_ref (TREE_TYPE (TREE_TYPE (decl
)));
640 begin_catch_block (build1 (ADDR_EXPR
, jclass_node
, ref
));
643 /* Create a binding level for the parm. */
644 compound_stmt_2
= begin_compound_stmt (/*has_no_scope=*/0);
647 initialize_handler_parm (decl
);
649 return build_tree_list (compound_stmt_1
, compound_stmt_2
);
653 /* Call this to end a catch block. Its responsible for emitting the
654 code to handle jumping back to the correct place, and for emitting
655 the label to jump to if this catch block didn't match. */
658 expand_end_catch_block (blocks
)
661 tree compound_stmt_1
= blocks
? TREE_PURPOSE (blocks
): NULL_TREE
;
662 tree compound_stmt_2
= blocks
? TREE_VALUE (blocks
): NULL_TREE
;
667 /* The exception being handled is rethrown if control reaches the end of
668 a handler of the function-try-block of a constructor or destructor. */
669 if (in_function_try_handler
670 && (DECL_CONSTRUCTOR_P (current_function_decl
)
671 || DECL_DESTRUCTOR_P (current_function_decl
)))
672 finish_expr_stmt (build_throw (NULL_TREE
));
674 /* Cleanup the EH parameter. */
675 finish_compound_stmt (/*has_no_scope=*/0, compound_stmt_2
);
676 /* Cleanup the EH object. */
677 finish_compound_stmt (/*has_no_scope=*/0, compound_stmt_1
);
680 /* An exception spec is implemented more or less like:
685 void *p[] = { typeid(raises) };
686 __check_eh_spec (p, count);
689 __check_eh_spec in exception.cc handles all the details. */
692 expand_start_eh_spec ()
694 return begin_try_block ();
698 expand_end_eh_spec (raises
, try_block
)
702 tree tmp
, fn
, decl
, types
= NULL_TREE
;
707 finish_try_block (try_block
);
708 handler
= begin_handler ();
709 blocks
= finish_handler_parms (NULL_TREE
, handler
);
711 if (TREE_VALUE (raises
) == NULL_TREE
)
713 fn
= get_identifier ("__check_null_eh_spec");
714 if (IDENTIFIER_GLOBAL_VALUE (fn
))
715 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
718 tmp
= build_function_type (void_type_node
, void_list_node
);
719 fn
= push_throw_library_fn (fn
, tmp
);
720 /* Since the spec doesn't allow any exceptions, this call will
721 never throw. We use push_throw_library_fn because we do want
722 TREE_THIS_VOLATILE to be set. */
723 TREE_NOTHROW (fn
) = 1;
729 /* Build up an array of type_infos. */
730 for (; raises
&& TREE_VALUE (raises
); raises
= TREE_CHAIN (raises
))
733 (NULL_TREE
, build_eh_type_type (TREE_VALUE (raises
)), types
);
737 types
= build_nt (CONSTRUCTOR
, NULL_TREE
, types
);
738 TREE_HAS_CONSTRUCTOR (types
) = 1;
740 /* We can't pass the CONSTRUCTOR directly, so stick it in a variable. */
741 tmp
= build_cplus_array_type (const_ptr_type_node
, NULL_TREE
);
742 decl
= build_decl (VAR_DECL
, NULL_TREE
, tmp
);
743 DECL_ARTIFICIAL (decl
) = 1;
744 DECL_INITIAL (decl
) = types
;
745 DECL_CONTEXT (decl
) = current_function_decl
;
746 cp_finish_decl (decl
, types
, NULL_TREE
, 0);
748 decl
= decay_conversion (decl
);
750 fn
= get_identifier ("__check_eh_spec");
751 if (IDENTIFIER_GLOBAL_VALUE (fn
))
752 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
756 (NULL_TREE
, integer_type_node
, tree_cons
757 (NULL_TREE
, TREE_TYPE (decl
), void_list_node
));
758 tmp
= build_function_type (void_type_node
, tmp
);
760 fn
= push_throw_library_fn (fn
, tmp
);
763 tmp
= tree_cons (NULL_TREE
, build_int_2 (count
, 0),
764 tree_cons (NULL_TREE
, decl
, NULL_TREE
));
767 tmp
= build_call (fn
, tmp
);
768 finish_expr_stmt (tmp
);
770 finish_handler (blocks
, handler
);
771 finish_handler_sequence (try_block
);
774 /* This is called to expand all the toplevel exception handling
775 finalization for a function. It should only be called once per
779 expand_exception_blocks ()
781 do_pending_stack_adjust ();
785 rtx funcend
= gen_label_rtx ();
788 /* We cannot protect n regions this way if we must flow into the
789 EH region through the top of the region, as we have to with
790 the setjmp/longjmp approach. */
791 if (USING_SJLJ_EXCEPTIONS
== 0)
792 expand_eh_region_start ();
794 emit_insns (catch_clauses
);
795 catch_clauses
= catch_clauses_last
= NULL_RTX
;
797 if (USING_SJLJ_EXCEPTIONS
== 0)
798 expand_eh_region_end (build_terminate_handler ());
800 emit_insns (catch_clauses
);
801 catch_clauses
= catch_clauses_last
= NULL_RTX
;
802 emit_label (funcend
);
806 /* Return a pointer to a buffer for an exception object of type TYPE. */
809 alloc_eh_object (type
)
814 fn
= get_identifier ("__eh_alloc");
815 if (IDENTIFIER_GLOBAL_VALUE (fn
))
816 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
819 /* Declare __eh_alloc (size_t), as defined in exception.cc. */
820 tree tmp
= tree_cons (NULL_TREE
, sizetype
, void_list_node
);
821 fn
= push_library_fn (fn
, build_function_type (ptr_type_node
, tmp
));
824 exp
= build_function_call (fn
, tree_cons
825 (NULL_TREE
, size_in_bytes (type
), NULL_TREE
));
826 exp
= build1 (NOP_EXPR
, build_pointer_type (type
), exp
);
830 /* Expand a throw statement. This follows the following
833 1. Allocate space to save the current PC onto the stack.
834 2. Generate and emit a label and save its address into the
835 newly allocated stack space since we can't save the pc directly.
836 3. If this is the first call to throw in this function:
837 generate a label for the throw block
838 4. jump to the throw block label. */
847 return error_mark_node
;
850 && decl_is_java_type (TREE_TYPE (exp
), 1))
852 /* A Java `throw' statement. */
853 tree args
= tree_cons (NULL_TREE
, exp
, NULL
);
855 fn
= get_identifier (USING_SJLJ_EXCEPTIONS
858 if (IDENTIFIER_GLOBAL_VALUE (fn
))
859 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
862 /* Declare _Jv_Throw (void *), as defined in Java's
864 tree tmp
= tree_cons (NULL_TREE
, ptr_type_node
, void_list_node
);
865 tmp
= build_function_type (ptr_type_node
, tmp
);
866 fn
= push_throw_library_fn (fn
, tmp
);
869 exp
= build_function_call (fn
, args
);
874 tree cleanup
= NULL_TREE
, e
;
879 begin_init_stmts (&stmt_expr
, &compound_stmt
);
881 /* throw expression */
882 /* First, decay it. */
883 exp
= decay_conversion (exp
);
885 /* The CLEANUP_TYPE is the internal type of a destructor. Under
886 the old ABI, destructors are two-argument functions; under
887 the new ABI they take only one argument. */
888 if (cleanup_type
== NULL_TREE
)
892 arg_types
= void_list_node
;
893 arg_types
= tree_cons (NULL_TREE
, ptr_type_node
, arg_types
);
894 cleanup_type
= (build_pointer_type
895 (build_function_type (void_type_node
, arg_types
)));
898 if (TYPE_PTR_P (TREE_TYPE (exp
)))
899 throw_type
= build_eh_type_type (TREE_TYPE (exp
));
904 /* OK, this is kind of wacky. The standard says that we call
905 terminate when the exception handling mechanism, after
906 completing evaluation of the expression to be thrown but
907 before the exception is caught (_except.throw_), calls a
908 user function that exits via an uncaught exception.
910 So we have to protect the actual initialization of the
911 exception object with terminate(), but evaluate the
912 expression first. Since there could be temps in the
913 expression, we need to handle that, too. We also expand
914 the call to __eh_alloc first (which doesn't matter, since
917 my_friendly_assert (stmts_are_full_exprs_p () == 1, 19990926);
919 /* Store the throw expression into a temp. This can be less
920 efficient than storing it into the allocated space directly, but
921 if we allocated the space first we would have to deal with
922 cleaning it up if evaluating this expression throws. */
923 if (TREE_SIDE_EFFECTS (exp
))
925 tree temp
= create_temporary_var (TREE_TYPE (exp
));
926 DECL_INITIAL (temp
) = exp
;
927 cp_finish_decl (temp
, exp
, NULL_TREE
, LOOKUP_ONLYCONVERTING
);
931 /* Allocate the space for the exception. */
932 ptr
= save_expr (alloc_eh_object (TREE_TYPE (exp
)));
933 finish_expr_stmt (ptr
);
935 try_block
= begin_try_block ();
936 object
= build_indirect_ref (ptr
, NULL_PTR
);
937 exp
= build_modify_expr (object
, INIT_EXPR
, exp
);
939 if (exp
== error_mark_node
)
940 error (" in thrown expression");
942 finish_expr_stmt (exp
);
943 finish_cleanup_try_block (try_block
);
944 finish_cleanup (build_terminate_handler (), try_block
);
946 throw_type
= build_eh_type_type (TREE_TYPE (object
));
948 if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (object
)))
950 cleanup
= lookup_fnfields (TYPE_BINFO (TREE_TYPE (object
)),
951 complete_dtor_identifier
,
953 cleanup
= TREE_VALUE (cleanup
);
955 mark_addressable (cleanup
);
956 /* Pretend it's a normal function. */
957 cleanup
= build1 (ADDR_EXPR
, cleanup_type
, cleanup
);
963 /* Cast EXP to `void *' so that it will match the prototype for
964 __cp_push_exception. */
965 exp
= convert (ptr_type_node
, exp
);
967 if (cleanup
== NULL_TREE
)
969 cleanup
= build_int_2 (0, 0);
970 TREE_TYPE (cleanup
) = cleanup_type
;
973 fn
= cp_push_exception_identifier
;
974 if (IDENTIFIER_GLOBAL_VALUE (fn
))
975 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
978 /* Declare __cp_push_exception (void*, void*, void (*)(void*, int)),
979 as defined in exception.cc. */
982 (NULL_TREE
, ptr_type_node
, tree_cons
983 (NULL_TREE
, ptr_type_node
, tree_cons
984 (NULL_TREE
, cleanup_type
, void_list_node
)));
985 fn
= push_void_library_fn (fn
, tmp
);
988 e
= tree_cons (NULL_TREE
, exp
, tree_cons
989 (NULL_TREE
, throw_type
, tree_cons
990 (NULL_TREE
, cleanup
, NULL_TREE
)));
991 finish_expr_stmt (build_function_call (fn
, e
));
993 exp
= finish_init_stmts (stmt_expr
, compound_stmt
);
997 /* rethrow current exception; note that it's no longer caught. */
999 tree fn
= get_identifier ("__uncatch_exception");
1000 if (IDENTIFIER_GLOBAL_VALUE (fn
))
1001 fn
= IDENTIFIER_GLOBAL_VALUE (fn
);
1003 /* Declare void __uncatch_exception (void)
1004 as defined in exception.cc. */
1005 fn
= push_void_library_fn (fn
, void_list_node
);
1007 exp
= build_function_call (fn
, NULL_TREE
);
1013 /* Build a throw expression. */
1019 if (e
== error_mark_node
)
1022 if (processing_template_decl
)
1023 return build_min (THROW_EXPR
, void_type_node
, e
);
1026 cp_warning ("throwing NULL, which has integral, not pointer type");
1030 if (!is_admissible_throw_operand (e
))
1031 return error_mark_node
;
1034 e
= expand_throw (e
);
1035 e
= build1 (THROW_EXPR
, void_type_node
, e
);
1036 TREE_SIDE_EFFECTS (e
) = 1;
1042 /* Make sure TYPE is complete, pointer to complete, reference to
1043 complete, or pointer to cv void. Issue diagnostic on failure.
1044 Return the zero on failure and non-zero on success. FROM can be
1045 the expr or decl from whence TYPE came, if available. */
1048 complete_ptr_ref_or_void_ptr_p (type
, from
)
1054 /* Check complete. */
1055 type
= complete_type_or_else (type
, from
);
1059 /* Or a pointer or ref to one, or cv void *. */
1060 is_ptr
= TREE_CODE (type
) == POINTER_TYPE
;
1061 if (is_ptr
|| TREE_CODE (type
) == REFERENCE_TYPE
)
1063 tree core
= TREE_TYPE (type
);
1065 if (is_ptr
&& VOID_TYPE_P (core
))
1067 else if (!complete_type_or_else (core
, from
))
1073 /* Return truth-value if EXPRESSION is admissible in throw-expression,
1074 i.e. if it is not of incomplete type or a pointer/reference to such
1075 a type or of an abstract class type. */
1078 is_admissible_throw_operand (expr
)
1081 tree type
= TREE_TYPE (expr
);
1083 /* 15.1/4 [...] The type of the throw-expression shall not be an
1084 incomplete type, or a pointer or a reference to an incomplete
1085 type, other than void*, const void*, volatile void*, or
1086 const volatile void*. Except for these restriction and the
1087 restrictions on type matching mentioned in 15.3, the operand
1088 of throw is treated exactly as a function argument in a call
1089 (5.2.2) or the operand of a return statement. */
1090 if (!complete_ptr_ref_or_void_ptr_p (type
, expr
))
1093 /* 10.4/3 An abstract class shall not be used as a parameter type,
1094 as a function return type or as type of an explicit
1096 else if (CLASS_TYPE_P (type
) && CLASSTYPE_PURE_VIRTUALS (type
))
1098 cp_error ("Expression '%E' of abstract class type '%T' cannot be used in throw-expression", expr
, type
);
1105 /* Returns nonzero if FN is a declaration of a standard C library
1106 function which is known not to throw.
1108 [lib.res.on.exception.handling]: None of the functions from the
1109 Standard C library shall report an error by throwing an
1110 exception, unless it calls a program-supplied function that
1111 throws an exception. */
1116 nothrow_libfn_p (fn
)
1121 if (TREE_PUBLIC (fn
)
1122 && DECL_EXTERNAL (fn
)
1123 && DECL_NAMESPACE_SCOPE_P (fn
)
1124 && DECL_EXTERN_C_P (fn
))
1127 /* Can't be a C library function. */
1130 id
= DECL_ASSEMBLER_NAME (fn
);
1131 return !!libc_name_p (IDENTIFIER_POINTER (id
), IDENTIFIER_LENGTH (id
));
1134 /* Returns nonzero if an exception of type FROM will be caught by a
1135 handler for type TO, as per [except.handle]. */
1138 can_convert_eh (to
, from
)
1141 if (TREE_CODE (to
) == REFERENCE_TYPE
)
1142 to
= TREE_TYPE (to
);
1143 if (TREE_CODE (from
) == REFERENCE_TYPE
)
1144 from
= TREE_TYPE (from
);
1146 if (TREE_CODE (to
) == POINTER_TYPE
&& TREE_CODE (from
) == POINTER_TYPE
)
1148 to
= TREE_TYPE (to
);
1149 from
= TREE_TYPE (from
);
1151 if (! at_least_as_qualified_p (to
, from
))
1154 if (TREE_CODE (to
) == VOID_TYPE
)
1157 /* else fall through */
1160 if (IS_AGGR_TYPE (to
) && IS_AGGR_TYPE (from
)
1161 && PUBLICLY_UNIQUELY_DERIVED_P (to
, from
))
1167 /* Check whether any of HANDLERS are shadowed by another handler accepting
1168 TYPE. Note that the shadowing may not be complete; even if an exception
1169 of type B would be caught by a handler for A, there could be a derived
1170 class C for which A is an ambiguous base but B is not, so the handler
1171 for B would catch an exception of type C. */
1174 check_handlers_1 (master
, handlers
)
1178 tree type
= TREE_TYPE (master
);
1181 for (handler
= handlers
; handler
; handler
= TREE_CHAIN (handler
))
1182 if (TREE_TYPE (handler
)
1183 && can_convert_eh (type
, TREE_TYPE (handler
)))
1185 lineno
= STMT_LINENO (handler
);
1186 cp_warning ("exception of type `%T' will be caught",
1187 TREE_TYPE (handler
));
1188 lineno
= STMT_LINENO (master
);
1189 cp_warning (" by earlier handler for `%T'", type
);
1194 /* Given a chain of HANDLERs, make sure that they're OK. */
1197 check_handlers (handlers
)
1201 int save_line
= lineno
;
1202 for (handler
= handlers
; handler
; handler
= TREE_CHAIN (handler
))
1204 if (TREE_CHAIN (handler
) == NULL_TREE
)
1205 /* No more handlers; nothing to shadow. */;
1206 else if (TREE_TYPE (handler
) == NULL_TREE
)
1208 lineno
= STMT_LINENO (handler
);
1210 ("`...' handler must be the last handler for its try block");
1213 check_handlers_1 (handler
, TREE_CHAIN (handler
));