OSDN Git Service

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