OSDN Git Service

PR c++/2294
[pf3gnuchains/gcc-fork.git] / gcc / cp / except.c
1 /* Handle exceptional things in C++.
2    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002, 2003  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
8 This file is part of GCC.
9
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 2, or (at your option)
13 any later version.
14
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.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING.  If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA.  */
24
25
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "tm.h"
30 #include "tree.h"
31 #include "rtl.h"
32 #include "expr.h"
33 #include "libfuncs.h"
34 #include "cp-tree.h"
35 #include "flags.h"
36 #include "output.h"
37 #include "except.h"
38 #include "toplev.h"
39 #include "tree-inline.h"
40
41 static void push_eh_cleanup (tree);
42 static tree prepare_eh_type (tree);
43 static tree build_eh_type_type (tree);
44 static tree do_begin_catch (void);
45 static int dtor_nothrow (tree);
46 static tree do_end_catch (tree);
47 static bool decl_is_java_type (tree decl, int err);
48 static void initialize_handler_parm (tree, tree);
49 static tree do_allocate_exception (tree);
50 static tree stabilize_throw_expr (tree, 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 void check_handlers_1 (tree, tree);
56 static tree cp_protect_cleanup_actions (void);
57
58 /* Sets up all the global eh stuff that needs to be initialized at the
59    start of compilation.  */
60
61 void
62 init_exception_processing (void)
63 {
64   tree tmp;
65
66   /* void std::terminate (); */
67   push_namespace (std_identifier);
68   tmp = build_function_type (void_type_node, void_list_node);
69   terminate_node = build_cp_library_fn_ptr ("terminate", tmp);
70   TREE_THIS_VOLATILE (terminate_node) = 1;
71   TREE_NOTHROW (terminate_node) = 1;
72   pop_namespace ();
73
74   /* void __cxa_call_unexpected(void *); */
75   tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
76   tmp = build_function_type (void_type_node, tmp);
77   call_unexpected_node
78     = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
79
80   eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
81                                              ? "__gxx_personality_sj0"
82                                              : "__gxx_personality_v0");
83
84   lang_eh_runtime_type = build_eh_type_type;
85   lang_protect_cleanup_actions = &cp_protect_cleanup_actions;
86 }
87
88 /* Returns an expression to be executed if an unhandled exception is
89    propagated out of a cleanup region.  */
90
91 static tree
92 cp_protect_cleanup_actions (void)
93 {
94   /* [except.terminate]
95
96      When the destruction of an object during stack unwinding exits
97      using an exception ... void terminate(); is called.  */
98   return build_call (terminate_node, NULL_TREE);
99 }     
100
101 static tree
102 prepare_eh_type (tree type)
103 {
104   if (type == NULL_TREE)
105     return type;
106   if (type == error_mark_node)
107     return error_mark_node;
108
109   /* peel back references, so they match.  */
110   type = non_reference (type);
111
112   /* Peel off cv qualifiers.  */
113   type = TYPE_MAIN_VARIANT (type);
114
115   return type;
116 }
117
118 /* Return the type info for TYPE as used by EH machinery.  */
119 tree
120 eh_type_info (tree type)
121 {
122   tree exp;
123
124   if (type == NULL_TREE || type == error_mark_node)
125     return type;
126
127   if (decl_is_java_type (type, 0))
128     exp = build_java_class_ref (TREE_TYPE (type));
129   else
130     exp = get_tinfo_decl (type);
131
132   return exp;
133 }
134
135 /* Build the address of a typeinfo decl for use in the runtime
136    matching field of the exception model.  */
137
138 static tree
139 build_eh_type_type (tree type)
140 {
141   tree exp = eh_type_info (type);
142
143   if (!exp)
144     return NULL;
145
146   mark_used (exp);
147
148   return build1 (ADDR_EXPR, ptr_type_node, exp);
149 }
150
151 tree
152 build_exc_ptr (void)
153 {
154   return build (EXC_PTR_EXPR, ptr_type_node);
155 }
156
157 /* Build up a call to __cxa_begin_catch, to tell the runtime that the
158    exception has been handled.  */
159
160 static tree
161 do_begin_catch (void)
162 {
163   tree fn;
164
165   fn = get_identifier ("__cxa_begin_catch");
166   if (!get_global_value_if_present (fn, &fn))
167     {
168       /* Declare void* __cxa_begin_catch (void *).  */
169       tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
170       fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
171     }
172
173   return build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
174                                              NULL_TREE));
175 }
176
177 /* Returns nonzero if cleaning up an exception of type TYPE (which can be
178    NULL_TREE for a ... handler) will not throw an exception.  */
179
180 static int
181 dtor_nothrow (tree type)
182 {
183   if (type == NULL_TREE)
184     return 0;
185
186   if (! TYPE_HAS_DESTRUCTOR (type))
187     return 1;
188
189   return TREE_NOTHROW (CLASSTYPE_DESTRUCTORS (type));
190 }
191
192 /* Build up a call to __cxa_end_catch, to destroy the exception object
193    for the current catch block if no others are currently using it.  */
194
195 static tree
196 do_end_catch (tree type)
197 {
198   tree fn, cleanup;
199
200   fn = get_identifier ("__cxa_end_catch");
201   if (!get_global_value_if_present (fn, &fn))
202     {
203       /* Declare void __cxa_end_catch ().  */
204       fn = push_void_library_fn (fn, void_list_node);
205       /* This can throw if the destructor for the exception throws.  */
206       TREE_NOTHROW (fn) = 0;
207     }
208
209   cleanup = build_function_call (fn, NULL_TREE);
210   TREE_NOTHROW (cleanup) = dtor_nothrow (type);
211
212   return cleanup;
213 }
214
215 /* This routine creates the cleanup for the current exception.  */
216
217 static void
218 push_eh_cleanup (tree type)
219 {
220   finish_decl_cleanup (NULL_TREE, do_end_catch (type));
221 }
222
223 /* Return nonzero value if DECL is a Java type suitable for catch or
224    throw.  */
225
226 static bool
227 decl_is_java_type (tree decl, int err)
228 {
229   bool r = (TREE_CODE (decl) == POINTER_TYPE
230             && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
231             && TYPE_FOR_JAVA (TREE_TYPE (decl)));
232
233   if (err)
234     {
235       if (TREE_CODE (decl) == REFERENCE_TYPE
236           && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
237           && TYPE_FOR_JAVA (TREE_TYPE (decl)))
238         {
239           /* Can't throw a reference.  */
240           error ("type `%T' is disallowed in Java `throw' or `catch'",
241                     decl);
242         }
243
244       if (r)
245         {
246           tree jthrow_node
247             = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jthrowable"));
248
249           if (jthrow_node == NULL_TREE)
250             fatal_error
251               ("call to Java `catch' or `throw' with `jthrowable' undefined");
252
253           jthrow_node = TREE_TYPE (TREE_TYPE (jthrow_node));
254
255           if (! DERIVED_FROM_P (jthrow_node, TREE_TYPE (decl)))
256             {
257               /* Thrown object must be a Throwable.  */
258               error ("type `%T' is not derived from `java::lang::Throwable'",
259                         TREE_TYPE (decl));
260             }
261         }
262     }
263
264   return r;
265 }
266
267 /* Select the personality routine to be used for exception handling,
268    or issue an error if we need two different ones in the same
269    translation unit.
270    ??? At present eh_personality_libfunc is set to
271    __gxx_personality_(sj|v)0 in init_exception_processing - should it
272    be done here instead?  */
273 void
274 choose_personality_routine (enum languages lang)
275 {
276   static enum {
277     chose_none,
278     chose_cpp,
279     chose_java,
280     gave_error
281   } state;
282
283   switch (state)
284     {
285     case gave_error:
286       return;
287
288     case chose_cpp:
289       if (lang != lang_cplusplus)
290         goto give_error;
291       return;
292
293     case chose_java:
294       if (lang != lang_java)
295         goto give_error;
296       return;
297
298     case chose_none:
299       ; /* proceed to language selection */
300     }
301
302   switch (lang)
303     {
304     case lang_cplusplus:
305       state = chose_cpp;
306       break;
307
308     case lang_java:
309       state = chose_java;
310       eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
311                                                  ? "__gcj_personality_sj0"
312                                                  : "__gcj_personality_v0");
313       break;
314
315     default:
316       abort ();
317     }
318   return;
319
320  give_error:
321   error ("mixing C++ and Java catches in a single translation unit");
322   state = gave_error;
323 }
324
325 /* Initialize the catch parameter DECL.  */
326
327 static void 
328 initialize_handler_parm (tree decl, tree exp)
329 {
330   tree init;
331   tree init_type;
332
333   /* Make sure we mark the catch param as used, otherwise we'll get a
334      warning about an unused ((anonymous)).  */
335   TREE_USED (decl) = 1;
336
337   /* Figure out the type that the initializer is.  Pointers are returned
338      adjusted by value from __cxa_begin_catch.  Others are returned by 
339      reference.  */
340   init_type = TREE_TYPE (decl);
341   if (! TYPE_PTR_P (init_type)
342       && TREE_CODE (init_type) != REFERENCE_TYPE)
343     init_type = build_reference_type (init_type);
344
345   choose_personality_routine (decl_is_java_type (init_type, 0)
346                               ? lang_java : lang_cplusplus);
347
348   /* Since pointers are passed by value, initialize a reference to
349      pointer catch parm with the address of the temporary.  */
350   if (TREE_CODE (init_type) == REFERENCE_TYPE
351       && TYPE_PTR_P (TREE_TYPE (init_type)))
352     exp = build_unary_op (ADDR_EXPR, exp, 1);
353
354   exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
355
356   init = convert_from_reference (exp);
357
358   /* If the constructor for the catch parm exits via an exception, we
359      must call terminate.  See eh23.C.  */
360   if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
361     {
362       /* Generate the copy constructor call directly so we can wrap it.
363          See also expand_default_init.  */
364       init = ocp_convert (TREE_TYPE (decl), init,
365                           CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
366       init = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (init), init);
367     }
368
369   /* Let `cp_finish_decl' know that this initializer is ok.  */
370   DECL_INITIAL (decl) = error_mark_node;
371   decl = pushdecl (decl);
372
373   start_decl_1 (decl);
374   cp_finish_decl (decl, init, NULL_TREE,
375                   LOOKUP_ONLYCONVERTING|DIRECT_BIND);
376 }
377
378 /* Call this to start a catch block.  DECL is the catch parameter.  */
379
380 tree
381 expand_start_catch_block (tree decl)
382 {
383   tree exp = NULL_TREE;
384   tree type;
385   bool is_java;
386
387   if (! doing_eh (1))
388     return NULL_TREE;
389
390   /* Make sure this declaration is reasonable.  */
391   if (decl && !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl), NULL_TREE))
392     decl = NULL_TREE;
393
394   if (decl)
395     type = prepare_eh_type (TREE_TYPE (decl));
396   else
397     type = NULL_TREE;
398
399   is_java = false;
400   if (decl)
401     {
402       tree init;
403
404       if (decl_is_java_type (type, 1))
405         {
406           /* Java only passes object via pointer and doesn't require
407              adjusting.  The java object is immediately before the
408              generic exception header.  */
409           init = build_exc_ptr ();
410           init = build1 (NOP_EXPR, build_pointer_type (type), init);
411           init = build (MINUS_EXPR, TREE_TYPE (init), init,
412                         TYPE_SIZE_UNIT (TREE_TYPE (init)));
413           init = build_indirect_ref (init, NULL);
414           is_java = true;
415         }
416       else
417         {
418           /* C++ requires that we call __cxa_begin_catch to get the
419              pointer to the actual object.  */
420           init = do_begin_catch ();
421         }
422           
423       exp = create_temporary_var (ptr_type_node);
424       DECL_REGISTER (exp) = 1;
425       cp_finish_decl (exp, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
426       finish_expr_stmt (build_modify_expr (exp, INIT_EXPR, init));
427     }
428   else
429     finish_expr_stmt (do_begin_catch ());
430
431   /* C++ requires that we call __cxa_end_catch at the end of
432      processing the exception.  */
433   if (! is_java)
434     push_eh_cleanup (type);
435
436   if (decl)
437     initialize_handler_parm (decl, exp);
438
439   return type;
440 }
441
442
443 /* Call this to end a catch block.  Its responsible for emitting the
444    code to handle jumping back to the correct place, and for emitting
445    the label to jump to if this catch block didn't match.  */
446
447 void
448 expand_end_catch_block (void)
449 {
450   if (! doing_eh (1))
451     return;
452
453   /* The exception being handled is rethrown if control reaches the end of
454      a handler of the function-try-block of a constructor or destructor.  */
455   if (in_function_try_handler
456       && (DECL_CONSTRUCTOR_P (current_function_decl)
457           || DECL_DESTRUCTOR_P (current_function_decl)))
458     finish_expr_stmt (build_throw (NULL_TREE));
459 }
460
461 tree
462 begin_eh_spec_block (void)
463 {
464   tree r = build_stmt (EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
465   add_stmt (r);
466   return r;
467 }
468
469 void
470 finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
471 {
472   tree raises;
473
474   RECHAIN_STMTS (eh_spec_block, EH_SPEC_STMTS (eh_spec_block));
475
476   /* Strip cv quals, etc, from the specification types.  */
477   for (raises = NULL_TREE;
478        raw_raises && TREE_VALUE (raw_raises);
479        raw_raises = TREE_CHAIN (raw_raises))
480     {
481       tree type = prepare_eh_type (TREE_VALUE (raw_raises));
482       tree tinfo = eh_type_info (type);
483
484       mark_used (tinfo);
485       raises = tree_cons (NULL_TREE, type, raises);
486     }
487
488   EH_SPEC_RAISES (eh_spec_block) = raises;
489 }
490
491 /* Return a pointer to a buffer for an exception object of type TYPE.  */
492
493 static tree
494 do_allocate_exception (tree type)
495 {
496   tree fn;
497
498   fn = get_identifier ("__cxa_allocate_exception");
499   if (!get_global_value_if_present (fn, &fn))
500     {
501       /* Declare void *__cxa_allocate_exception(size_t).  */
502       tree tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
503       fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
504     }
505   
506   return build_function_call (fn, tree_cons (NULL_TREE, size_in_bytes (type),
507                                              NULL_TREE));
508 }
509
510 #if 0
511 /* Call __cxa_free_exception from a cleanup.  This is never invoked
512    directly, but see the comment for stabilize_throw_expr.  */
513
514 static tree
515 do_free_exception (tree ptr)
516 {
517   tree fn;
518
519   fn = get_identifier ("__cxa_free_exception");
520   if (!get_global_value_if_present (fn, &fn))
521     {
522       /* Declare void __cxa_free_exception (void *).  */
523       fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
524                                                 void_list_node));
525     }
526
527   return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
528 }
529 #endif
530
531 /* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
532    Called from build_throw via walk_tree_without_duplicates.  */
533
534 static tree
535 wrap_cleanups_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
536                  void *data ATTRIBUTE_UNUSED)
537 {
538   tree exp = *tp;
539   tree cleanup;
540
541   /* Don't walk into types.  */
542   if (TYPE_P (exp))
543     {
544       *walk_subtrees = 0;
545       return NULL_TREE;
546     }
547   if (TREE_CODE (exp) != TARGET_EXPR)
548     return NULL_TREE;
549
550   cleanup = TARGET_EXPR_CLEANUP (exp);
551   if (cleanup)
552     {
553       cleanup = build1 (MUST_NOT_THROW_EXPR, void_type_node, cleanup);
554       TARGET_EXPR_CLEANUP (exp) = cleanup;
555     }
556
557   /* Keep iterating.  */
558   return NULL_TREE;
559 }
560
561 /* Like stabilize_expr, but specifically for a thrown expression.  When
562    throwing a temporary class object, we want to construct it directly into
563    the thrown exception, so we look past the TARGET_EXPR and stabilize the
564    arguments of the call instead.
565
566    The case where EXP is a call to a function returning a class is a bit of
567    a grey area in the standard; it's unclear whether or not it should be
568    allowed to throw.  I'm going to say no, as that allows us to optimize
569    this case without worrying about deallocating the exception object if it
570    does.  The alternatives would be either not optimizing this case, or
571    wrapping the initialization in a TRY_CATCH_EXPR to call do_free_exception
572    rather than in a MUST_NOT_THROW_EXPR, for this case only.  */
573
574 static tree
575 stabilize_throw_expr (tree exp, tree *initp)
576 {
577   tree init_expr;
578
579   if (TREE_CODE (exp) == TARGET_EXPR
580       && TREE_CODE (TARGET_EXPR_INITIAL (exp)) == AGGR_INIT_EXPR
581       && flag_elide_constructors)
582     {
583       tree aggr_init = AGGR_INIT_EXPR_CHECK (TARGET_EXPR_INITIAL (exp));
584       tree args = TREE_OPERAND (aggr_init, 1);
585       tree newargs = NULL_TREE;
586       tree *p = &newargs;
587
588       init_expr = void_zero_node;
589       for (; args; args = TREE_CHAIN (args))
590         {
591           tree arg = TREE_VALUE (args);
592           tree arg_init_expr;
593
594           arg = stabilize_expr (arg, &arg_init_expr);
595
596           if (TREE_SIDE_EFFECTS (arg_init_expr))
597             init_expr = build (COMPOUND_EXPR, void_type_node, init_expr,
598                                arg_init_expr);
599           *p = tree_cons (NULL_TREE, arg, NULL_TREE);
600           p = &TREE_CHAIN (*p);
601         }
602       TREE_OPERAND (aggr_init, 1) = newargs;
603     }
604   else
605     {
606       exp = stabilize_expr (exp, &init_expr);
607     }
608
609   *initp = init_expr;
610   return exp;
611 }
612
613 /* Build a throw expression.  */
614
615 tree
616 build_throw (tree exp)
617 {
618   tree fn;
619
620   if (exp == error_mark_node)
621     return exp;
622
623   if (processing_template_decl)
624     return build_min (THROW_EXPR, void_type_node, exp);
625
626   if (exp == null_node)
627     warning ("throwing NULL, which has integral, not pointer type");
628   
629   if (exp != NULL_TREE)
630     {
631       if (!is_admissible_throw_operand (exp))
632         return error_mark_node;
633     }
634
635   if (! doing_eh (1))
636     return error_mark_node;
637
638   if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
639     {
640       tree fn = get_identifier ("_Jv_Throw");
641       if (!get_global_value_if_present (fn, &fn))
642         {
643           /* Declare void _Jv_Throw (void *).  */
644           tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
645           tmp = build_function_type (ptr_type_node, tmp);
646           fn = push_throw_library_fn (fn, tmp);
647         }
648       else if (really_overloaded_fn (fn))
649         {\r
650           error ("`%D' should never be overloaded", fn);
651           return error_mark_node;\r
652         }
653       fn = OVL_CURRENT (fn);
654       exp = build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE));
655     }
656   else if (exp)
657     {
658       tree throw_type;
659       tree cleanup;
660       tree object, ptr;
661       tree tmp;
662       tree temp_expr, allocate_expr;
663
664       fn = get_identifier ("__cxa_throw");
665       if (!get_global_value_if_present (fn, &fn))
666         {
667           /* The CLEANUP_TYPE is the internal type of a destructor.  */
668           if (cleanup_type == NULL_TREE)
669             {
670               tmp = void_list_node;
671               tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
672               tmp = build_function_type (void_type_node, tmp);
673               cleanup_type = build_pointer_type (tmp);
674             }
675
676           /* Declare void __cxa_throw (void*, void*, void (*)(void*)).  */
677           /* ??? Second argument is supposed to be "std::type_info*".  */
678           tmp = void_list_node;
679           tmp = tree_cons (NULL_TREE, cleanup_type, tmp);
680           tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
681           tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
682           tmp = build_function_type (void_type_node, tmp);
683           fn = push_throw_library_fn (fn, tmp);
684         }
685
686       /* throw expression */
687       /* First, decay it.  */
688       exp = decay_conversion (exp);
689
690       /* OK, this is kind of wacky.  The standard says that we call
691          terminate when the exception handling mechanism, after
692          completing evaluation of the expression to be thrown but
693          before the exception is caught (_except.throw_), calls a
694          user function that exits via an uncaught exception.
695
696          So we have to protect the actual initialization of the
697          exception object with terminate(), but evaluate the
698          expression first.  Since there could be temps in the
699          expression, we need to handle that, too.  We also expand
700          the call to __cxa_allocate_exception first (which doesn't
701          matter, since it can't throw).  */
702
703       /* Pre-evaluate the thrown expression first, since if we allocated
704          the space first we would have to deal with cleaning it up if
705          evaluating this expression throws.  */
706       exp = stabilize_throw_expr (exp, &temp_expr);
707
708       /* Allocate the space for the exception.  */
709       allocate_expr = do_allocate_exception (TREE_TYPE (exp));
710       allocate_expr = get_target_expr (allocate_expr);
711       ptr = TARGET_EXPR_SLOT (allocate_expr);
712       object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
713       object = build_indirect_ref (object, NULL);
714
715       /* And initialize the exception object.  */
716       exp = build_init (object, exp, LOOKUP_ONLYCONVERTING);
717       if (exp == error_mark_node)
718         {
719           error ("  in thrown expression");
720           return error_mark_node;
721         }
722
723       exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
724       /* Prepend the allocation.  */
725       exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
726       if (temp_expr != void_zero_node)
727         {
728           /* Prepend the calculation of the throw expression.  Also, force
729              any cleanups from the expression to be evaluated here so that
730              we don't have to do them during unwinding.  But first wrap
731              them in MUST_NOT_THROW_EXPR, since they are run after the
732              exception object is initialized.  */
733           walk_tree_without_duplicates (&temp_expr, wrap_cleanups_r, 0);
734           exp = build (COMPOUND_EXPR, TREE_TYPE (exp), temp_expr, exp);
735           exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
736         }
737
738       throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
739
740       if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (object)))
741         {
742           cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
743                                      complete_dtor_identifier, 0);
744           cleanup = BASELINK_FUNCTIONS (cleanup);
745           mark_used (cleanup);
746           cxx_mark_addressable (cleanup);
747           /* Pretend it's a normal function.  */
748           cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);
749         }
750       else
751         {
752           cleanup = build_int_2 (0, 0);
753           TREE_TYPE (cleanup) = cleanup_type;
754         }
755
756       tmp = tree_cons (NULL_TREE, cleanup, NULL_TREE);
757       tmp = tree_cons (NULL_TREE, throw_type, tmp);
758       tmp = tree_cons (NULL_TREE, ptr, tmp);
759       /* ??? Indicate that this function call throws throw_type.  */
760       tmp = build_function_call (fn, tmp);
761
762       /* Tack on the initialization stuff.  */
763       exp = build (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp);
764     }
765   else
766     {
767       /* Rethrow current exception.  */
768
769       tree fn = get_identifier ("__cxa_rethrow");
770       if (!get_global_value_if_present (fn, &fn))
771         {
772           /* Declare void __cxa_rethrow (void).  */
773           fn = push_throw_library_fn
774             (fn, build_function_type (void_type_node, void_list_node));
775         }
776
777       /* ??? Indicate that this function call allows exceptions of the type
778          of the enclosing catch block (if known).  */    
779       exp = build_function_call (fn, NULL_TREE);
780     }
781
782   exp = build1 (THROW_EXPR, void_type_node, exp);
783
784   return exp;
785 }
786
787 /* Make sure TYPE is complete, pointer to complete, reference to
788    complete, or pointer to cv void. Issue diagnostic on failure.
789    Return the zero on failure and nonzero on success. FROM can be
790    the expr or decl from whence TYPE came, if available.  */
791
792 static int
793 complete_ptr_ref_or_void_ptr_p (tree type, tree from)
794 {
795   int is_ptr;
796   
797   /* Check complete.  */
798   type = complete_type_or_else (type, from);
799   if (!type)
800     return 0;
801   
802   /* Or a pointer or ref to one, or cv void *.  */
803   is_ptr = TREE_CODE (type) == POINTER_TYPE;
804   if (is_ptr || TREE_CODE (type) == REFERENCE_TYPE)
805     {
806       tree core = TREE_TYPE (type);
807   
808       if (is_ptr && VOID_TYPE_P (core))
809         /* OK */;
810       else if (!complete_type_or_else (core, from))
811         return 0;
812     }
813   return 1;
814 }
815
816 /* Return truth-value if EXPRESSION is admissible in throw-expression,
817    i.e. if it is not of incomplete type or a pointer/reference to such
818    a type or of an abstract class type.  */
819
820 static bool
821 is_admissible_throw_operand (tree expr)
822 {
823   tree type = TREE_TYPE (expr);
824
825   /* 15.1/4 [...] The type of the throw-expression shall not be an
826             incomplete type, or a pointer or a reference to an incomplete
827             type, other than void*, const void*, volatile void*, or
828             const volatile void*.  Except for these restriction and the
829             restrictions on type matching mentioned in 15.3, the operand
830             of throw is treated exactly as a function argument in a call
831             (5.2.2) or the operand of a return statement.  */
832   if (!complete_ptr_ref_or_void_ptr_p (type, expr))
833     return false;
834
835   /* 10.4/3 An abstract class shall not be used as a parameter type,
836             as a function return type or as type of an explicit
837             conversion.  */
838   else if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type))
839     {
840       error ("expression '%E' of abstract class type '%T' cannot be used in throw-expression", expr, type);
841       return false;
842     }
843
844   return true;
845 }
846
847 /* Returns nonzero if FN is a declaration of a standard C library
848    function which is known not to throw.
849
850    [lib.res.on.exception.handling]: None of the functions from the
851    Standard C library shall report an error by throwing an
852    exception, unless it calls a program-supplied function that
853    throws an exception.  */
854
855 #include "cfns.h"
856
857 int
858 nothrow_libfn_p (tree fn)
859 {
860   tree id;
861
862   if (TREE_PUBLIC (fn)
863       && DECL_EXTERNAL (fn)
864       && DECL_NAMESPACE_SCOPE_P (fn)
865       && DECL_EXTERN_C_P (fn))
866     /* OK */;
867   else
868     /* Can't be a C library function.  */
869     return 0;
870
871   id = DECL_ASSEMBLER_NAME (fn);
872   return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
873 }
874
875 /* Returns nonzero if an exception of type FROM will be caught by a
876    handler for type TO, as per [except.handle].  */
877
878 static int
879 can_convert_eh (tree to, tree from)
880 {
881   to = non_reference (to);
882   from = non_reference (from);
883
884   if (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
885     {
886       to = TREE_TYPE (to);
887       from = TREE_TYPE (from);
888
889       if (! at_least_as_qualified_p (to, from))
890         return 0;
891
892       if (TREE_CODE (to) == VOID_TYPE)
893         return 1;
894
895       /* else fall through */
896     }
897
898   if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
899       && PUBLICLY_UNIQUELY_DERIVED_P (to, from))
900     return 1;
901
902   return 0;
903 }
904
905 /* Check whether any of HANDLERS are shadowed by another handler accepting
906    TYPE.  Note that the shadowing may not be complete; even if an exception
907    of type B would be caught by a handler for A, there could be a derived
908    class C for which A is an ambiguous base but B is not, so the handler
909    for B would catch an exception of type C.  */
910
911 static void
912 check_handlers_1 (tree master, tree handlers)
913 {
914   tree type = TREE_TYPE (master);
915   tree handler;
916
917   for (handler = handlers; handler; handler = TREE_CHAIN (handler))
918     if (TREE_TYPE (handler)
919         && can_convert_eh (type, TREE_TYPE (handler)))
920       {
921         input_line = STMT_LINENO (handler);
922         warning ("exception of type `%T' will be caught",
923                     TREE_TYPE (handler));
924         input_line = STMT_LINENO (master);
925         warning ("   by earlier handler for `%T'", type);
926         break;
927       }
928 }
929
930 /* Given a chain of HANDLERs, make sure that they're OK.  */
931
932 void
933 check_handlers (tree handlers)
934 {
935   tree handler;
936   int save_line = input_line;
937   
938   for (handler = handlers; handler; handler = TREE_CHAIN (handler))
939     {
940       if (TREE_CHAIN (handler) == NULL_TREE)
941         /* No more handlers; nothing to shadow.  */;
942       else if (TREE_TYPE (handler) == NULL_TREE)
943         {
944           input_line = STMT_LINENO (handler);
945           pedwarn
946             ("`...' handler must be the last handler for its try block");
947         }
948       else
949         check_handlers_1 (handler, TREE_CHAIN (handler));
950     }
951   input_line = save_line;
952 }