Deleted Added
sdiff udiff text old ( 110621 ) new ( 117404 )
full compact
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.
7
8This file is part of GNU CC.

--- 17 unchanged lines hidden (view full) ---

26#include "config.h"
27#include "system.h"
28#include "tree.h"
29#include "rtl.h"
30#include "expr.h"
31#include "libfuncs.h"
32#include "cp-tree.h"
33#include "flags.h"
34#include "obstack.h"
35#include "output.h"
36#include "except.h"
37#include "toplev.h"
38
39static void push_eh_cleanup PARAMS ((tree));
40static tree prepare_eh_type PARAMS ((tree));
41static tree build_eh_type_type PARAMS ((tree));
42static tree do_begin_catch PARAMS ((void));
43static int dtor_nothrow PARAMS ((tree));
44static tree do_end_catch PARAMS ((tree));
45static void push_eh_cleanup PARAMS ((tree));
46static bool decl_is_java_type PARAMS ((tree decl, int err));
47static void initialize_handler_parm PARAMS ((tree, tree));
48static tree do_allocate_exception PARAMS ((tree));
49static int complete_ptr_ref_or_void_ptr_p PARAMS ((tree, tree));
50static bool is_admissible_throw_operand PARAMS ((tree));
51static int can_convert_eh PARAMS ((tree, tree));
52static void check_handlers_1 PARAMS ((tree, tree));
53static tree cp_protect_cleanup_actions PARAMS ((void));
54
55#include "decl.h"
56#include "obstack.h"
57
58/* Sets up all the global eh stuff that needs to be initialized at the
59 start of compilation. */
60
61void
62init_exception_processing ()
63{
64 tree tmp;
65

--- 47 unchanged lines hidden (view full) ---

113
114 /* Peel off cv qualifiers. */
115 type = TYPE_MAIN_VARIANT (type);
116
117 return type;
118}
119
120/* Build the address of a typeinfo decl for use in the runtime
121 matching field of the exception model. */
122
123static tree
124build_eh_type_type (type)
125 tree type;
126{
127 tree exp;
128
129 if (type == NULL_TREE || type == error_mark_node)

--- 40 unchanged lines hidden (view full) ---

170
171/* Returns nonzero if cleaning up an exception of type TYPE (which can be
172 NULL_TREE for a ... handler) will not throw an exception. */
173
174static int
175dtor_nothrow (type)
176 tree type;
177{
178 tree fn;
179
180 if (type == NULL_TREE)
181 return 0;
182
183 if (! TYPE_HAS_DESTRUCTOR (type))
184 return 1;
185
186 fn = lookup_member (type, dtor_identifier, 0, 0);
187 fn = TREE_VALUE (fn);
188 return TREE_NOTHROW (fn);
189}
190
191/* Build up a call to __cxa_end_catch, to destroy the exception object
192 for the current catch block if no others are currently using it. */
193
194static tree
195do_end_catch (type)
196 tree type;

--- 316 unchanged lines hidden (view full) ---

513 }
514
515 return build_function_call (fn, tree_cons (NULL_TREE, size_in_bytes (type),
516 NULL_TREE));
517}
518
519#if 0
520/* Call __cxa_free_exception from a cleanup. This is never invoked
521 directly. */
522
523static tree
524do_free_exception (ptr)
525 tree ptr;
526{
527 tree fn;
528
529 fn = get_identifier ("__cxa_free_exception");

--- 5 unchanged lines hidden (view full) ---

535 fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
536 void_list_node));
537 }
538
539 return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
540}
541#endif
542
543/* Build a throw expression. */
544
545tree
546build_throw (exp)
547 tree exp;
548{
549 tree fn;
550

--- 29 unchanged lines hidden (view full) ---

580 }
581
582 exp = build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE));
583 }
584 else if (exp)
585 {
586 tree throw_type;
587 tree cleanup;
588 tree stmt_expr;
589 tree compound_stmt;
590 tree object, ptr;
591 tree tmp;
592
593 fn = get_identifier ("__cxa_throw");
594 if (IDENTIFIER_GLOBAL_VALUE (fn))
595 fn = IDENTIFIER_GLOBAL_VALUE (fn);
596 else
597 {
598 /* The CLEANUP_TYPE is the internal type of a destructor. */
599 if (cleanup_type == NULL_TREE)

--- 9 unchanged lines hidden (view full) ---

609 tmp = void_list_node;
610 tmp = tree_cons (NULL_TREE, cleanup_type, tmp);
611 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
612 tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
613 tmp = build_function_type (void_type_node, tmp);
614 fn = push_throw_library_fn (fn, tmp);
615 }
616
617 begin_init_stmts (&stmt_expr, &compound_stmt);
618
619 /* throw expression */
620 /* First, decay it. */
621 exp = decay_conversion (exp);
622
623 /* OK, this is kind of wacky. The standard says that we call
624 terminate when the exception handling mechanism, after
625 completing evaluation of the expression to be thrown but
626 before the exception is caught (_except.throw_), calls a
627 user function that exits via an uncaught exception.
628
629 So we have to protect the actual initialization of the
630 exception object with terminate(), but evaluate the
631 expression first. Since there could be temps in the
632 expression, we need to handle that, too. We also expand
633 the call to __cxa_allocate_exception first (which doesn't
634 matter, since it can't throw). */
635
636 my_friendly_assert (stmts_are_full_exprs_p () == 1, 19990926);
637
638 /* Store the throw expression into a temp. This can be less
639 efficient than storing it into the allocated space directly, but
640 if we allocated the space first we would have to deal with
641 cleaning it up if evaluating this expression throws. */
642 if (TREE_SIDE_EFFECTS (exp))
643 {
644 tmp = create_temporary_var (TREE_TYPE (exp));
645 DECL_INITIAL (tmp) = exp;
646 cp_finish_decl (tmp, exp, NULL_TREE, LOOKUP_ONLYCONVERTING);
647 exp = tmp;
648 }
649
650 /* Allocate the space for the exception. */
651 ptr = create_temporary_var (ptr_type_node);
652 DECL_REGISTER (ptr) = 1;
653 cp_finish_decl (ptr, NULL_TREE, NULL_TREE, LOOKUP_ONLYCONVERTING);
654 tmp = do_allocate_exception (TREE_TYPE (exp));
655 tmp = build_modify_expr (ptr, INIT_EXPR, tmp);
656 finish_expr_stmt (tmp);
657
658 object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
659 object = build_indirect_ref (object, NULL);
660
661 exp = build_modify_expr (object, INIT_EXPR, exp);
662 if (exp == error_mark_node)
663 error (" in thrown expression");
664
665 exp = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (exp), exp);
666 finish_expr_stmt (exp);
667
668 throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
669
670 if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (object)))
671 {
672 cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
673 complete_dtor_identifier, 0);
674 cleanup = TREE_VALUE (cleanup);
675 mark_used (cleanup);
676 mark_addressable (cleanup);
677 /* Pretend it's a normal function. */
678 cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);
679 }
680 else
681 {
682 cleanup = build_int_2 (0, 0);
683 TREE_TYPE (cleanup) = cleanup_type;
684 }
685
686 tmp = tree_cons (NULL_TREE, cleanup, NULL_TREE);
687 tmp = tree_cons (NULL_TREE, throw_type, tmp);
688 tmp = tree_cons (NULL_TREE, ptr, tmp);
689 tmp = build_function_call (fn, tmp);
690
691 /* ??? Indicate that this function call throws throw_type. */
692
693 finish_expr_stmt (tmp);
694
695 exp = finish_init_stmts (stmt_expr, compound_stmt);
696 }
697 else
698 {
699 /* Rethrow current exception. */
700
701 tree fn = get_identifier ("__cxa_rethrow");
702 if (IDENTIFIER_GLOBAL_VALUE (fn))
703 fn = IDENTIFIER_GLOBAL_VALUE (fn);
704 else
705 {
706 /* Declare void __cxa_rethrow (void). */
707 fn = push_throw_library_fn
708 (fn, build_function_type (void_type_node, void_list_node));
709 }
710
711 exp = build_function_call (fn, NULL_TREE);
712 }
713
714 exp = build1 (THROW_EXPR, void_type_node, exp);
715
716 return exp;
717}
718
719/* Make sure TYPE is complete, pointer to complete, reference to
720 complete, or pointer to cv void. Issue diagnostic on failure.
721 Return the zero on failure and non-zero on success. FROM can be
722 the expr or decl from whence TYPE came, if available. */
723
724static int
725complete_ptr_ref_or_void_ptr_p (type, from)
726 tree type;
727 tree from;
728{
729 int is_ptr;

--- 164 unchanged lines hidden ---