OSDN Git Service

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