Bring in a trimmed down gcc-3.4-20040618.
[dragonfly.git] / contrib / gcc-3.4 / 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
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 wrap_cleanups_r (tree *, int *, void *);
51 static int complete_ptr_ref_or_void_ptr_p (tree, tree);
52 static bool is_admissible_throw_operand (tree);
53 static int can_convert_eh (tree, tree);
54 static void check_handlers_1 (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 build1 (ADDR_EXPR, ptr_type_node, exp);
148 }
149
150 tree
151 build_exc_ptr (void)
152 {
153   return build (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 (! TYPE_HAS_DESTRUCTOR (type))
186     return 1;
187
188   return TREE_NOTHROW (CLASSTYPE_DESTRUCTORS (type));
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
194 static tree
195 do_end_catch (tree type)
196 {
197   tree fn, cleanup;
198
199   fn = get_identifier ("__cxa_end_catch");
200   if (!get_global_value_if_present (fn, &fn))
201     {
202       /* Declare void __cxa_end_catch ().  */
203       fn = push_void_library_fn (fn, void_list_node);
204       /* This can throw if the destructor for the exception throws.  */
205       TREE_NOTHROW (fn) = 0;
206     }
207
208   cleanup = build_function_call (fn, NULL_TREE);
209   TREE_NOTHROW (cleanup) = dtor_nothrow (type);
210
211   return cleanup;
212 }
213
214 /* This routine creates the cleanup for the current exception.  */
215
216 static void
217 push_eh_cleanup (tree type)
218 {
219   finish_decl_cleanup (NULL_TREE, do_end_catch (type));
220 }
221
222 /* Return nonzero value if DECL is a Java type suitable for catch or
223    throw.  */
224
225 static bool
226 decl_is_java_type (tree decl, int err)
227 {
228   bool r = (TREE_CODE (decl) == POINTER_TYPE
229             && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
230             && TYPE_FOR_JAVA (TREE_TYPE (decl)));
231
232   if (err)
233     {
234       if (TREE_CODE (decl) == REFERENCE_TYPE
235           && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
236           && TYPE_FOR_JAVA (TREE_TYPE (decl)))
237         {
238           /* Can't throw a reference.  */
239           error ("type `%T' is disallowed in Java `throw' or `catch'",
240                     decl);
241         }
242
243       if (r)
244         {
245           tree jthrow_node
246             = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jthrowable"));
247
248           if (jthrow_node == NULL_TREE)
249             fatal_error
250               ("call to Java `catch' or `throw' with `jthrowable' undefined");
251
252           jthrow_node = TREE_TYPE (TREE_TYPE (jthrow_node));
253
254           if (! DERIVED_FROM_P (jthrow_node, TREE_TYPE (decl)))
255             {
256               /* Thrown object must be a Throwable.  */
257               error ("type `%T' is not derived from `java::lang::Throwable'",
258                         TREE_TYPE (decl));
259             }
260         }
261     }
262
263   return r;
264 }
265
266 /* Select the personality routine to be used for exception handling,
267    or issue an error if we need two different ones in the same
268    translation unit.
269    ??? At present eh_personality_libfunc is set to
270    __gxx_personality_(sj|v)0 in init_exception_processing - should it
271    be done here instead?  */
272 void
273 choose_personality_routine (enum languages lang)
274 {
275   static enum {
276     chose_none,
277     chose_cpp,
278     chose_java,
279     gave_error
280   } state;
281
282   switch (state)
283     {
284     case gave_error:
285       return;
286
287     case chose_cpp:
288       if (lang != lang_cplusplus)
289         goto give_error;
290       return;
291
292     case chose_java:
293       if (lang != lang_java)
294         goto give_error;
295       return;
296
297     case chose_none:
298       ; /* Proceed to language selection.  */
299     }
300
301   switch (lang)
302     {
303     case lang_cplusplus:
304       state = chose_cpp;
305       break;
306
307     case lang_java:
308       state = chose_java;
309       eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
310                                                  ? "__gcj_personality_sj0"
311                                                  : "__gcj_personality_v0");
312       break;
313
314     default:
315       abort ();
316     }
317   return;
318
319  give_error:
320   error ("mixing C++ and Java catches in a single translation unit");
321   state = gave_error;
322 }
323
324 /* Initialize the catch parameter DECL.  */
325
326 static void 
327 initialize_handler_parm (tree decl, tree exp)
328 {
329   tree init;
330   tree init_type;
331
332   /* Make sure we mark the catch param as used, otherwise we'll get a
333      warning about an unused ((anonymous)).  */
334   TREE_USED (decl) = 1;
335
336   /* Figure out the type that the initializer is.  Pointers are returned
337      adjusted by value from __cxa_begin_catch.  Others are returned by 
338      reference.  */
339   init_type = TREE_TYPE (decl);
340   if (! TYPE_PTR_P (init_type)
341       && TREE_CODE (init_type) != REFERENCE_TYPE)
342     init_type = build_reference_type (init_type);
343
344   choose_personality_routine (decl_is_java_type (init_type, 0)
345                               ? lang_java : lang_cplusplus);
346
347   /* Since pointers are passed by value, initialize a reference to
348      pointer catch parm with the address of the temporary.  */
349   if (TREE_CODE (init_type) == REFERENCE_TYPE
350       && TYPE_PTR_P (TREE_TYPE (init_type)))
351     exp = build_unary_op (ADDR_EXPR, exp, 1);
352
353   exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
354
355   init = convert_from_reference (exp);
356
357   /* If the constructor for the catch parm exits via an exception, we
358      must call terminate.  See eh23.C.  */
359   if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
360     {
361       /* Generate the copy constructor call directly so we can wrap it.
362          See also expand_default_init.  */
363       init = ocp_convert (TREE_TYPE (decl), init,
364                           CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
365       init = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (init), init);
366     }
367
368   /* Let `cp_finish_decl' know that this initializer is ok.  */
369   DECL_INITIAL (decl) = error_mark_node;
370   decl = pushdecl (decl);
371
372   start_decl_1 (decl);
373   cp_finish_decl (decl, init, NULL_TREE,
374                   LOOKUP_ONLYCONVERTING|DIRECT_BIND);
375 }
376
377 /* Call this to start a catch block.  DECL is the catch parameter.  */
378
379 tree
380 expand_start_catch_block (tree decl)
381 {
382   tree exp = NULL_TREE;
383   tree type;
384   bool is_java;
385
386   if (! doing_eh (1))
387     return NULL_TREE;
388
389   /* Make sure this declaration is reasonable.  */
390   if (decl && !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl), NULL_TREE))
391     decl = NULL_TREE;
392
393   if (decl)
394     type = prepare_eh_type (TREE_TYPE (decl));
395   else
396     type = NULL_TREE;
397
398   is_java = false;
399   if (decl)
400     {
401       tree init;
402
403       if (decl_is_java_type (type, 1))
404         {
405           /* Java only passes object via pointer and doesn't require
406              adjusting.  The java object is immediately before the
407              generic exception header.  */
408           init = build_exc_ptr ();
409           init = build1 (NOP_EXPR, build_pointer_type (type), init);
410           init = build (MINUS_EXPR, TREE_TYPE (init), init,
411                         TYPE_SIZE_UNIT (TREE_TYPE (init)));
412           init = build_indirect_ref (init, NULL);
413           is_java = true;
414         }
415       else
416         {
417           /* C++ requires that we call __cxa_begin_catch to get the
418              pointer to the actual object.  */
419           init = do_begin_catch ();
420         }
421           
422       exp = create_temporary_var (ptr_type_node);
423       DECL_REGISTER (exp) = 1;
424       cp_finish_decl (exp, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
425       finish_expr_stmt (build_modify_expr (exp, INIT_EXPR, init));
426     }
427   else
428     finish_expr_stmt (do_begin_catch ());
429
430   /* C++ requires that we call __cxa_end_catch at the end of
431      processing the exception.  */
432   if (! is_java)
433     push_eh_cleanup (type);
434
435   if (decl)
436     initialize_handler_parm (decl, exp);
437
438   return type;
439 }
440
441
442 /* Call this to end a catch block.  Its responsible for emitting the
443    code to handle jumping back to the correct place, and for emitting
444    the label to jump to if this catch block didn't match.  */
445
446 void
447 expand_end_catch_block (void)
448 {
449   if (! doing_eh (1))
450     return;
451
452   /* The exception being handled is rethrown if control reaches the end of
453      a handler of the function-try-block of a constructor or destructor.  */
454   if (in_function_try_handler
455       && (DECL_CONSTRUCTOR_P (current_function_decl)
456           || DECL_DESTRUCTOR_P (current_function_decl)))
457     finish_expr_stmt (build_throw (NULL_TREE));
458 }
459
460 tree
461 begin_eh_spec_block (void)
462 {
463   tree r = build_stmt (EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
464   add_stmt (r);
465   return r;
466 }
467
468 void
469 finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
470 {
471   tree raises;
472
473   RECHAIN_STMTS (eh_spec_block, EH_SPEC_STMTS (eh_spec_block));
474
475   /* Strip cv quals, etc, from the specification types.  */
476   for (raises = NULL_TREE;
477        raw_raises && TREE_VALUE (raw_raises);
478        raw_raises = TREE_CHAIN (raw_raises))
479     {
480       tree type = prepare_eh_type (TREE_VALUE (raw_raises));
481       tree tinfo = eh_type_info (type);
482
483       mark_used (tinfo);
484       raises = tree_cons (NULL_TREE, type, raises);
485     }
486
487   EH_SPEC_RAISES (eh_spec_block) = raises;
488 }
489
490 /* Return a pointer to a buffer for an exception object of type TYPE.  */
491
492 static tree
493 do_allocate_exception (tree type)
494 {
495   tree fn;
496
497   fn = get_identifier ("__cxa_allocate_exception");
498   if (!get_global_value_if_present (fn, &fn))
499     {
500       /* Declare void *__cxa_allocate_exception(size_t).  */
501       tree tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
502       fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
503     }
504   
505   return build_function_call (fn, tree_cons (NULL_TREE, size_in_bytes (type),
506                                              NULL_TREE));
507 }
508
509 /* Call __cxa_free_exception from a cleanup.  This is never invoked
510    directly, but see the comment for stabilize_throw_expr.  */
511
512 static tree
513 do_free_exception (tree ptr)
514 {
515   tree fn;
516
517   fn = get_identifier ("__cxa_free_exception");
518   if (!get_global_value_if_present (fn, &fn))
519     {
520       /* Declare void __cxa_free_exception (void *).  */
521       fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
522                                                 void_list_node));
523     }
524
525   return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
526 }
527
528 /* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
529    Called from build_throw via walk_tree_without_duplicates.  */
530
531 static tree
532 wrap_cleanups_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
533                  void *data ATTRIBUTE_UNUSED)
534 {
535   tree exp = *tp;
536   tree cleanup;
537
538   /* Don't walk into types.  */
539   if (TYPE_P (exp))
540     {
541       *walk_subtrees = 0;
542       return NULL_TREE;
543     }
544   if (TREE_CODE (exp) != TARGET_EXPR)
545     return NULL_TREE;
546
547   cleanup = TARGET_EXPR_CLEANUP (exp);
548   if (cleanup)
549     {
550       cleanup = build1 (MUST_NOT_THROW_EXPR, void_type_node, cleanup);
551       TARGET_EXPR_CLEANUP (exp) = cleanup;
552     }
553
554   /* Keep iterating.  */
555   return NULL_TREE;
556 }
557
558 /* Build a throw expression.  */
559
560 tree
561 build_throw (tree exp)
562 {
563   tree fn;
564
565   if (exp == error_mark_node)
566     return exp;
567
568   if (processing_template_decl)
569     {
570       current_function_returns_abnormally = 1;
571       return build_min (THROW_EXPR, void_type_node, exp);
572     }
573
574   if (exp == null_node)
575     warning ("throwing NULL, which has integral, not pointer type");
576   
577   if (exp != NULL_TREE)
578     {
579       if (!is_admissible_throw_operand (exp))
580         return error_mark_node;
581     }
582
583   if (! doing_eh (1))
584     return error_mark_node;
585
586   if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
587     {
588       tree fn = get_identifier ("_Jv_Throw");
589       if (!get_global_value_if_present (fn, &fn))
590         {
591           /* Declare void _Jv_Throw (void *).  */
592           tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
593           tmp = build_function_type (ptr_type_node, tmp);
594           fn = push_throw_library_fn (fn, tmp);
595         }
596       else if (really_overloaded_fn (fn))
597         {\r
598           error ("`%D' should never be overloaded", fn);
599           return error_mark_node;\r
600         }
601       fn = OVL_CURRENT (fn);
602       exp = build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE));
603     }
604   else if (exp)
605     {
606       tree throw_type;
607       tree cleanup;
608       tree object, ptr;
609       tree tmp;
610       tree temp_expr, allocate_expr;
611       bool elided;
612
613       fn = get_identifier ("__cxa_throw");
614       if (!get_global_value_if_present (fn, &fn))
615         {
616           /* The CLEANUP_TYPE is the internal type of a destructor.  */
617           if (cleanup_type == NULL_TREE)
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           /* Declare void __cxa_throw (void*, void*, void (*)(void*)).  */
626           /* ??? Second argument is supposed to be "std::type_info*".  */
627           tmp = void_list_node;
628           tmp = tree_cons (NULL_TREE, cleanup_type, tmp);
629           tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
630           tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
631           tmp = build_function_type (void_type_node, tmp);
632           fn = push_throw_library_fn (fn, tmp);
633         }
634
635       /* throw expression */
636       /* First, decay it.  */
637       exp = decay_conversion (exp);
638
639       /* OK, this is kind of wacky.  The standard says that we call
640          terminate when the exception handling mechanism, after
641          completing evaluation of the expression to be thrown but
642          before the exception is caught (_except.throw_), calls a
643          user function that exits via an uncaught exception.
644
645          So we have to protect the actual initialization of the
646          exception object with terminate(), but evaluate the
647          expression first.  Since there could be temps in the
648          expression, we need to handle that, too.  We also expand
649          the call to __cxa_allocate_exception first (which doesn't
650          matter, since it can't throw).  */
651
652       /* Allocate the space for the exception.  */
653       allocate_expr = do_allocate_exception (TREE_TYPE (exp));
654       allocate_expr = get_target_expr (allocate_expr);
655       ptr = TARGET_EXPR_SLOT (allocate_expr);
656       object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
657       object = build_indirect_ref (object, NULL);
658
659       elided = (TREE_CODE (exp) == TARGET_EXPR);
660
661       /* And initialize the exception object.  */
662       exp = build_init (object, exp, LOOKUP_ONLYCONVERTING);
663       if (exp == error_mark_node)
664         {
665           error ("  in thrown expression");
666           return error_mark_node;
667         }
668
669       /* Pre-evaluate the thrown expression first, since if we allocated
670          the space first we would have to deal with cleaning it up if
671          evaluating this expression throws.
672
673          The case where EXP the initializer is a call to a constructor or a
674          function returning a class is a bit of a grey area in the
675          standard; it's unclear whether or not it should be allowed to
676          throw.  We used to say no, as that allowed us to optimize this
677          case without worrying about deallocating the exception object if
678          it does.  But that conflicted with expectations (PR 13944) and the
679          EDG compiler; now we wrap the initialization in a TRY_CATCH_EXPR
680          to call do_free_exception rather than in a MUST_NOT_THROW_EXPR,
681          for this case only.
682
683          Note that we don't check the return value from stabilize_init
684          because it will only return false in cases where elided is true,
685          and therefore we don't need to work around the failure to
686          preevaluate.  */
687       temp_expr = NULL_TREE;
688       stabilize_init (exp, &temp_expr);
689
690       if (elided)
691         exp = build (TRY_CATCH_EXPR, void_type_node, exp,
692                      do_free_exception (ptr));
693       else
694         exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
695
696       /* Prepend the allocation.  */
697       exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
698       if (temp_expr)
699         {
700           /* Prepend the calculation of the throw expression.  Also, force
701              any cleanups from the expression to be evaluated here so that
702              we don't have to do them during unwinding.  But first wrap
703              them in MUST_NOT_THROW_EXPR, since they are run after the
704              exception object is initialized.  */
705           walk_tree_without_duplicates (&temp_expr, wrap_cleanups_r, 0);
706           exp = build (COMPOUND_EXPR, TREE_TYPE (exp), temp_expr, exp);
707           exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
708         }
709
710       throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
711
712       if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (object)))
713         {
714           cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
715                                      complete_dtor_identifier, 0);
716           cleanup = BASELINK_FUNCTIONS (cleanup);
717           mark_used (cleanup);
718           cxx_mark_addressable (cleanup);
719           /* Pretend it's a normal function.  */
720           cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);
721         }
722       else
723         {
724           cleanup = build_int_2 (0, 0);
725           TREE_TYPE (cleanup) = cleanup_type;
726         }
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 = build (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 '%E' of abstract class type '%T' cannot be used in throw-expression", expr, type);
813       return false;
814     }
815
816   return true;
817 }
818
819 /* Returns nonzero if FN is a declaration of a standard C library
820    function which is known not to throw.
821
822    [lib.res.on.exception.handling]: None of the functions from the
823    Standard C library shall report an error by throwing an
824    exception, unless it calls a program-supplied function that
825    throws an exception.  */
826
827 #include "cfns.h"
828
829 int
830 nothrow_libfn_p (tree fn)
831 {
832   tree id;
833
834   if (TREE_PUBLIC (fn)
835       && DECL_EXTERNAL (fn)
836       && DECL_NAMESPACE_SCOPE_P (fn)
837       && DECL_EXTERN_C_P (fn))
838     /* OK */;
839   else
840     /* Can't be a C library function.  */
841     return 0;
842
843   id = DECL_ASSEMBLER_NAME (fn);
844   return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
845 }
846
847 /* Returns nonzero if an exception of type FROM will be caught by a
848    handler for type TO, as per [except.handle].  */
849
850 static int
851 can_convert_eh (tree to, tree from)
852 {
853   to = non_reference (to);
854   from = non_reference (from);
855
856   if (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
857     {
858       to = TREE_TYPE (to);
859       from = TREE_TYPE (from);
860
861       if (! at_least_as_qualified_p (to, from))
862         return 0;
863
864       if (TREE_CODE (to) == VOID_TYPE)
865         return 1;
866
867       /* Else fall through.  */
868     }
869
870   if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
871       && PUBLICLY_UNIQUELY_DERIVED_P (to, from))
872     return 1;
873
874   return 0;
875 }
876
877 /* Check whether any of HANDLERS are shadowed by another handler accepting
878    TYPE.  Note that the shadowing may not be complete; even if an exception
879    of type B would be caught by a handler for A, there could be a derived
880    class C for which A is an ambiguous base but B is not, so the handler
881    for B would catch an exception of type C.  */
882
883 static void
884 check_handlers_1 (tree master, tree handlers)
885 {
886   tree type = TREE_TYPE (master);
887   tree handler;
888
889   for (handler = handlers; handler; handler = TREE_CHAIN (handler))
890     if (TREE_TYPE (handler)
891         && can_convert_eh (type, TREE_TYPE (handler)))
892       {
893         input_line = STMT_LINENO (handler);
894         warning ("exception of type `%T' will be caught",
895                     TREE_TYPE (handler));
896         input_line = STMT_LINENO (master);
897         warning ("   by earlier handler for `%T'", type);
898         break;
899       }
900 }
901
902 /* Given a chain of HANDLERs, make sure that they're OK.  */
903
904 void
905 check_handlers (tree handlers)
906 {
907   tree handler;
908   int save_line = input_line;
909   
910   for (handler = handlers; handler; handler = TREE_CHAIN (handler))
911     {
912       if (TREE_CHAIN (handler) == NULL_TREE)
913         /* No more handlers; nothing to shadow.  */;
914       else if (TREE_TYPE (handler) == NULL_TREE)
915         {
916           input_line = STMT_LINENO (handler);
917           pedwarn
918             ("`...' handler must be the last handler for its try block");
919         }
920       else
921         check_handlers_1 (handler, TREE_CHAIN (handler));
922     }
923   input_line = save_line;
924 }