OSDN Git Service

.:
[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 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   EH_SPEC_STMTS (r) = push_stmt_list ();
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   EH_SPEC_STMTS (eh_spec_block) = pop_stmt_list (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 /* Call __cxa_free_exception from a cleanup.  This is never invoked
511    directly, but see the comment for stabilize_throw_expr.  */
512
513 static tree
514 do_free_exception (tree ptr)
515 {
516   tree fn;
517
518   fn = get_identifier ("__cxa_free_exception");
519   if (!get_global_value_if_present (fn, &fn))
520     {
521       /* Declare void __cxa_free_exception (void *).  */
522       fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
523                                                 void_list_node));
524     }
525
526   return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
527 }
528
529 /* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
530    Called from build_throw via walk_tree_without_duplicates.  */
531
532 static tree
533 wrap_cleanups_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
534                  void *data ATTRIBUTE_UNUSED)
535 {
536   tree exp = *tp;
537   tree cleanup;
538
539   /* Don't walk into types.  */
540   if (TYPE_P (exp))
541     {
542       *walk_subtrees = 0;
543       return NULL_TREE;
544     }
545   if (TREE_CODE (exp) != TARGET_EXPR)
546     return NULL_TREE;
547
548   cleanup = TARGET_EXPR_CLEANUP (exp);
549   if (cleanup)
550     {
551       cleanup = build1 (MUST_NOT_THROW_EXPR, void_type_node, cleanup);
552       TARGET_EXPR_CLEANUP (exp) = cleanup;
553     }
554
555   /* Keep iterating.  */
556   return NULL_TREE;
557 }
558
559 /* Build a throw expression.  */
560
561 tree
562 build_throw (tree exp)
563 {
564   tree fn;
565
566   if (exp == error_mark_node)
567     return exp;
568
569   if (processing_template_decl)
570     {
571       current_function_returns_abnormally = 1;
572       return build_min (THROW_EXPR, void_type_node, exp);
573     }
574
575   if (exp == null_node)
576     warning ("throwing NULL, which has integral, not pointer type");
577   
578   if (exp != NULL_TREE)
579     {
580       if (!is_admissible_throw_operand (exp))
581         return error_mark_node;
582     }
583
584   if (! doing_eh (1))
585     return error_mark_node;
586
587   if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
588     {
589       tree fn = get_identifier ("_Jv_Throw");
590       if (!get_global_value_if_present (fn, &fn))
591         {
592           /* Declare void _Jv_Throw (void *).  */
593           tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
594           tmp = build_function_type (ptr_type_node, tmp);
595           fn = push_throw_library_fn (fn, tmp);
596         }
597       else if (really_overloaded_fn (fn))
598         {
599           error ("`%D' should never be overloaded", fn);
600           return error_mark_node;
601         }
602       fn = OVL_CURRENT (fn);
603       exp = build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE));
604     }
605   else if (exp)
606     {
607       tree throw_type;
608       tree cleanup;
609       tree object, ptr;
610       tree tmp;
611       tree temp_expr, allocate_expr;
612       bool elided;
613
614       /* The CLEANUP_TYPE is the internal type of a destructor.  */
615       if (!cleanup_type)
616         {
617           tmp = void_list_node;
618           tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
619           tmp = build_function_type (void_type_node, tmp);
620           cleanup_type = build_pointer_type (tmp);
621         }
622       
623       fn = get_identifier ("__cxa_throw");
624       if (!get_global_value_if_present (fn, &fn))
625         {
626           /* Declare void __cxa_throw (void*, void*, void (*)(void*)).  */
627           /* ??? Second argument is supposed to be "std::type_info*".  */
628           tmp = void_list_node;
629           tmp = tree_cons (NULL_TREE, cleanup_type, tmp);
630           tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
631           tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
632           tmp = build_function_type (void_type_node, tmp);
633           fn = push_throw_library_fn (fn, tmp);
634         }
635       
636       /* throw expression */
637       /* First, decay it.  */
638       exp = decay_conversion (exp);
639
640       /* OK, this is kind of wacky.  The standard says that we call
641          terminate when the exception handling mechanism, after
642          completing evaluation of the expression to be thrown but
643          before the exception is caught (_except.throw_), calls a
644          user function that exits via an uncaught exception.
645
646          So we have to protect the actual initialization of the
647          exception object with terminate(), but evaluate the
648          expression first.  Since there could be temps in the
649          expression, we need to handle that, too.  We also expand
650          the call to __cxa_allocate_exception first (which doesn't
651          matter, since it can't throw).  */
652
653       /* Allocate the space for the exception.  */
654       allocate_expr = do_allocate_exception (TREE_TYPE (exp));
655       allocate_expr = get_target_expr (allocate_expr);
656       ptr = TARGET_EXPR_SLOT (allocate_expr);
657       object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
658       object = build_indirect_ref (object, NULL);
659
660       elided = (TREE_CODE (exp) == TARGET_EXPR);
661
662       /* And initialize the exception object.  */
663       exp = build_init (object, exp, LOOKUP_ONLYCONVERTING);
664       if (exp == error_mark_node)
665         {
666           error ("  in thrown expression");
667           return error_mark_node;
668         }
669
670       /* Pre-evaluate the thrown expression first, since if we allocated
671          the space first we would have to deal with cleaning it up if
672          evaluating this expression throws.
673
674          The case where EXP the initializer is a call to a constructor or a
675          function returning a class is a bit of a grey area in the
676          standard; it's unclear whether or not it should be allowed to
677          throw.  We used to say no, as that allowed us to optimize this
678          case without worrying about deallocating the exception object if
679          it does.  But that conflicted with expectations (PR 13944) and the
680          EDG compiler; now we wrap the initialization in a TRY_CATCH_EXPR
681          to call do_free_exception rather than in a MUST_NOT_THROW_EXPR,
682          for this case only.
683
684          Note that we don't check the return value from stabilize_init
685          because it will only return false in cases where elided is true,
686          and therefore we don't need to work around the failure to
687          preevaluate.  */
688       temp_expr = NULL_TREE;
689       stabilize_init (exp, &temp_expr);
690
691       if (elided)
692         exp = build (TRY_CATCH_EXPR, void_type_node, exp,
693                      do_free_exception (ptr));
694       else
695         exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
696
697       /* Prepend the allocation.  */
698       exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
699       if (temp_expr)
700         {
701           /* Prepend the calculation of the throw expression.  Also, force
702              any cleanups from the expression to be evaluated here so that
703              we don't have to do them during unwinding.  But first wrap
704              them in MUST_NOT_THROW_EXPR, since they are run after the
705              exception object is initialized.  */
706           walk_tree_without_duplicates (&temp_expr, wrap_cleanups_r, 0);
707           exp = build (COMPOUND_EXPR, TREE_TYPE (exp), temp_expr, exp);
708           exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
709         }
710
711       throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
712
713       if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (object)))
714         {
715           cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
716                                      complete_dtor_identifier, 0);
717           cleanup = BASELINK_FUNCTIONS (cleanup);
718           mark_used (cleanup);
719           cxx_mark_addressable (cleanup);
720           /* Pretend it's a normal function.  */
721           cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);
722         }
723       else
724         cleanup = build_int_cst (cleanup_type, 0, 0);
725         
726       tmp = tree_cons (NULL_TREE, cleanup, NULL_TREE);
727       tmp = tree_cons (NULL_TREE, throw_type, tmp);
728       tmp = tree_cons (NULL_TREE, ptr, tmp);
729       /* ??? Indicate that this function call throws throw_type.  */
730       tmp = build_function_call (fn, tmp);
731
732       /* Tack on the initialization stuff.  */
733       exp = build (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp);
734     }
735   else
736     {
737       /* Rethrow current exception.  */
738
739       tree fn = get_identifier ("__cxa_rethrow");
740       if (!get_global_value_if_present (fn, &fn))
741         {
742           /* Declare void __cxa_rethrow (void).  */
743           fn = push_throw_library_fn
744             (fn, build_function_type (void_type_node, void_list_node));
745         }
746
747       /* ??? Indicate that this function call allows exceptions of the type
748          of the enclosing catch block (if known).  */    
749       exp = build_function_call (fn, NULL_TREE);
750     }
751
752   exp = build1 (THROW_EXPR, void_type_node, exp);
753
754   return exp;
755 }
756
757 /* Make sure TYPE is complete, pointer to complete, reference to
758    complete, or pointer to cv void. Issue diagnostic on failure.
759    Return the zero on failure and nonzero on success. FROM can be
760    the expr or decl from whence TYPE came, if available.  */
761
762 static int
763 complete_ptr_ref_or_void_ptr_p (tree type, tree from)
764 {
765   int is_ptr;
766   
767   /* Check complete.  */
768   type = complete_type_or_else (type, from);
769   if (!type)
770     return 0;
771   
772   /* Or a pointer or ref to one, or cv void *.  */
773   is_ptr = TREE_CODE (type) == POINTER_TYPE;
774   if (is_ptr || TREE_CODE (type) == REFERENCE_TYPE)
775     {
776       tree core = TREE_TYPE (type);
777   
778       if (is_ptr && VOID_TYPE_P (core))
779         /* OK */;
780       else if (!complete_type_or_else (core, from))
781         return 0;
782     }
783   return 1;
784 }
785
786 /* Return truth-value if EXPRESSION is admissible in throw-expression,
787    i.e. if it is not of incomplete type or a pointer/reference to such
788    a type or of an abstract class type.  */
789
790 static bool
791 is_admissible_throw_operand (tree expr)
792 {
793   tree type = TREE_TYPE (expr);
794
795   /* 15.1/4 [...] The type of the throw-expression shall not be an
796             incomplete type, or a pointer or a reference to an incomplete
797             type, other than void*, const void*, volatile void*, or
798             const volatile void*.  Except for these restriction and the
799             restrictions on type matching mentioned in 15.3, the operand
800             of throw is treated exactly as a function argument in a call
801             (5.2.2) or the operand of a return statement.  */
802   if (!complete_ptr_ref_or_void_ptr_p (type, expr))
803     return false;
804
805   /* 10.4/3 An abstract class shall not be used as a parameter type,
806             as a function return type or as type of an explicit
807             conversion.  */
808   else if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type))
809     {
810       error ("expression '%E' of abstract class type '%T' cannot be used in throw-expression", expr, type);
811       return false;
812     }
813
814   return true;
815 }
816
817 /* Returns nonzero if FN is a declaration of a standard C library
818    function which is known not to throw.
819
820    [lib.res.on.exception.handling]: None of the functions from the
821    Standard C library shall report an error by throwing an
822    exception, unless it calls a program-supplied function that
823    throws an exception.  */
824
825 #include "cfns.h"
826
827 int
828 nothrow_libfn_p (tree fn)
829 {
830   tree id;
831
832   if (TREE_PUBLIC (fn)
833       && DECL_EXTERNAL (fn)
834       && DECL_NAMESPACE_SCOPE_P (fn)
835       && DECL_EXTERN_C_P (fn))
836     /* OK */;
837   else
838     /* Can't be a C library function.  */
839     return 0;
840
841   /* Being a C library function, DECL_ASSEMBLER_NAME == DECL_NAME
842      unless the system headers are playing rename tricks, and if
843      they are, we don't want to be confused by them.  */
844   id = DECL_NAME (fn);
845   return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
846 }
847
848 /* Returns nonzero if an exception of type FROM will be caught by a
849    handler for type TO, as per [except.handle].  */
850
851 static int
852 can_convert_eh (tree to, tree from)
853 {
854   to = non_reference (to);
855   from = non_reference (from);
856
857   if (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
858     {
859       to = TREE_TYPE (to);
860       from = TREE_TYPE (from);
861
862       if (! at_least_as_qualified_p (to, from))
863         return 0;
864
865       if (TREE_CODE (to) == VOID_TYPE)
866         return 1;
867
868       /* Else fall through.  */
869     }
870
871   if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
872       && PUBLICLY_UNIQUELY_DERIVED_P (to, from))
873     return 1;
874
875   return 0;
876 }
877
878 /* Check whether any of the handlers in I are shadowed by another handler
879    accepting TYPE.  Note that the shadowing may not be complete; even if
880    an exception of type B would be caught by a handler for A, there could
881    be a derived class C for which A is an ambiguous base but B is not, so
882    the handler for B would catch an exception of type C.  */
883
884 static void
885 check_handlers_1 (tree master, tree_stmt_iterator i)
886 {
887   tree type = TREE_TYPE (master);
888
889   for (; !tsi_end_p (i); tsi_next (&i))
890     {
891       tree handler = tsi_stmt (i);
892       if (TREE_TYPE (handler) && can_convert_eh (type, TREE_TYPE (handler)))
893         {
894           warning ("%Hexception of type `%T' will be caught",
895                    EXPR_LOCUS (handler), TREE_TYPE (handler));
896           warning ("%H   by earlier handler for `%T'",
897                    EXPR_LOCUS (master), type);
898           break;
899         }
900     }
901 }
902
903 /* Given a STATEMENT_LIST of HANDLERs, make sure that they're OK.  */
904
905 void
906 check_handlers (tree handlers)
907 {
908   tree_stmt_iterator i;
909
910   /* If we don't have a STATEMENT_LIST, then we've just got one
911      handler, and thus nothing to warn about.  */
912   if (TREE_CODE (handlers) != STATEMENT_LIST)
913     return;
914
915   i = tsi_start (handlers);
916   if (!tsi_end_p (i))
917     while (1)
918       {
919         tree handler = tsi_stmt (i);
920         tsi_next (&i);
921
922         /* No more handlers; nothing to shadow.  */
923         if (tsi_end_p (i))
924           break;
925         if (TREE_TYPE (handler) == NULL_TREE)
926           pedwarn ("%H`...' handler must be the last handler for"
927                    " its try block", EXPR_LOCUS (handler));
928         else
929           check_handlers_1 (handler, i);
930       }
931 }