1 /* Handle exceptional things in C++.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2007 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 GCC.
10 GCC 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 3, or (at your option)
15 GCC 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 GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
27 #include "coretypes.h"
38 #include "tree-inline.h"
39 #include "tree-iterator.h"
42 static void push_eh_cleanup (tree);
43 static tree prepare_eh_type (tree);
44 static tree build_eh_type_type (tree);
45 static tree do_begin_catch (void);
46 static int dtor_nothrow (tree);
47 static tree do_end_catch (tree);
48 static bool decl_is_java_type (tree decl, int err);
49 static void initialize_handler_parm (tree, tree);
50 static tree do_allocate_exception (tree);
51 static tree wrap_cleanups_r (tree *, int *, void *);
52 static int complete_ptr_ref_or_void_ptr_p (tree, tree);
53 static bool is_admissible_throw_operand (tree);
54 static int can_convert_eh (tree, tree);
55 static tree cp_protect_cleanup_actions (void);
57 /* Sets up all the global eh stuff that needs to be initialized at the
58 start of compilation. */
61 init_exception_processing (void)
65 /* void std::terminate (); */
66 push_namespace (std_identifier);
67 tmp = build_function_type (void_type_node, void_list_node);
68 terminate_node = build_cp_library_fn_ptr ("terminate", tmp);
69 TREE_THIS_VOLATILE (terminate_node) = 1;
70 TREE_NOTHROW (terminate_node) = 1;
73 /* void __cxa_call_unexpected(void *); */
74 tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
75 tmp = build_function_type (void_type_node, tmp);
77 = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
79 eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
80 ? "__gxx_personality_sj0"
81 : "__gxx_personality_v0");
82 if (targetm.arm_eabi_unwinder)
83 unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
85 default_init_unwind_resume_libfunc ();
87 lang_eh_runtime_type = build_eh_type_type;
88 lang_protect_cleanup_actions = &cp_protect_cleanup_actions;
91 /* Returns an expression to be executed if an unhandled exception is
92 propagated out of a cleanup region. */
95 cp_protect_cleanup_actions (void)
99 When the destruction of an object during stack unwinding exits
100 using an exception ... void terminate(); is called. */
101 return build_call_n (terminate_node, 0);
105 prepare_eh_type (tree type)
107 if (type == NULL_TREE)
109 if (type == error_mark_node)
110 return error_mark_node;
112 /* peel back references, so they match. */
113 type = non_reference (type);
115 /* Peel off cv qualifiers. */
116 type = TYPE_MAIN_VARIANT (type);
118 /* Functions and arrays decay to pointers. */
119 type = type_decays_to (type);
124 /* Return the type info for TYPE as used by EH machinery. */
126 eh_type_info (tree type)
130 if (type == NULL_TREE || type == error_mark_node)
133 if (decl_is_java_type (type, 0))
134 exp = build_java_class_ref (TREE_TYPE (type));
136 exp = get_tinfo_decl (type);
141 /* Build the address of a typeinfo decl for use in the runtime
142 matching field of the exception model. */
145 build_eh_type_type (tree type)
147 tree exp = eh_type_info (type);
154 return convert (ptr_type_node, build_address (exp));
160 return build0 (EXC_PTR_EXPR, ptr_type_node);
163 /* Build up a call to __cxa_get_exception_ptr so that we can build a
164 copy constructor for the thrown object. */
167 do_get_exception_ptr (void)
171 fn = get_identifier ("__cxa_get_exception_ptr");
172 if (!get_global_value_if_present (fn, &fn))
174 /* Declare void* __cxa_get_exception_ptr (void *). */
175 tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
176 fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
179 return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
181 tf_warning_or_error);
184 /* Build up a call to __cxa_begin_catch, to tell the runtime that the
185 exception has been handled. */
188 do_begin_catch (void)
192 fn = get_identifier ("__cxa_begin_catch");
193 if (!get_global_value_if_present (fn, &fn))
195 /* Declare void* __cxa_begin_catch (void *). */
196 tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
197 fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
200 return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
202 tf_warning_or_error);
205 /* Returns nonzero if cleaning up an exception of type TYPE (which can be
206 NULL_TREE for a ... handler) will not throw an exception. */
209 dtor_nothrow (tree type)
211 if (type == NULL_TREE)
214 if (!CLASS_TYPE_P (type))
217 if (CLASSTYPE_LAZY_DESTRUCTOR (type))
218 lazily_declare_fn (sfk_destructor, type);
220 return TREE_NOTHROW (CLASSTYPE_DESTRUCTORS (type));
223 /* Build up a call to __cxa_end_catch, to destroy the exception object
224 for the current catch block if no others are currently using it. */
227 do_end_catch (tree type)
231 fn = get_identifier ("__cxa_end_catch");
232 if (!get_global_value_if_present (fn, &fn))
234 /* Declare void __cxa_end_catch (). */
235 fn = push_void_library_fn (fn, void_list_node);
236 /* This can throw if the destructor for the exception throws. */
237 TREE_NOTHROW (fn) = 0;
240 cleanup = cp_build_function_call (fn, NULL_TREE, tf_warning_or_error);
241 TREE_NOTHROW (cleanup) = dtor_nothrow (type);
246 /* This routine creates the cleanup for the current exception. */
249 push_eh_cleanup (tree type)
251 finish_decl_cleanup (NULL_TREE, do_end_catch (type));
254 /* Return nonzero value if DECL is a Java type suitable for catch or
258 decl_is_java_type (tree decl, int err)
260 bool r = (TREE_CODE (decl) == POINTER_TYPE
261 && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
262 && TYPE_FOR_JAVA (TREE_TYPE (decl)));
266 if (TREE_CODE (decl) == REFERENCE_TYPE
267 && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
268 && TYPE_FOR_JAVA (TREE_TYPE (decl)))
270 /* Can't throw a reference. */
271 error ("type %qT is disallowed in Java %<throw%> or %<catch%>",
278 = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jthrowable"));
280 if (jthrow_node == NULL_TREE)
282 ("call to Java %<catch%> or %<throw%> with %<jthrowable%> undefined");
284 jthrow_node = TREE_TYPE (TREE_TYPE (jthrow_node));
286 if (! DERIVED_FROM_P (jthrow_node, TREE_TYPE (decl)))
288 /* Thrown object must be a Throwable. */
289 error ("type %qT is not derived from %<java::lang::Throwable%>",
298 /* Select the personality routine to be used for exception handling,
299 or issue an error if we need two different ones in the same
301 ??? At present eh_personality_libfunc is set to
302 __gxx_personality_(sj|v)0 in init_exception_processing - should it
303 be done here instead? */
305 choose_personality_routine (enum languages lang)
320 if (lang != lang_cplusplus)
325 if (lang != lang_java)
330 ; /* Proceed to language selection. */
341 eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
342 ? "__gcj_personality_sj0"
343 : "__gcj_personality_v0");
352 error ("mixing C++ and Java catches in a single translation unit");
356 /* Initialize the catch parameter DECL. */
359 initialize_handler_parm (tree decl, tree exp)
364 /* Make sure we mark the catch param as used, otherwise we'll get a
365 warning about an unused ((anonymous)). */
366 TREE_USED (decl) = 1;
368 /* Figure out the type that the initializer is. Pointers are returned
369 adjusted by value from __cxa_begin_catch. Others are returned by
371 init_type = TREE_TYPE (decl);
372 if (!POINTER_TYPE_P (init_type))
373 init_type = build_reference_type (init_type);
375 choose_personality_routine (decl_is_java_type (init_type, 0)
376 ? lang_java : lang_cplusplus);
378 /* Since pointers are passed by value, initialize a reference to
379 pointer catch parm with the address of the temporary. */
380 if (TREE_CODE (init_type) == REFERENCE_TYPE
381 && TYPE_PTR_P (TREE_TYPE (init_type)))
382 exp = cp_build_unary_op (ADDR_EXPR, exp, 1, tf_warning_or_error);
384 exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
386 init = convert_from_reference (exp);
388 /* If the constructor for the catch parm exits via an exception, we
389 must call terminate. See eh23.C. */
390 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
392 /* Generate the copy constructor call directly so we can wrap it.
393 See also expand_default_init. */
394 init = ocp_convert (TREE_TYPE (decl), init,
395 CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
396 /* Force cleanups now to avoid nesting problems with the
397 MUST_NOT_THROW_EXPR. */
398 init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
399 init = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (init), init);
402 decl = pushdecl (decl);
404 start_decl_1 (decl, true);
405 cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE,
406 LOOKUP_ONLYCONVERTING|DIRECT_BIND);
409 /* Call this to start a catch block. DECL is the catch parameter. */
412 expand_start_catch_block (tree decl)
420 /* Make sure this declaration is reasonable. */
421 if (decl && !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl), NULL_TREE))
422 decl = error_mark_node;
425 type = prepare_eh_type (TREE_TYPE (decl));
429 if (decl && decl_is_java_type (type, 1))
431 /* Java only passes object via pointer and doesn't require
432 adjusting. The java object is immediately before the
433 generic exception header. */
434 exp = build_exc_ptr ();
435 exp = build1 (NOP_EXPR, build_pointer_type (type), exp);
436 exp = build2 (POINTER_PLUS_EXPR, TREE_TYPE (exp), exp,
437 fold_build1 (NEGATE_EXPR, sizetype,
438 TYPE_SIZE_UNIT (TREE_TYPE (exp))));
439 exp = cp_build_indirect_ref (exp, NULL, tf_warning_or_error);
440 initialize_handler_parm (decl, exp);
444 /* Call __cxa_end_catch at the end of processing the exception. */
445 push_eh_cleanup (type);
447 /* If there's no decl at all, then all we need to do is make sure
448 to tell the runtime that we've begun handling the exception. */
449 if (decl == NULL || decl == error_mark_node)
450 finish_expr_stmt (do_begin_catch ());
452 /* If the C++ object needs constructing, we need to do that before
453 calling __cxa_begin_catch, so that std::uncaught_exception gets
454 the right value during the copy constructor. */
455 else if (flag_use_cxa_get_exception_ptr
456 && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
458 exp = do_get_exception_ptr ();
459 initialize_handler_parm (decl, exp);
460 finish_expr_stmt (do_begin_catch ());
463 /* Otherwise the type uses a bitwise copy, and we don't have to worry
464 about the value of std::uncaught_exception and therefore can do the
465 copy with the return value of __cxa_end_catch instead. */
468 tree init = do_begin_catch ();
469 tree init_type = type;
471 /* Pointers are passed by values, everything else by reference. */
472 if (!TYPE_PTR_P (type))
473 init_type = build_pointer_type (type);
474 if (init_type != TREE_TYPE (init))
475 init = build1 (NOP_EXPR, init_type, init);
476 exp = create_temporary_var (init_type);
477 DECL_REGISTER (exp) = 1;
478 cp_finish_decl (exp, init, /*init_const_expr=*/false,
479 NULL_TREE, LOOKUP_ONLYCONVERTING);
480 initialize_handler_parm (decl, exp);
487 /* Call this to end a catch block. Its responsible for emitting the
488 code to handle jumping back to the correct place, and for emitting
489 the label to jump to if this catch block didn't match. */
492 expand_end_catch_block (void)
497 /* The exception being handled is rethrown if control reaches the end of
498 a handler of the function-try-block of a constructor or destructor. */
499 if (in_function_try_handler
500 && (DECL_CONSTRUCTOR_P (current_function_decl)
501 || DECL_DESTRUCTOR_P (current_function_decl)))
502 finish_expr_stmt (build_throw (NULL_TREE));
506 begin_eh_spec_block (void)
508 tree r = build_stmt (EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
510 EH_SPEC_STMTS (r) = push_stmt_list ();
515 finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
519 EH_SPEC_STMTS (eh_spec_block) = pop_stmt_list (EH_SPEC_STMTS (eh_spec_block));
521 /* Strip cv quals, etc, from the specification types. */
522 for (raises = NULL_TREE;
523 raw_raises && TREE_VALUE (raw_raises);
524 raw_raises = TREE_CHAIN (raw_raises))
526 tree type = prepare_eh_type (TREE_VALUE (raw_raises));
527 tree tinfo = eh_type_info (type);
530 raises = tree_cons (NULL_TREE, type, raises);
533 EH_SPEC_RAISES (eh_spec_block) = raises;
536 /* Return a pointer to a buffer for an exception object of type TYPE. */
539 do_allocate_exception (tree type)
543 fn = get_identifier ("__cxa_allocate_exception");
544 if (!get_global_value_if_present (fn, &fn))
546 /* Declare void *__cxa_allocate_exception(size_t). */
547 tree tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
548 fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
551 return cp_build_function_call (fn,
552 tree_cons (NULL_TREE, size_in_bytes (type),
554 tf_warning_or_error);
557 /* Call __cxa_free_exception from a cleanup. This is never invoked
558 directly, but see the comment for stabilize_throw_expr. */
561 do_free_exception (tree ptr)
565 fn = get_identifier ("__cxa_free_exception");
566 if (!get_global_value_if_present (fn, &fn))
568 /* Declare void __cxa_free_exception (void *). */
569 fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
573 return cp_build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE),
574 tf_warning_or_error);
577 /* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
578 Called from build_throw via walk_tree_without_duplicates. */
581 wrap_cleanups_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
582 void *data ATTRIBUTE_UNUSED)
587 /* Don't walk into types. */
593 if (TREE_CODE (exp) != TARGET_EXPR)
596 cleanup = TARGET_EXPR_CLEANUP (exp);
599 cleanup = build1 (MUST_NOT_THROW_EXPR, void_type_node, cleanup);
600 TARGET_EXPR_CLEANUP (exp) = cleanup;
603 /* Keep iterating. */
607 /* Build a throw expression. */
610 build_throw (tree exp)
614 if (exp == error_mark_node)
617 if (processing_template_decl)
620 current_function_returns_abnormally = 1;
621 return build_min (THROW_EXPR, void_type_node, exp);
624 if (exp == null_node)
625 warning (0, "throwing NULL, which has integral, not pointer type");
627 if (exp != NULL_TREE)
629 if (!is_admissible_throw_operand (exp))
630 return error_mark_node;
634 return error_mark_node;
636 if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
638 tree fn = get_identifier ("_Jv_Throw");
639 if (!get_global_value_if_present (fn, &fn))
641 /* Declare void _Jv_Throw (void *). */
642 tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
643 tmp = build_function_type (ptr_type_node, tmp);
644 fn = push_throw_library_fn (fn, tmp);
646 else if (really_overloaded_fn (fn))
648 error ("%qD should never be overloaded", fn);
649 return error_mark_node;
651 fn = OVL_CURRENT (fn);
652 exp = cp_build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE),
653 tf_warning_or_error);
662 tree temp_expr, allocate_expr;
665 /* The CLEANUP_TYPE is the internal type of a destructor. */
668 tmp = void_list_node;
669 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
670 tmp = build_function_type (void_type_node, tmp);
671 cleanup_type = build_pointer_type (tmp);
674 fn = get_identifier ("__cxa_throw");
675 if (!get_global_value_if_present (fn, &fn))
677 /* Declare void __cxa_throw (void*, void*, void (*)(void*)). */
678 /* ??? Second argument is supposed to be "std::type_info*". */
679 tmp = void_list_node;
680 tmp = tree_cons (NULL_TREE, cleanup_type, tmp);
681 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
682 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
683 tmp = build_function_type (void_type_node, tmp);
684 fn = push_throw_library_fn (fn, tmp);
689 A throw-expression initializes a temporary object, the type
690 of which is determined by removing any top-level
691 cv-qualifiers from the static type of the operand of throw
692 and adjusting the type from "array of T" or "function return
693 T" to "pointer to T" or "pointer to function returning T"
695 temp_type = is_bitfield_expr_with_lowered_type (exp);
697 temp_type = type_decays_to (TREE_TYPE (exp));
699 /* OK, this is kind of wacky. The standard says that we call
700 terminate when the exception handling mechanism, after
701 completing evaluation of the expression to be thrown but
702 before the exception is caught (_except.throw_), calls a
703 user function that exits via an uncaught exception.
705 So we have to protect the actual initialization of the
706 exception object with terminate(), but evaluate the
707 expression first. Since there could be temps in the
708 expression, we need to handle that, too. We also expand
709 the call to __cxa_allocate_exception first (which doesn't
710 matter, since it can't throw). */
712 /* Allocate the space for the exception. */
713 allocate_expr = do_allocate_exception (temp_type);
714 allocate_expr = get_target_expr (allocate_expr);
715 ptr = TARGET_EXPR_SLOT (allocate_expr);
716 object = build_nop (build_pointer_type (temp_type), ptr);
717 object = cp_build_indirect_ref (object, NULL, tf_warning_or_error);
719 elided = (TREE_CODE (exp) == TARGET_EXPR);
721 /* And initialize the exception object. */
722 if (CLASS_TYPE_P (temp_type))
724 int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
726 /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes
727 treated as an rvalue for the purposes of overload resolution
728 to favor move constructors over copy constructors. */
729 if (/* Must be a local, automatic variable. */
730 TREE_CODE (exp) == VAR_DECL
731 && DECL_CONTEXT (exp) == current_function_decl
732 && ! TREE_STATIC (exp)
733 /* The variable must not have the `volatile' qualifier. */
734 && !(cp_type_quals (TREE_TYPE (exp)) & TYPE_QUAL_VOLATILE))
735 flags = flags | LOOKUP_PREFER_RVALUE;
737 /* Call the copy constructor. */
738 exp = (build_special_member_call
739 (object, complete_ctor_identifier,
740 build_tree_list (NULL_TREE, exp),
742 flags, tf_warning_or_error));
743 if (exp == error_mark_node)
745 error (" in thrown expression");
746 return error_mark_node;
750 exp = build2 (INIT_EXPR, temp_type, object,
751 decay_conversion (exp));
753 /* Pre-evaluate the thrown expression first, since if we allocated
754 the space first we would have to deal with cleaning it up if
755 evaluating this expression throws.
757 The case where EXP the initializer is a cast or a function
758 returning a class is a bit of a grey area in the standard; it's
759 unclear whether or not it should be allowed to throw. We used to
760 say no, as that allowed us to optimize this case without worrying
761 about deallocating the exception object if it does. But that
762 conflicted with expectations (PR 13944) and the EDG compiler; now
763 we wrap the initialization in a TRY_CATCH_EXPR to call
764 do_free_exception rather than in a MUST_NOT_THROW_EXPR, for this
767 BUT: Issue 475 may do away with this inconsistency by removing the
768 terminate() in this situation.
770 Note that we don't check the return value from stabilize_init
771 because it will only return false in cases where elided is true,
772 and therefore we don't need to work around the failure to
774 temp_expr = NULL_TREE;
775 stabilize_init (exp, &temp_expr);
777 /* Wrap the initialization in a CLEANUP_POINT_EXPR so that cleanups
778 for temporaries within the initialization are run before the one
779 for the exception object, preserving LIFO order. */
780 exp = build1 (CLEANUP_POINT_EXPR, void_type_node, exp);
783 exp = build2 (TRY_CATCH_EXPR, void_type_node, exp,
784 do_free_exception (ptr));
786 exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
788 /* Prepend the allocation. */
789 exp = build2 (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
792 /* Prepend the calculation of the throw expression. Also, force
793 any cleanups from the expression to be evaluated here so that
794 we don't have to do them during unwinding. But first wrap
795 them in MUST_NOT_THROW_EXPR, since they are run after the
796 exception object is initialized. */
797 cp_walk_tree_without_duplicates (&temp_expr, wrap_cleanups_r, 0);
798 exp = build2 (COMPOUND_EXPR, TREE_TYPE (exp), temp_expr, exp);
799 exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
802 throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
804 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object)))
806 cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
807 complete_dtor_identifier, 0);
808 cleanup = BASELINK_FUNCTIONS (cleanup);
810 cxx_mark_addressable (cleanup);
811 /* Pretend it's a normal function. */
812 cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);
815 cleanup = build_int_cst (cleanup_type, 0);
817 tmp = tree_cons (NULL_TREE, cleanup, NULL_TREE);
818 tmp = tree_cons (NULL_TREE, throw_type, tmp);
819 tmp = tree_cons (NULL_TREE, ptr, tmp);
820 /* ??? Indicate that this function call throws throw_type. */
821 tmp = cp_build_function_call (fn, tmp, tf_warning_or_error);
823 /* Tack on the initialization stuff. */
824 exp = build2 (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp);
828 /* Rethrow current exception. */
830 tree fn = get_identifier ("__cxa_rethrow");
831 if (!get_global_value_if_present (fn, &fn))
833 /* Declare void __cxa_rethrow (void). */
834 fn = push_throw_library_fn
835 (fn, build_function_type (void_type_node, void_list_node));
838 /* ??? Indicate that this function call allows exceptions of the type
839 of the enclosing catch block (if known). */
840 exp = cp_build_function_call (fn, NULL_TREE, tf_warning_or_error);
843 exp = build1 (THROW_EXPR, void_type_node, exp);
848 /* Make sure TYPE is complete, pointer to complete, reference to
849 complete, or pointer to cv void. Issue diagnostic on failure.
850 Return the zero on failure and nonzero on success. FROM can be
851 the expr or decl from whence TYPE came, if available. */
854 complete_ptr_ref_or_void_ptr_p (tree type, tree from)
858 /* Check complete. */
859 type = complete_type_or_else (type, from);
863 /* Or a pointer or ref to one, or cv void *. */
864 is_ptr = TREE_CODE (type) == POINTER_TYPE;
865 if (is_ptr || TREE_CODE (type) == REFERENCE_TYPE)
867 tree core = TREE_TYPE (type);
869 if (is_ptr && VOID_TYPE_P (core))
871 else if (!complete_type_or_else (core, from))
877 /* Return truth-value if EXPRESSION is admissible in throw-expression,
878 i.e. if it is not of incomplete type or a pointer/reference to such
879 a type or of an abstract class type. */
882 is_admissible_throw_operand (tree expr)
884 tree type = TREE_TYPE (expr);
886 /* 15.1/4 [...] The type of the throw-expression shall not be an
887 incomplete type, or a pointer or a reference to an incomplete
888 type, other than void*, const void*, volatile void*, or
889 const volatile void*. Except for these restriction and the
890 restrictions on type matching mentioned in 15.3, the operand
891 of throw is treated exactly as a function argument in a call
892 (5.2.2) or the operand of a return statement. */
893 if (!complete_ptr_ref_or_void_ptr_p (type, expr))
896 /* 10.4/3 An abstract class shall not be used as a parameter type,
897 as a function return type or as type of an explicit
899 else if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type))
901 error ("expression %qE of abstract class type %qT cannot "
902 "be used in throw-expression", expr, type);
909 /* Returns nonzero if FN is a declaration of a standard C library
910 function which is known not to throw.
912 [lib.res.on.exception.handling]: None of the functions from the
913 Standard C library shall report an error by throwing an
914 exception, unless it calls a program-supplied function that
915 throws an exception. */
920 nothrow_libfn_p (const_tree fn)
925 && DECL_EXTERNAL (fn)
926 && DECL_NAMESPACE_SCOPE_P (fn)
927 && DECL_EXTERN_C_P (fn))
930 /* Can't be a C library function. */
933 /* Being a C library function, DECL_ASSEMBLER_NAME == DECL_NAME
934 unless the system headers are playing rename tricks, and if
935 they are, we don't want to be confused by them. */
937 return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
940 /* Returns nonzero if an exception of type FROM will be caught by a
941 handler for type TO, as per [except.handle]. */
944 can_convert_eh (tree to, tree from)
946 to = non_reference (to);
947 from = non_reference (from);
949 if (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
952 from = TREE_TYPE (from);
954 if (! at_least_as_qualified_p (to, from))
957 if (TREE_CODE (to) == VOID_TYPE)
960 /* Else fall through. */
963 if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
964 && PUBLICLY_UNIQUELY_DERIVED_P (to, from))
970 /* Check whether any of the handlers in I are shadowed by another handler
971 accepting TYPE. Note that the shadowing may not be complete; even if
972 an exception of type B would be caught by a handler for A, there could
973 be a derived class C for which A is an ambiguous base but B is not, so
974 the handler for B would catch an exception of type C. */
977 check_handlers_1 (tree master, tree_stmt_iterator i)
979 tree type = TREE_TYPE (master);
981 for (; !tsi_end_p (i); tsi_next (&i))
983 tree handler = tsi_stmt (i);
984 if (TREE_TYPE (handler) && can_convert_eh (type, TREE_TYPE (handler)))
986 warning (0, "%Hexception of type %qT will be caught",
987 EXPR_LOCUS (handler), TREE_TYPE (handler));
988 warning (0, "%H by earlier handler for %qT",
989 EXPR_LOCUS (master), type);
995 /* Given a STATEMENT_LIST of HANDLERs, make sure that they're OK. */
998 check_handlers (tree handlers)
1000 tree_stmt_iterator i;
1002 /* If we don't have a STATEMENT_LIST, then we've just got one
1003 handler, and thus nothing to warn about. */
1004 if (TREE_CODE (handlers) != STATEMENT_LIST)
1007 i = tsi_start (handlers);
1011 tree handler = tsi_stmt (i);
1014 /* No more handlers; nothing to shadow. */
1017 if (TREE_TYPE (handler) == NULL_TREE)
1018 pedwarn ("%H%<...%> handler must be the last handler for"
1019 " its try block", EXPR_LOCUS (handler));
1021 check_handlers_1 (handler, i);