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, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Michael Tiemann <tiemann@cygnus.com>
6 Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
7 initial re-implementation courtesy Tad Hunt.
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3, or (at your option)
16 GCC is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING3. If not see
23 <http://www.gnu.org/licenses/>. */
28 #include "coretypes.h"
36 #include "tree-inline.h"
37 #include "tree-iterator.h"
41 static void push_eh_cleanup (tree);
42 static tree prepare_eh_type (tree);
43 static tree do_begin_catch (void);
44 static int dtor_nothrow (tree);
45 static tree do_end_catch (tree);
46 static bool decl_is_java_type (tree decl, int err);
47 static void initialize_handler_parm (tree, tree);
48 static tree do_allocate_exception (tree);
49 static tree wrap_cleanups_r (tree *, int *, void *);
50 static int complete_ptr_ref_or_void_ptr_p (tree, tree);
51 static bool is_admissible_throw_operand (tree);
52 static int can_convert_eh (tree, tree);
53 static tree cp_protect_cleanup_actions (void);
55 /* Sets up all the global eh stuff that needs to be initialized at the
56 start of compilation. */
59 init_exception_processing (void)
63 /* void std::terminate (); */
64 push_namespace (std_identifier);
65 tmp = build_function_type (void_type_node, void_list_node);
66 terminate_node = build_cp_library_fn_ptr ("terminate", tmp);
67 TREE_THIS_VOLATILE (terminate_node) = 1;
68 TREE_NOTHROW (terminate_node) = 1;
71 /* void __cxa_call_unexpected(void *); */
72 tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
73 tmp = build_function_type (void_type_node, tmp);
75 = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
77 lang_protect_cleanup_actions = &cp_protect_cleanup_actions;
80 /* Returns an expression to be executed if an unhandled exception is
81 propagated out of a cleanup region. */
84 cp_protect_cleanup_actions (void)
88 When the destruction of an object during stack unwinding exits
89 using an exception ... void terminate(); is called. */
90 return terminate_node;
94 prepare_eh_type (tree type)
96 if (type == NULL_TREE)
98 if (type == error_mark_node)
99 return error_mark_node;
101 /* peel back references, so they match. */
102 type = non_reference (type);
104 /* Peel off cv qualifiers. */
105 type = TYPE_MAIN_VARIANT (type);
107 /* Functions and arrays decay to pointers. */
108 type = type_decays_to (type);
113 /* Return the type info for TYPE as used by EH machinery. */
115 eh_type_info (tree type)
119 if (type == NULL_TREE || type == error_mark_node)
122 if (decl_is_java_type (type, 0))
123 exp = build_java_class_ref (TREE_TYPE (type));
125 exp = get_tinfo_decl (type);
130 /* Build the address of a typeinfo decl for use in the runtime
131 matching field of the exception model. */
134 build_eh_type_type (tree type)
136 tree exp = eh_type_info (type);
143 return convert (ptr_type_node, build_address (exp));
149 return build_call_n (built_in_decls [BUILT_IN_EH_POINTER],
150 1, integer_zero_node);
153 /* Declare a function NAME, returning RETURN_TYPE, taking a single
154 parameter PARM_TYPE, with an empty exception specification.
156 Note that the C++ ABI document does not have a throw-specifier on
157 the routines declared below via this function. The declarations
158 are consistent with the actual implementations in libsupc++. */
161 declare_nothrow_library_fn (tree name, tree return_type, tree parm_type)
163 tree tmp = tree_cons (NULL_TREE, parm_type, void_list_node);
164 return push_library_fn (name, build_function_type (return_type, tmp),
168 /* Build up a call to __cxa_get_exception_ptr so that we can build a
169 copy constructor for the thrown object. */
172 do_get_exception_ptr (void)
176 fn = get_identifier ("__cxa_get_exception_ptr");
177 if (!get_global_value_if_present (fn, &fn))
179 /* Declare void* __cxa_get_exception_ptr (void *) throw(). */
180 fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
183 return cp_build_function_call_nary (fn, tf_warning_or_error,
184 build_exc_ptr (), NULL_TREE);
187 /* Build up a call to __cxa_begin_catch, to tell the runtime that the
188 exception has been handled. */
191 do_begin_catch (void)
195 fn = get_identifier ("__cxa_begin_catch");
196 if (!get_global_value_if_present (fn, &fn))
198 /* Declare void* __cxa_begin_catch (void *) throw(). */
199 fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
202 return cp_build_function_call_nary (fn, tf_warning_or_error,
203 build_exc_ptr (), NULL_TREE);
206 /* Returns nonzero if cleaning up an exception of type TYPE (which can be
207 NULL_TREE for a ... handler) will not throw an exception. */
210 dtor_nothrow (tree type)
212 if (type == NULL_TREE || type == error_mark_node)
215 if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
218 if (CLASSTYPE_LAZY_DESTRUCTOR (type))
219 lazily_declare_fn (sfk_destructor, type);
221 return TREE_NOTHROW (CLASSTYPE_DESTRUCTORS (type));
224 /* Build up a call to __cxa_end_catch, to destroy the exception object
225 for the current catch block if no others are currently using it. */
228 do_end_catch (tree type)
232 fn = get_identifier ("__cxa_end_catch");
233 if (!get_global_value_if_present (fn, &fn))
235 /* Declare void __cxa_end_catch (). */
236 fn = push_void_library_fn (fn, void_list_node);
237 /* This can throw if the destructor for the exception throws. */
238 TREE_NOTHROW (fn) = 0;
241 cleanup = cp_build_function_call_vec (fn, NULL, tf_warning_or_error);
242 TREE_NOTHROW (cleanup) = dtor_nothrow (type);
247 /* This routine creates the cleanup for the current exception. */
250 push_eh_cleanup (tree type)
252 finish_decl_cleanup (NULL_TREE, do_end_catch (type));
255 /* Return nonzero value if DECL is a Java type suitable for catch or
259 decl_is_java_type (tree decl, int err)
261 bool r = (TREE_CODE (decl) == POINTER_TYPE
262 && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
263 && TYPE_FOR_JAVA (TREE_TYPE (decl)));
267 if (TREE_CODE (decl) == REFERENCE_TYPE
268 && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
269 && TYPE_FOR_JAVA (TREE_TYPE (decl)))
271 /* Can't throw a reference. */
272 error ("type %qT is disallowed in Java %<throw%> or %<catch%>",
279 = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jthrowable"));
281 if (jthrow_node == NULL_TREE)
283 ("call to Java %<catch%> or %<throw%> with %<jthrowable%> undefined");
285 jthrow_node = TREE_TYPE (TREE_TYPE (jthrow_node));
287 if (! DERIVED_FROM_P (jthrow_node, TREE_TYPE (decl)))
289 /* Thrown object must be a Throwable. */
290 error ("type %qT is not derived from %<java::lang::Throwable%>",
299 /* Select the personality routine to be used for exception handling,
300 or issue an error if we need two different ones in the same
302 ??? At present eh_personality_decl is set to
303 __gxx_personality_(sj|v)0 in init_exception_processing - should it
304 be done here instead? */
306 choose_personality_routine (enum languages lang)
321 if (lang != lang_cplusplus)
326 if (lang != lang_java)
331 ; /* Proceed to language selection. */
342 terminate_node = built_in_decls [BUILT_IN_ABORT];
343 pragma_java_exceptions = true;
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;
367 DECL_READ_P (decl) = 1;
369 /* Figure out the type that the initializer is. Pointers are returned
370 adjusted by value from __cxa_begin_catch. Others are returned by
372 init_type = TREE_TYPE (decl);
373 if (!POINTER_TYPE_P (init_type))
374 init_type = build_reference_type (init_type);
376 choose_personality_routine (decl_is_java_type (init_type, 0)
377 ? lang_java : lang_cplusplus);
379 /* Since pointers are passed by value, initialize a reference to
380 pointer catch parm with the address of the temporary. */
381 if (TREE_CODE (init_type) == REFERENCE_TYPE
382 && TYPE_PTR_P (TREE_TYPE (init_type)))
383 exp = cp_build_unary_op (ADDR_EXPR, exp, 1, tf_warning_or_error);
385 exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
387 init = convert_from_reference (exp);
389 /* If the constructor for the catch parm exits via an exception, we
390 must call terminate. See eh23.C. */
391 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
393 /* Generate the copy constructor call directly so we can wrap it.
394 See also expand_default_init. */
395 init = ocp_convert (TREE_TYPE (decl), init,
396 CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
397 /* Force cleanups now to avoid nesting problems with the
398 MUST_NOT_THROW_EXPR. */
399 init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
400 init = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (init), init);
403 decl = pushdecl (decl);
405 start_decl_1 (decl, true);
406 cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE,
407 LOOKUP_ONLYCONVERTING|DIRECT_BIND);
410 /* Call this to start a catch block. DECL is the catch parameter. */
413 expand_start_catch_block (tree decl)
421 /* Make sure this declaration is reasonable. */
422 if (decl && !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl), NULL_TREE))
423 decl = error_mark_node;
426 type = prepare_eh_type (TREE_TYPE (decl));
430 if (decl && decl_is_java_type (type, 1))
432 /* Java only passes object via pointer and doesn't require
433 adjusting. The java object is immediately before the
434 generic exception header. */
435 exp = build_exc_ptr ();
436 exp = build1 (NOP_EXPR, build_pointer_type (type), exp);
437 exp = build2 (POINTER_PLUS_EXPR, TREE_TYPE (exp), exp,
438 fold_build1_loc (input_location,
439 NEGATE_EXPR, sizetype,
440 TYPE_SIZE_UNIT (TREE_TYPE (exp))));
441 exp = cp_build_indirect_ref (exp, RO_NULL, tf_warning_or_error);
442 initialize_handler_parm (decl, exp);
446 /* Call __cxa_end_catch at the end of processing the exception. */
447 push_eh_cleanup (type);
449 init = do_begin_catch ();
451 /* If there's no decl at all, then all we need to do is make sure
452 to tell the runtime that we've begun handling the exception. */
453 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
454 finish_expr_stmt (init);
456 /* If the C++ object needs constructing, we need to do that before
457 calling __cxa_begin_catch, so that std::uncaught_exception gets
458 the right value during the copy constructor. */
459 else if (flag_use_cxa_get_exception_ptr
460 && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
462 exp = do_get_exception_ptr ();
463 initialize_handler_parm (decl, exp);
464 finish_expr_stmt (init);
467 /* Otherwise the type uses a bitwise copy, and we don't have to worry
468 about the value of std::uncaught_exception and therefore can do the
469 copy with the return value of __cxa_end_catch instead. */
472 tree init_type = type;
474 /* Pointers are passed by values, everything else by reference. */
475 if (!TYPE_PTR_P (type))
476 init_type = build_pointer_type (type);
477 if (init_type != TREE_TYPE (init))
478 init = build1 (NOP_EXPR, init_type, init);
479 exp = create_temporary_var (init_type);
480 DECL_REGISTER (exp) = 1;
481 cp_finish_decl (exp, init, /*init_const_expr=*/false,
482 NULL_TREE, LOOKUP_ONLYCONVERTING);
483 initialize_handler_parm (decl, exp);
490 /* Call this to end a catch block. Its responsible for emitting the
491 code to handle jumping back to the correct place, and for emitting
492 the label to jump to if this catch block didn't match. */
495 expand_end_catch_block (void)
500 /* The exception being handled is rethrown if control reaches the end of
501 a handler of the function-try-block of a constructor or destructor. */
502 if (in_function_try_handler
503 && (DECL_CONSTRUCTOR_P (current_function_decl)
504 || DECL_DESTRUCTOR_P (current_function_decl)))
505 finish_expr_stmt (build_throw (NULL_TREE));
509 begin_eh_spec_block (void)
512 /* A noexcept specification (or throw() with -fnothrow-opt) is a
513 MUST_NOT_THROW_EXPR. */
514 if (TYPE_NOEXCEPT_P (TREE_TYPE (current_function_decl)))
516 r = build_stmt (input_location, MUST_NOT_THROW_EXPR, NULL_TREE);
517 TREE_SIDE_EFFECTS (r) = 1;
520 r = build_stmt (input_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
522 TREE_OPERAND (r, 0) = push_stmt_list ();
527 finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
531 TREE_OPERAND (eh_spec_block, 0)
532 = pop_stmt_list (TREE_OPERAND (eh_spec_block, 0));
534 if (TREE_CODE (eh_spec_block) == MUST_NOT_THROW_EXPR)
537 /* Strip cv quals, etc, from the specification types. */
538 for (raises = NULL_TREE;
539 raw_raises && TREE_VALUE (raw_raises);
540 raw_raises = TREE_CHAIN (raw_raises))
542 tree type = prepare_eh_type (TREE_VALUE (raw_raises));
543 tree tinfo = eh_type_info (type);
546 raises = tree_cons (NULL_TREE, type, raises);
549 EH_SPEC_RAISES (eh_spec_block) = raises;
552 /* Return a pointer to a buffer for an exception object of type TYPE. */
555 do_allocate_exception (tree type)
559 fn = get_identifier ("__cxa_allocate_exception");
560 if (!get_global_value_if_present (fn, &fn))
562 /* Declare void *__cxa_allocate_exception(size_t) throw(). */
563 fn = declare_nothrow_library_fn (fn, ptr_type_node, size_type_node);
566 return cp_build_function_call_nary (fn, tf_warning_or_error,
567 size_in_bytes (type), NULL_TREE);
570 /* Call __cxa_free_exception from a cleanup. This is never invoked
571 directly, but see the comment for stabilize_throw_expr. */
574 do_free_exception (tree ptr)
578 fn = get_identifier ("__cxa_free_exception");
579 if (!get_global_value_if_present (fn, &fn))
581 /* Declare void __cxa_free_exception (void *) throw(). */
582 fn = declare_nothrow_library_fn (fn, void_type_node, ptr_type_node);
585 return cp_build_function_call_nary (fn, tf_warning_or_error, ptr, NULL_TREE);
588 /* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
589 Called from build_throw via walk_tree_without_duplicates. */
592 wrap_cleanups_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
593 void *data ATTRIBUTE_UNUSED)
598 /* Don't walk into types. */
604 if (TREE_CODE (exp) != TARGET_EXPR)
607 cleanup = TARGET_EXPR_CLEANUP (exp);
610 cleanup = build1 (MUST_NOT_THROW_EXPR, void_type_node, cleanup);
611 TARGET_EXPR_CLEANUP (exp) = cleanup;
614 /* Keep iterating. */
618 /* Build a throw expression. */
621 build_throw (tree exp)
625 if (exp == error_mark_node)
628 if (processing_template_decl)
631 current_function_returns_abnormally = 1;
632 return build_min (THROW_EXPR, void_type_node, exp);
635 if (exp == null_node)
636 warning (0, "throwing NULL, which has integral, not pointer type");
638 if (exp != NULL_TREE)
640 if (!is_admissible_throw_operand (exp))
641 return error_mark_node;
645 return error_mark_node;
647 if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
649 tree fn = get_identifier ("_Jv_Throw");
650 if (!get_global_value_if_present (fn, &fn))
652 /* Declare void _Jv_Throw (void *). */
653 tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
654 tmp = build_function_type (ptr_type_node, tmp);
655 fn = push_throw_library_fn (fn, tmp);
657 else if (really_overloaded_fn (fn))
659 error ("%qD should never be overloaded", fn);
660 return error_mark_node;
662 fn = OVL_CURRENT (fn);
663 exp = cp_build_function_call_nary (fn, tf_warning_or_error,
675 /* The CLEANUP_TYPE is the internal type of a destructor. */
678 tmp = void_list_node;
679 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
680 tmp = build_function_type (void_type_node, tmp);
681 cleanup_type = build_pointer_type (tmp);
684 fn = get_identifier ("__cxa_throw");
685 if (!get_global_value_if_present (fn, &fn))
687 /* Declare void __cxa_throw (void*, void*, void (*)(void*)). */
688 /* ??? Second argument is supposed to be "std::type_info*". */
689 tmp = void_list_node;
690 tmp = tree_cons (NULL_TREE, cleanup_type, tmp);
691 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
692 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
693 tmp = build_function_type (void_type_node, tmp);
694 fn = push_throw_library_fn (fn, tmp);
699 A throw-expression initializes a temporary object, the type
700 of which is determined by removing any top-level
701 cv-qualifiers from the static type of the operand of throw
702 and adjusting the type from "array of T" or "function return
703 T" to "pointer to T" or "pointer to function returning T"
705 temp_type = is_bitfield_expr_with_lowered_type (exp);
707 temp_type = type_decays_to (TREE_TYPE (exp));
709 /* OK, this is kind of wacky. The standard says that we call
710 terminate when the exception handling mechanism, after
711 completing evaluation of the expression to be thrown but
712 before the exception is caught (_except.throw_), calls a
713 user function that exits via an uncaught exception.
715 So we have to protect the actual initialization of the
716 exception object with terminate(), but evaluate the
717 expression first. Since there could be temps in the
718 expression, we need to handle that, too. We also expand
719 the call to __cxa_allocate_exception first (which doesn't
720 matter, since it can't throw). */
722 /* Allocate the space for the exception. */
723 allocate_expr = do_allocate_exception (temp_type);
724 allocate_expr = get_target_expr (allocate_expr);
725 ptr = TARGET_EXPR_SLOT (allocate_expr);
726 TARGET_EXPR_CLEANUP (allocate_expr) = do_free_exception (ptr);
727 CLEANUP_EH_ONLY (allocate_expr) = 1;
729 object = build_nop (build_pointer_type (temp_type), ptr);
730 object = cp_build_indirect_ref (object, RO_NULL, tf_warning_or_error);
732 /* And initialize the exception object. */
733 if (CLASS_TYPE_P (temp_type))
735 int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
736 VEC(tree,gc) *exp_vec;
738 /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes
739 treated as an rvalue for the purposes of overload resolution
740 to favor move constructors over copy constructors. */
741 if (/* Must be a local, automatic variable. */
742 TREE_CODE (exp) == VAR_DECL
743 && DECL_CONTEXT (exp) == current_function_decl
744 && ! TREE_STATIC (exp)
745 /* The variable must not have the `volatile' qualifier. */
746 && !(cp_type_quals (TREE_TYPE (exp)) & TYPE_QUAL_VOLATILE))
747 flags = flags | LOOKUP_PREFER_RVALUE;
749 /* Call the copy constructor. */
750 exp_vec = make_tree_vector_single (exp);
751 exp = (build_special_member_call
752 (object, complete_ctor_identifier, &exp_vec,
753 TREE_TYPE (object), flags, tf_warning_or_error));
754 release_tree_vector (exp_vec);
755 if (exp == error_mark_node)
757 error (" in thrown expression");
758 return error_mark_node;
763 tmp = decay_conversion (exp);
764 if (tmp == error_mark_node)
765 return error_mark_node;
766 exp = build2 (INIT_EXPR, temp_type, object, tmp);
769 /* Mark any cleanups from the initialization as MUST_NOT_THROW, since
770 they are run after the exception object is initialized. */
771 cp_walk_tree_without_duplicates (&exp, wrap_cleanups_r, 0);
773 /* Prepend the allocation. */
774 exp = build2 (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
776 /* Force all the cleanups to be evaluated here so that we don't have
777 to do them during unwinding. */
778 exp = build1 (CLEANUP_POINT_EXPR, void_type_node, exp);
780 throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
782 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object)))
784 cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
785 complete_dtor_identifier, 0);
786 cleanup = BASELINK_FUNCTIONS (cleanup);
788 cxx_mark_addressable (cleanup);
789 /* Pretend it's a normal function. */
790 cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);
793 cleanup = build_int_cst (cleanup_type, 0);
795 /* ??? Indicate that this function call throws throw_type. */
796 tmp = cp_build_function_call_nary (fn, tf_warning_or_error,
797 ptr, throw_type, cleanup, NULL_TREE);
799 /* Tack on the initialization stuff. */
800 exp = build2 (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp);
804 /* Rethrow current exception. */
806 tree fn = get_identifier ("__cxa_rethrow");
807 if (!get_global_value_if_present (fn, &fn))
809 /* Declare void __cxa_rethrow (void). */
810 fn = push_throw_library_fn
811 (fn, build_function_type (void_type_node, void_list_node));
814 /* ??? Indicate that this function call allows exceptions of the type
815 of the enclosing catch block (if known). */
816 exp = cp_build_function_call_vec (fn, NULL, tf_warning_or_error);
819 exp = build1 (THROW_EXPR, void_type_node, exp);
824 /* Make sure TYPE is complete, pointer to complete, reference to
825 complete, or pointer to cv void. Issue diagnostic on failure.
826 Return the zero on failure and nonzero on success. FROM can be
827 the expr or decl from whence TYPE came, if available. */
830 complete_ptr_ref_or_void_ptr_p (tree type, tree from)
834 /* Check complete. */
835 type = complete_type_or_else (type, from);
839 /* Or a pointer or ref to one, or cv void *. */
840 is_ptr = TREE_CODE (type) == POINTER_TYPE;
841 if (is_ptr || TREE_CODE (type) == REFERENCE_TYPE)
843 tree core = TREE_TYPE (type);
845 if (is_ptr && VOID_TYPE_P (core))
847 else if (!complete_type_or_else (core, from))
853 /* Return truth-value if EXPRESSION is admissible in throw-expression,
854 i.e. if it is not of incomplete type or a pointer/reference to such
855 a type or of an abstract class type. */
858 is_admissible_throw_operand (tree expr)
860 tree type = TREE_TYPE (expr);
862 /* 15.1/4 [...] The type of the throw-expression shall not be an
863 incomplete type, or a pointer or a reference to an incomplete
864 type, other than void*, const void*, volatile void*, or
865 const volatile void*. Except for these restriction and the
866 restrictions on type matching mentioned in 15.3, the operand
867 of throw is treated exactly as a function argument in a call
868 (5.2.2) or the operand of a return statement. */
869 if (!complete_ptr_ref_or_void_ptr_p (type, expr))
872 /* 10.4/3 An abstract class shall not be used as a parameter type,
873 as a function return type or as type of an explicit
875 else if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type))
877 error ("expression %qE of abstract class type %qT cannot "
878 "be used in throw-expression", expr, type);
885 /* Returns nonzero if FN is a declaration of a standard C library
886 function which is known not to throw.
888 [lib.res.on.exception.handling]: None of the functions from the
889 Standard C library shall report an error by throwing an
890 exception, unless it calls a program-supplied function that
891 throws an exception. */
896 nothrow_libfn_p (const_tree fn)
901 && DECL_EXTERNAL (fn)
902 && DECL_NAMESPACE_SCOPE_P (fn)
903 && DECL_EXTERN_C_P (fn))
906 /* Can't be a C library function. */
909 /* Being a C library function, DECL_ASSEMBLER_NAME == DECL_NAME
910 unless the system headers are playing rename tricks, and if
911 they are, we don't want to be confused by them. */
913 return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
916 /* Returns nonzero if an exception of type FROM will be caught by a
917 handler for type TO, as per [except.handle]. */
920 can_convert_eh (tree to, tree from)
922 to = non_reference (to);
923 from = non_reference (from);
925 if (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
928 from = TREE_TYPE (from);
930 if (! at_least_as_qualified_p (to, from))
933 if (TREE_CODE (to) == VOID_TYPE)
936 /* Else fall through. */
939 if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
940 && PUBLICLY_UNIQUELY_DERIVED_P (to, from))
946 /* Check whether any of the handlers in I are shadowed by another handler
947 accepting TYPE. Note that the shadowing may not be complete; even if
948 an exception of type B would be caught by a handler for A, there could
949 be a derived class C for which A is an ambiguous base but B is not, so
950 the handler for B would catch an exception of type C. */
953 check_handlers_1 (tree master, tree_stmt_iterator i)
955 tree type = TREE_TYPE (master);
957 for (; !tsi_end_p (i); tsi_next (&i))
959 tree handler = tsi_stmt (i);
960 if (TREE_TYPE (handler) && can_convert_eh (type, TREE_TYPE (handler)))
962 warning_at (EXPR_LOCATION (handler), 0,
963 "exception of type %qT will be caught",
964 TREE_TYPE (handler));
965 warning_at (EXPR_LOCATION (master), 0,
966 " by earlier handler for %qT", type);
972 /* Given a STATEMENT_LIST of HANDLERs, make sure that they're OK. */
975 check_handlers (tree handlers)
977 tree_stmt_iterator i;
979 /* If we don't have a STATEMENT_LIST, then we've just got one
980 handler, and thus nothing to warn about. */
981 if (TREE_CODE (handlers) != STATEMENT_LIST)
984 i = tsi_start (handlers);
988 tree handler = tsi_stmt (i);
991 /* No more handlers; nothing to shadow. */
994 if (TREE_TYPE (handler) == NULL_TREE)
995 permerror (EXPR_LOCATION (handler), "%<...%>"
996 " handler must be the last handler for its try block");
998 check_handlers_1 (handler, i);
1002 /* walk_tree helper for finish_noexcept_expr. Returns non-null if the
1003 expression *TP causes the noexcept operator to evaluate to false.
1005 5.3.7 [expr.noexcept]: The result of the noexcept operator is false if
1006 in a potentially-evaluated context the expression would contain
1007 * a potentially evaluated call to a function, member function,
1008 function pointer, or member function pointer that does not have a
1009 non-throwing exception-specification (15.4),
1010 * a potentially evaluated throw-expression (15.1),
1011 * a potentially evaluated dynamic_cast expression dynamic_cast<T>(v),
1012 where T is a reference type, that requires a run-time check (5.2.7), or
1013 * a potentially evaluated typeid expression (5.2.8) applied to a glvalue
1014 expression whose type is a polymorphic class type (10.3). */
1017 check_noexcept_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
1018 void *data ATTRIBUTE_UNUSED)
1021 enum tree_code code = TREE_CODE (t);
1022 if (code == CALL_EXPR
1023 || code == AGGR_INIT_EXPR)
1025 /* We can only use the exception specification of the called function
1026 for determining the value of a noexcept expression; we can't use
1027 TREE_NOTHROW, as it might have a different value in another
1028 translation unit, creating ODR problems.
1030 We could use TREE_NOTHROW (t) for !TREE_PUBLIC fns, though... */
1031 tree fn = (code == AGGR_INIT_EXPR
1032 ? AGGR_INIT_EXPR_FN (t) : CALL_EXPR_FN (t));
1033 if (TREE_CODE (fn) == ADDR_EXPR)
1035 /* We do use TREE_NOTHROW for ABI internals like __dynamic_cast,
1036 and for C library functions known not to throw. */
1037 tree fn2 = TREE_OPERAND (fn, 0);
1038 if (TREE_CODE (fn2) == FUNCTION_DECL
1039 && DECL_EXTERN_C_P (fn2)
1040 && (DECL_ARTIFICIAL (fn2)
1041 || nothrow_libfn_p (fn2)))
1042 return TREE_NOTHROW (fn2) ? NULL_TREE : t;
1044 fn = TREE_TYPE (TREE_TYPE (fn));
1045 if (!TYPE_NOTHROW_P (fn))
1052 /* Evaluate noexcept ( EXPR ). */
1055 finish_noexcept_expr (tree expr)
1057 if (processing_template_decl)
1058 return build_min (NOEXCEPT_EXPR, boolean_type_node, expr);
1060 if (cp_walk_tree_without_duplicates (&expr, check_noexcept_r, 0))
1061 return boolean_false_node;
1063 return boolean_true_node;
1066 /* Return true iff SPEC is throw() or noexcept(true). */
1069 nothrow_spec_p (const_tree spec)
1071 if (spec == NULL_TREE
1072 || TREE_VALUE (spec) != NULL_TREE
1073 || spec == noexcept_false_spec)
1075 if (TREE_PURPOSE (spec) == NULL_TREE
1076 || spec == noexcept_true_spec)
1078 gcc_assert (processing_template_decl
1079 || TREE_PURPOSE (spec) == error_mark_node);
1083 /* For FUNCTION_TYPE or METHOD_TYPE, true if NODE is noexcept. This is the
1084 case for things declared noexcept(true) and, with -fnothrow-opt, for
1085 throw() functions. */
1088 type_noexcept_p (const_tree type)
1090 tree spec = TYPE_RAISES_EXCEPTIONS (type);
1091 if (flag_nothrow_opt)
1092 return nothrow_spec_p (spec);
1094 return spec == noexcept_true_spec;
1097 /* For FUNCTION_TYPE or METHOD_TYPE, true if NODE can throw any type,
1098 i.e. no exception-specification or noexcept(false). */
1101 type_throw_all_p (const_tree type)
1103 tree spec = TYPE_RAISES_EXCEPTIONS (type);
1104 return spec == NULL_TREE || spec == noexcept_false_spec;
1107 /* Create a representation of the noexcept-specification with
1108 constant-expression of EXPR. COMPLAIN is as for tsubst. */
1111 build_noexcept_spec (tree expr, int complain)
1113 expr = perform_implicit_conversion_flags (boolean_type_node, expr,
1116 if (expr == boolean_true_node)
1117 return noexcept_true_spec;
1118 else if (expr == boolean_false_node)
1119 return noexcept_false_spec;
1122 gcc_assert (processing_template_decl || expr == error_mark_node);
1123 return build_tree_list (expr, NULL_TREE);