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. */
38 static void push_eh_cleanup PARAMS ((tree));
39 static tree prepare_eh_type PARAMS ((tree));
40 static tree build_eh_type_type PARAMS ((tree));
41 static tree do_begin_catch PARAMS ((void));
42 static int dtor_nothrow PARAMS ((tree));
43 static tree do_end_catch PARAMS ((tree));
44 static void push_eh_cleanup PARAMS ((tree));
45 static bool decl_is_java_type PARAMS ((tree decl, int err));
46 static void initialize_handler_parm PARAMS ((tree, tree));
47 static tree do_allocate_exception PARAMS ((tree));
48 static int complete_ptr_ref_or_void_ptr_p PARAMS ((tree, tree));
49 static bool is_admissible_throw_operand PARAMS ((tree));
50 static int can_convert_eh PARAMS ((tree, tree));
51 static void check_handlers_1 PARAMS ((tree, tree));
52 static tree cp_protect_cleanup_actions PARAMS ((void));
57 /* Sets up all the global eh stuff that needs to be initialized at the
58 start of compilation. */
61 init_exception_processing ()
66 push_namespace (std_identifier);
68 /* void std::terminate (); */
69 tmp = build_function_type (void_type_node, void_list_node);
70 terminate_node = build_cp_library_fn_ptr ("terminate", tmp);
71 TREE_THIS_VOLATILE (terminate_node) = 1;
72 TREE_NOTHROW (terminate_node) = 1;
76 /* void __cxa_call_unexpected(void *); */
77 tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
78 tmp = build_function_type (void_type_node, tmp);
80 = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
82 eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
83 ? "__gxx_personality_sj0"
84 : "__gxx_personality_v0");
86 lang_eh_runtime_type = build_eh_type_type;
87 lang_protect_cleanup_actions = &cp_protect_cleanup_actions;
90 /* Returns an expression to be executed if an unhandled exception is
91 propogated out of a cleanup region. */
94 cp_protect_cleanup_actions ()
98 When the destruction of an object during stack unwinding exits
99 using an exception ... void terminate(); is called. */
100 return build_call (terminate_node, NULL_TREE);
104 prepare_eh_type (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 if (TREE_CODE (type) == REFERENCE_TYPE)
114 type = TREE_TYPE (type);
116 /* Peel off cv qualifiers. */
117 type = TYPE_MAIN_VARIANT (type);
122 /* Build the address of a typeinfo decl for use in the runtime
123 matching field of the exception model. */
126 build_eh_type_type (type)
131 if (type == NULL_TREE || type == error_mark_node)
134 if (decl_is_java_type (type, 0))
135 exp = build_java_class_ref (TREE_TYPE (type));
137 exp = get_tinfo_decl (type);
140 exp = build1 (ADDR_EXPR, ptr_type_node, exp);
148 return build (EXC_PTR_EXPR, ptr_type_node);
151 /* Build up a call to __cxa_begin_catch, to tell the runtime that the
152 exception has been handled. */
159 fn = get_identifier ("__cxa_begin_catch");
160 if (IDENTIFIER_GLOBAL_VALUE (fn))
161 fn = IDENTIFIER_GLOBAL_VALUE (fn);
164 /* Declare void* __cxa_begin_catch (void *). */
165 tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
166 fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
169 return build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
173 /* Returns nonzero if cleaning up an exception of type TYPE (which can be
174 NULL_TREE for a ... handler) will not throw an exception. */
182 if (type == NULL_TREE)
185 if (! TYPE_HAS_DESTRUCTOR (type))
188 fn = lookup_member (type, dtor_identifier, 0, 0);
189 fn = TREE_VALUE (fn);
190 return TREE_NOTHROW (fn);
193 /* Build up a call to __cxa_end_catch, to destroy the exception object
194 for the current catch block if no others are currently using it. */
202 fn = get_identifier ("__cxa_end_catch");
203 if (IDENTIFIER_GLOBAL_VALUE (fn))
204 fn = IDENTIFIER_GLOBAL_VALUE (fn);
207 /* Declare void __cxa_end_catch (). */
208 fn = push_void_library_fn (fn, void_list_node);
209 /* This can throw if the destructor for the exception throws. */
210 TREE_NOTHROW (fn) = 0;
213 cleanup = build_function_call (fn, NULL_TREE);
214 TREE_NOTHROW (cleanup) = dtor_nothrow (type);
219 /* This routine creates the cleanup for the current exception. */
222 push_eh_cleanup (type)
225 finish_decl_cleanup (NULL_TREE, do_end_catch (type));
228 /* Return nonzero value if DECL is a Java type suitable for catch or
232 decl_is_java_type (decl, err)
236 bool r = (TREE_CODE (decl) == POINTER_TYPE
237 && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
238 && TYPE_FOR_JAVA (TREE_TYPE (decl)));
242 if (TREE_CODE (decl) == REFERENCE_TYPE
243 && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
244 && TYPE_FOR_JAVA (TREE_TYPE (decl)))
246 /* Can't throw a reference. */
247 cp_error ("type `%T' is disallowed in Java `throw' or `catch'",
254 = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jthrowable"));
256 if (jthrow_node == NULL_TREE)
258 ("call to Java `catch' or `throw' with `jthrowable' undefined");
260 jthrow_node = TREE_TYPE (TREE_TYPE (jthrow_node));
262 if (! DERIVED_FROM_P (jthrow_node, TREE_TYPE (decl)))
264 /* Thrown object must be a Throwable. */
265 cp_error ("type `%T' is not derived from `java::lang::Throwable'",
274 /* Select the personality routine to be used for exception handling,
275 or issue an error if we need two different ones in the same
277 ??? At present eh_personality_libfunc is set to
278 __gxx_personality_(sj|v)0 in init_exception_processing - should it
279 be done here instead? */
281 choose_personality_routine (lang)
297 if (lang != lang_cplusplus)
302 if (lang != lang_java)
307 ; /* proceed to language selection */
318 eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
319 ? "__gcj_personality_sj0"
320 : "__gcj_personality_v0");
329 error ("mixing C++ and Java catches in a single translation unit");
333 /* Initialize the catch parameter DECL. */
336 initialize_handler_parm (decl, exp)
343 /* Make sure we mark the catch param as used, otherwise we'll get a
344 warning about an unused ((anonymous)). */
345 TREE_USED (decl) = 1;
347 /* Figure out the type that the initializer is. Pointers are returned
348 adjusted by value from __cxa_begin_catch. Others are returned by
350 init_type = TREE_TYPE (decl);
351 if (TREE_CODE (init_type) != POINTER_TYPE
352 && TREE_CODE (init_type) != REFERENCE_TYPE)
353 init_type = build_reference_type (init_type);
355 choose_personality_routine (decl_is_java_type (init_type, 0)
356 ? lang_java : lang_cplusplus);
358 /* Since pointers are passed by value, initialize a reference to
359 pointer catch parm with the address of the temporary. */
360 if (TREE_CODE (init_type) == REFERENCE_TYPE
361 && TREE_CODE (TREE_TYPE (init_type)) == POINTER_TYPE)
362 exp = build_unary_op (ADDR_EXPR, exp, 1);
364 exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
366 init = convert_from_reference (exp);
368 /* If the constructor for the catch parm exits via an exception, we
369 must call terminate. See eh23.C. */
370 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
372 /* Generate the copy constructor call directly so we can wrap it.
373 See also expand_default_init. */
374 init = ocp_convert (TREE_TYPE (decl), init,
375 CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
376 init = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (init), init);
379 /* Let `cp_finish_decl' know that this initializer is ok. */
380 DECL_INITIAL (decl) = error_mark_node;
381 decl = pushdecl (decl);
384 cp_finish_decl (decl, init, NULL_TREE,
385 LOOKUP_ONLYCONVERTING|DIRECT_BIND);
388 /* Call this to start a catch block. DECL is the catch parameter. */
391 expand_start_catch_block (decl)
394 tree exp = NULL_TREE;
401 /* Make sure this declaration is reasonable. */
402 if (decl && !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl), NULL_TREE))
406 type = prepare_eh_type (TREE_TYPE (decl));
415 if (decl_is_java_type (type, 1))
417 /* Java only passes object via pointer and doesn't require
418 adjusting. The java object is immediately before the
419 generic exception header. */
420 init = build_exc_ptr ();
421 init = build1 (NOP_EXPR, build_pointer_type (type), init);
422 init = build (MINUS_EXPR, TREE_TYPE (init), init,
423 TYPE_SIZE_UNIT (TREE_TYPE (init)));
424 init = build_indirect_ref (init, NULL);
429 /* C++ requires that we call __cxa_begin_catch to get the
430 pointer to the actual object. */
431 init = do_begin_catch ();
434 exp = create_temporary_var (ptr_type_node);
435 DECL_REGISTER (exp) = 1;
436 cp_finish_decl (exp, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
437 finish_expr_stmt (build_modify_expr (exp, INIT_EXPR, init));
440 finish_expr_stmt (do_begin_catch ());
442 /* C++ requires that we call __cxa_end_catch at the end of
443 processing the exception. */
445 push_eh_cleanup (type);
448 initialize_handler_parm (decl, exp);
454 /* Call this to end a catch block. Its responsible for emitting the
455 code to handle jumping back to the correct place, and for emitting
456 the label to jump to if this catch block didn't match. */
459 expand_end_catch_block ()
464 /* The exception being handled is rethrown if control reaches the end of
465 a handler of the function-try-block of a constructor or destructor. */
466 if (in_function_try_handler
467 && (DECL_CONSTRUCTOR_P (current_function_decl)
468 || DECL_DESTRUCTOR_P (current_function_decl)))
469 finish_expr_stmt (build_throw (NULL_TREE));
473 begin_eh_spec_block ()
475 tree r = build_stmt (EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
481 finish_eh_spec_block (raw_raises, eh_spec_block)
487 RECHAIN_STMTS (eh_spec_block, EH_SPEC_STMTS (eh_spec_block));
489 /* Strip cv quals, etc, from the specification types. */
490 for (raises = NULL_TREE;
491 raw_raises && TREE_VALUE (raw_raises);
492 raw_raises = TREE_CHAIN (raw_raises))
493 raises = tree_cons (NULL_TREE, prepare_eh_type (TREE_VALUE (raw_raises)),
496 EH_SPEC_RAISES (eh_spec_block) = raises;
499 /* Return a pointer to a buffer for an exception object of type TYPE. */
502 do_allocate_exception (type)
507 fn = get_identifier ("__cxa_allocate_exception");
508 if (IDENTIFIER_GLOBAL_VALUE (fn))
509 fn = IDENTIFIER_GLOBAL_VALUE (fn);
512 /* Declare void *__cxa_allocate_exception(size_t). */
513 tree tmp = tree_cons (NULL_TREE, c_size_type_node, void_list_node);
514 fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
517 return build_function_call (fn, tree_cons (NULL_TREE, size_in_bytes (type),
522 /* Call __cxa_free_exception from a cleanup. This is never invoked
526 do_free_exception (ptr)
531 fn = get_identifier ("__cxa_free_exception");
532 if (IDENTIFIER_GLOBAL_VALUE (fn))
533 fn = IDENTIFIER_GLOBAL_VALUE (fn);
536 /* Declare void __cxa_free_exception (void *). */
537 fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
541 return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
545 /* Build a throw expression. */
553 if (exp == error_mark_node)
556 if (processing_template_decl)
557 return build_min (THROW_EXPR, void_type_node, exp);
559 if (exp == null_node)
560 cp_warning ("throwing NULL, which has integral, not pointer type");
562 if (exp != NULL_TREE)
564 if (!is_admissible_throw_operand (exp))
565 return error_mark_node;
569 return error_mark_node;
571 if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
573 tree fn = get_identifier ("_Jv_Throw");
574 if (IDENTIFIER_GLOBAL_VALUE (fn))
575 fn = IDENTIFIER_GLOBAL_VALUE (fn);
578 /* Declare void _Jv_Throw (void *). */
579 tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
580 tmp = build_function_type (ptr_type_node, tmp);
581 fn = push_throw_library_fn (fn, tmp);
584 exp = build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE));
595 fn = get_identifier ("__cxa_throw");
596 if (IDENTIFIER_GLOBAL_VALUE (fn))
597 fn = IDENTIFIER_GLOBAL_VALUE (fn);
600 /* The CLEANUP_TYPE is the internal type of a destructor. */
601 if (cleanup_type == NULL_TREE)
603 tmp = void_list_node;
604 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
605 tmp = build_function_type (void_type_node, tmp);
606 cleanup_type = build_pointer_type (tmp);
609 /* Declare void __cxa_throw (void*, void*, void (*)(void*)). */
610 /* ??? Second argument is supposed to be "std::type_info*". */
611 tmp = void_list_node;
612 tmp = tree_cons (NULL_TREE, cleanup_type, tmp);
613 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
614 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
615 tmp = build_function_type (void_type_node, tmp);
616 fn = push_throw_library_fn (fn, tmp);
619 begin_init_stmts (&stmt_expr, &compound_stmt);
621 /* throw expression */
622 /* First, decay it. */
623 exp = decay_conversion (exp);
625 /* OK, this is kind of wacky. The standard says that we call
626 terminate when the exception handling mechanism, after
627 completing evaluation of the expression to be thrown but
628 before the exception is caught (_except.throw_), calls a
629 user function that exits via an uncaught exception.
631 So we have to protect the actual initialization of the
632 exception object with terminate(), but evaluate the
633 expression first. Since there could be temps in the
634 expression, we need to handle that, too. We also expand
635 the call to __cxa_allocate_exception first (which doesn't
636 matter, since it can't throw). */
638 my_friendly_assert (stmts_are_full_exprs_p () == 1, 19990926);
640 /* Store the throw expression into a temp. This can be less
641 efficient than storing it into the allocated space directly, but
642 if we allocated the space first we would have to deal with
643 cleaning it up if evaluating this expression throws. */
644 if (TREE_SIDE_EFFECTS (exp))
646 tmp = create_temporary_var (TREE_TYPE (exp));
647 DECL_INITIAL (tmp) = exp;
648 cp_finish_decl (tmp, exp, NULL_TREE, LOOKUP_ONLYCONVERTING);
652 /* Allocate the space for the exception. */
653 ptr = create_temporary_var (ptr_type_node);
654 DECL_REGISTER (ptr) = 1;
655 cp_finish_decl (ptr, NULL_TREE, NULL_TREE, LOOKUP_ONLYCONVERTING);
656 tmp = do_allocate_exception (TREE_TYPE (exp));
657 tmp = build_modify_expr (ptr, INIT_EXPR, tmp);
658 finish_expr_stmt (tmp);
660 object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
661 object = build_indirect_ref (object, NULL);
663 exp = build_modify_expr (object, INIT_EXPR, exp);
664 if (exp == error_mark_node)
665 error (" in thrown expression");
667 exp = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (exp), exp);
668 finish_expr_stmt (exp);
670 throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
672 if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (object)))
674 cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
675 complete_dtor_identifier, 0);
676 cleanup = TREE_VALUE (cleanup);
678 mark_addressable (cleanup);
679 /* Pretend it's a normal function. */
680 cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);
684 cleanup = build_int_2 (0, 0);
685 TREE_TYPE (cleanup) = cleanup_type;
688 tmp = tree_cons (NULL_TREE, cleanup, NULL_TREE);
689 tmp = tree_cons (NULL_TREE, throw_type, tmp);
690 tmp = tree_cons (NULL_TREE, ptr, tmp);
691 tmp = build_function_call (fn, tmp);
693 /* ??? Indicate that this function call throws throw_type. */
695 finish_expr_stmt (tmp);
697 exp = finish_init_stmts (stmt_expr, compound_stmt);
701 /* Rethrow current exception. */
703 tree fn = get_identifier ("__cxa_rethrow");
704 if (IDENTIFIER_GLOBAL_VALUE (fn))
705 fn = IDENTIFIER_GLOBAL_VALUE (fn);
708 /* Declare void __cxa_rethrow (void). */
709 fn = push_throw_library_fn
710 (fn, build_function_type (void_type_node, void_list_node));
713 exp = build_function_call (fn, NULL_TREE);
716 exp = build1 (THROW_EXPR, void_type_node, exp);
721 /* Make sure TYPE is complete, pointer to complete, reference to
722 complete, or pointer to cv void. Issue diagnostic on failure.
723 Return the zero on failure and non-zero on success. FROM can be
724 the expr or decl from whence TYPE came, if available. */
727 complete_ptr_ref_or_void_ptr_p (type, from)
733 /* Check complete. */
734 type = complete_type_or_else (type, from);
738 /* Or a pointer or ref to one, or cv void *. */
739 is_ptr = TREE_CODE (type) == POINTER_TYPE;
740 if (is_ptr || TREE_CODE (type) == REFERENCE_TYPE)
742 tree core = TREE_TYPE (type);
744 if (is_ptr && VOID_TYPE_P (core))
746 else if (!complete_type_or_else (core, from))
752 /* Return truth-value if EXPRESSION is admissible in throw-expression,
753 i.e. if it is not of incomplete type or a pointer/reference to such
754 a type or of an abstract class type. */
757 is_admissible_throw_operand (expr)
760 tree type = TREE_TYPE (expr);
762 /* 15.1/4 [...] The type of the throw-expression shall not be an
763 incomplete type, or a pointer or a reference to an incomplete
764 type, other than void*, const void*, volatile void*, or
765 const volatile void*. Except for these restriction and the
766 restrictions on type matching mentioned in 15.3, the operand
767 of throw is treated exactly as a function argument in a call
768 (5.2.2) or the operand of a return statement. */
769 if (!complete_ptr_ref_or_void_ptr_p (type, expr))
772 /* 10.4/3 An abstract class shall not be used as a parameter type,
773 as a function return type or as type of an explicit
775 else if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type))
777 cp_error ("Expression '%E' of abstract class type '%T' cannot be used in throw-expression", expr, type);
784 /* Returns nonzero if FN is a declaration of a standard C library
785 function which is known not to throw.
787 [lib.res.on.exception.handling]: None of the functions from the
788 Standard C library shall report an error by throwing an
789 exception, unless it calls a program-supplied function that
790 throws an exception. */
801 && DECL_EXTERNAL (fn)
802 && DECL_NAMESPACE_SCOPE_P (fn)
803 && DECL_EXTERN_C_P (fn))
806 /* Can't be a C library function. */
809 id = DECL_ASSEMBLER_NAME (fn);
810 return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
813 /* Returns nonzero if an exception of type FROM will be caught by a
814 handler for type TO, as per [except.handle]. */
817 can_convert_eh (to, from)
820 if (TREE_CODE (to) == REFERENCE_TYPE)
822 if (TREE_CODE (from) == REFERENCE_TYPE)
823 from = TREE_TYPE (from);
825 if (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
828 from = TREE_TYPE (from);
830 if (! at_least_as_qualified_p (to, from))
833 if (TREE_CODE (to) == VOID_TYPE)
836 /* else fall through */
839 if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
840 && PUBLICLY_UNIQUELY_DERIVED_P (to, from))
846 /* Check whether any of HANDLERS are shadowed by another handler accepting
847 TYPE. Note that the shadowing may not be complete; even if an exception
848 of type B would be caught by a handler for A, there could be a derived
849 class C for which A is an ambiguous base but B is not, so the handler
850 for B would catch an exception of type C. */
853 check_handlers_1 (master, handlers)
857 tree type = TREE_TYPE (master);
860 for (handler = handlers; handler; handler = TREE_CHAIN (handler))
861 if (TREE_TYPE (handler)
862 && can_convert_eh (type, TREE_TYPE (handler)))
864 lineno = STMT_LINENO (handler);
865 cp_warning ("exception of type `%T' will be caught",
866 TREE_TYPE (handler));
867 lineno = STMT_LINENO (master);
868 cp_warning (" by earlier handler for `%T'", type);
873 /* Given a chain of HANDLERs, make sure that they're OK. */
876 check_handlers (handlers)
880 int save_line = lineno;
881 for (handler = handlers; handler; handler = TREE_CHAIN (handler))
883 if (TREE_CHAIN (handler) == NULL_TREE)
884 /* No more handlers; nothing to shadow. */;
885 else if (TREE_TYPE (handler) == NULL_TREE)
887 lineno = STMT_LINENO (handler);
889 ("`...' handler must be the last handler for its try block");
892 check_handlers_1 (handler, TREE_CHAIN (handler));