OSDN Git Service

* Make-lang.in, call.c, class.c, decl2.c, except.c, expr.c,
[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
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     {
625       current_function_returns_abnormally = 1;
626       return build_min (THROW_EXPR, void_type_node, exp);
627     }
628
629   if (exp == null_node)
630     warning ("throwing NULL, which has integral, not pointer type");
631   
632   if (exp != NULL_TREE)
633     {
634       if (!is_admissible_throw_operand (exp))
635         return error_mark_node;
636     }
637
638   if (! doing_eh (1))
639     return error_mark_node;
640
641   if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
642     {
643       tree fn = get_identifier ("_Jv_Throw");
644       if (!get_global_value_if_present (fn, &fn))
645         {
646           /* Declare void _Jv_Throw (void *).  */
647           tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
648           tmp = build_function_type (ptr_type_node, tmp);
649           fn = push_throw_library_fn (fn, tmp);
650         }
651       else if (really_overloaded_fn (fn))
652         {\r
653           error ("`%D' should never be overloaded", fn);
654           return error_mark_node;\r
655         }
656       fn = OVL_CURRENT (fn);
657       exp = build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE));
658     }
659   else if (exp)
660     {
661       tree throw_type;
662       tree cleanup;
663       tree object, ptr;
664       tree tmp;
665       tree temp_expr, allocate_expr;
666
667       fn = get_identifier ("__cxa_throw");
668       if (!get_global_value_if_present (fn, &fn))
669         {
670           /* The CLEANUP_TYPE is the internal type of a destructor.  */
671           if (cleanup_type == NULL_TREE)
672             {
673               tmp = void_list_node;
674               tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
675               tmp = build_function_type (void_type_node, tmp);
676               cleanup_type = build_pointer_type (tmp);
677             }
678
679           /* Declare void __cxa_throw (void*, void*, void (*)(void*)).  */
680           /* ??? Second argument is supposed to be "std::type_info*".  */
681           tmp = void_list_node;
682           tmp = tree_cons (NULL_TREE, cleanup_type, tmp);
683           tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
684           tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
685           tmp = build_function_type (void_type_node, tmp);
686           fn = push_throw_library_fn (fn, tmp);
687         }
688
689       /* throw expression */
690       /* First, decay it.  */
691       exp = decay_conversion (exp);
692
693       /* OK, this is kind of wacky.  The standard says that we call
694          terminate when the exception handling mechanism, after
695          completing evaluation of the expression to be thrown but
696          before the exception is caught (_except.throw_), calls a
697          user function that exits via an uncaught exception.
698
699          So we have to protect the actual initialization of the
700          exception object with terminate(), but evaluate the
701          expression first.  Since there could be temps in the
702          expression, we need to handle that, too.  We also expand
703          the call to __cxa_allocate_exception first (which doesn't
704          matter, since it can't throw).  */
705
706       /* Pre-evaluate the thrown expression first, since if we allocated
707          the space first we would have to deal with cleaning it up if
708          evaluating this expression throws.  */
709       exp = stabilize_throw_expr (exp, &temp_expr);
710
711       /* Allocate the space for the exception.  */
712       allocate_expr = do_allocate_exception (TREE_TYPE (exp));
713       allocate_expr = get_target_expr (allocate_expr);
714       ptr = TARGET_EXPR_SLOT (allocate_expr);
715       object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
716       object = build_indirect_ref (object, NULL);
717
718       /* And initialize the exception object.  */
719       exp = build_init (object, exp, LOOKUP_ONLYCONVERTING);
720       if (exp == error_mark_node)
721         {
722           error ("  in thrown expression");
723           return error_mark_node;
724         }
725
726       exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
727       /* Prepend the allocation.  */
728       exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
729       if (temp_expr != void_zero_node)
730         {
731           /* Prepend the calculation of the throw expression.  Also, force
732              any cleanups from the expression to be evaluated here so that
733              we don't have to do them during unwinding.  But first wrap
734              them in MUST_NOT_THROW_EXPR, since they are run after the
735              exception object is initialized.  */
736           walk_tree_without_duplicates (&temp_expr, wrap_cleanups_r, 0);
737           exp = build (COMPOUND_EXPR, TREE_TYPE (exp), temp_expr, exp);
738           exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
739         }
740
741       throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
742
743       if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (object)))
744         {
745           cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
746                                      complete_dtor_identifier, 0);
747           cleanup = BASELINK_FUNCTIONS (cleanup);
748           mark_used (cleanup);
749           cxx_mark_addressable (cleanup);
750           /* Pretend it's a normal function.  */
751           cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);
752         }
753       else
754         {
755           cleanup = build_int_2 (0, 0);
756           TREE_TYPE (cleanup) = cleanup_type;
757         }
758
759       tmp = tree_cons (NULL_TREE, cleanup, NULL_TREE);
760       tmp = tree_cons (NULL_TREE, throw_type, tmp);
761       tmp = tree_cons (NULL_TREE, ptr, tmp);
762       /* ??? Indicate that this function call throws throw_type.  */
763       tmp = build_function_call (fn, tmp);
764
765       /* Tack on the initialization stuff.  */
766       exp = build (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp);
767     }
768   else
769     {
770       /* Rethrow current exception.  */
771
772       tree fn = get_identifier ("__cxa_rethrow");
773       if (!get_global_value_if_present (fn, &fn))
774         {
775           /* Declare void __cxa_rethrow (void).  */
776           fn = push_throw_library_fn
777             (fn, build_function_type (void_type_node, void_list_node));
778         }
779
780       /* ??? Indicate that this function call allows exceptions of the type
781          of the enclosing catch block (if known).  */    
782       exp = build_function_call (fn, NULL_TREE);
783     }
784
785   exp = build1 (THROW_EXPR, void_type_node, exp);
786
787   return exp;
788 }
789
790 /* Make sure TYPE is complete, pointer to complete, reference to
791    complete, or pointer to cv void. Issue diagnostic on failure.
792    Return the zero on failure and nonzero on success. FROM can be
793    the expr or decl from whence TYPE came, if available.  */
794
795 static int
796 complete_ptr_ref_or_void_ptr_p (tree type, tree from)
797 {
798   int is_ptr;
799   
800   /* Check complete.  */
801   type = complete_type_or_else (type, from);
802   if (!type)
803     return 0;
804   
805   /* Or a pointer or ref to one, or cv void *.  */
806   is_ptr = TREE_CODE (type) == POINTER_TYPE;
807   if (is_ptr || TREE_CODE (type) == REFERENCE_TYPE)
808     {
809       tree core = TREE_TYPE (type);
810   
811       if (is_ptr && VOID_TYPE_P (core))
812         /* OK */;
813       else if (!complete_type_or_else (core, from))
814         return 0;
815     }
816   return 1;
817 }
818
819 /* Return truth-value if EXPRESSION is admissible in throw-expression,
820    i.e. if it is not of incomplete type or a pointer/reference to such
821    a type or of an abstract class type.  */
822
823 static bool
824 is_admissible_throw_operand (tree expr)
825 {
826   tree type = TREE_TYPE (expr);
827
828   /* 15.1/4 [...] The type of the throw-expression shall not be an
829             incomplete type, or a pointer or a reference to an incomplete
830             type, other than void*, const void*, volatile void*, or
831             const volatile void*.  Except for these restriction and the
832             restrictions on type matching mentioned in 15.3, the operand
833             of throw is treated exactly as a function argument in a call
834             (5.2.2) or the operand of a return statement.  */
835   if (!complete_ptr_ref_or_void_ptr_p (type, expr))
836     return false;
837
838   /* 10.4/3 An abstract class shall not be used as a parameter type,
839             as a function return type or as type of an explicit
840             conversion.  */
841   else if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type))
842     {
843       error ("expression '%E' of abstract class type '%T' cannot be used in throw-expression", expr, type);
844       return false;
845     }
846
847   return true;
848 }
849
850 /* Returns nonzero if FN is a declaration of a standard C library
851    function which is known not to throw.
852
853    [lib.res.on.exception.handling]: None of the functions from the
854    Standard C library shall report an error by throwing an
855    exception, unless it calls a program-supplied function that
856    throws an exception.  */
857
858 #include "cfns.h"
859
860 int
861 nothrow_libfn_p (tree fn)
862 {
863   tree id;
864
865   if (TREE_PUBLIC (fn)
866       && DECL_EXTERNAL (fn)
867       && DECL_NAMESPACE_SCOPE_P (fn)
868       && DECL_EXTERN_C_P (fn))
869     /* OK */;
870   else
871     /* Can't be a C library function.  */
872     return 0;
873
874   id = DECL_ASSEMBLER_NAME (fn);
875   return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
876 }
877
878 /* Returns nonzero if an exception of type FROM will be caught by a
879    handler for type TO, as per [except.handle].  */
880
881 static int
882 can_convert_eh (tree to, tree from)
883 {
884   to = non_reference (to);
885   from = non_reference (from);
886
887   if (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
888     {
889       to = TREE_TYPE (to);
890       from = TREE_TYPE (from);
891
892       if (! at_least_as_qualified_p (to, from))
893         return 0;
894
895       if (TREE_CODE (to) == VOID_TYPE)
896         return 1;
897
898       /* Else fall through.  */
899     }
900
901   if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
902       && PUBLICLY_UNIQUELY_DERIVED_P (to, from))
903     return 1;
904
905   return 0;
906 }
907
908 /* Check whether any of HANDLERS are shadowed by another handler accepting
909    TYPE.  Note that the shadowing may not be complete; even if an exception
910    of type B would be caught by a handler for A, there could be a derived
911    class C for which A is an ambiguous base but B is not, so the handler
912    for B would catch an exception of type C.  */
913
914 static void
915 check_handlers_1 (tree master, tree handlers)
916 {
917   tree type = TREE_TYPE (master);
918   tree handler;
919
920   for (handler = handlers; handler; handler = TREE_CHAIN (handler))
921     if (TREE_TYPE (handler)
922         && can_convert_eh (type, TREE_TYPE (handler)))
923       {
924         input_line = STMT_LINENO (handler);
925         warning ("exception of type `%T' will be caught",
926                     TREE_TYPE (handler));
927         input_line = STMT_LINENO (master);
928         warning ("   by earlier handler for `%T'", type);
929         break;
930       }
931 }
932
933 /* Given a chain of HANDLERs, make sure that they're OK.  */
934
935 void
936 check_handlers (tree handlers)
937 {
938   tree handler;
939   int save_line = input_line;
940   
941   for (handler = handlers; handler; handler = TREE_CHAIN (handler))
942     {
943       if (TREE_CHAIN (handler) == NULL_TREE)
944         /* No more handlers; nothing to shadow.  */;
945       else if (TREE_TYPE (handler) == NULL_TREE)
946         {
947           input_line = STMT_LINENO (handler);
948           pedwarn
949             ("`...' handler must be the last handler for its try block");
950         }
951       else
952         check_handlers_1 (handler, TREE_CHAIN (handler));
953     }
954   input_line = save_line;
955 }