OSDN Git Service

* g++.dg/abi/vague1.C: Use xfail, rather than embedded Tcl code.
[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 void push_eh_cleanup (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 stabilize_throw_expr (tree, tree *);
52 static tree wrap_cleanups_r (tree *, int *, void *);
53 static int complete_ptr_ref_or_void_ptr_p (tree, tree);
54 static bool is_admissible_throw_operand (tree);
55 static int can_convert_eh (tree, tree);
56 static void check_handlers_1 (tree, tree);
57 static tree cp_protect_cleanup_actions (void);
58
59 /* Sets up all the global eh stuff that needs to be initialized at the
60    start of compilation.  */
61
62 void
63 init_exception_processing (void)
64 {
65   tree tmp;
66
67   /* void std::terminate (); */
68   push_namespace (std_identifier);
69   tmp = build_function_type (void_type_node, void_list_node);
70   terminate_node = build_cp_library_fn_ptr ("terminate", tmp);
71   TREE_THIS_VOLATILE (terminate_node) = 1;
72   TREE_NOTHROW (terminate_node) = 1;
73   pop_namespace ();
74
75   /* void __cxa_call_unexpected(void *); */
76   tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
77   tmp = build_function_type (void_type_node, tmp);
78   call_unexpected_node
79     = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
80
81   eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
82                                              ? "__gxx_personality_sj0"
83                                              : "__gxx_personality_v0");
84
85   lang_eh_runtime_type = build_eh_type_type;
86   lang_protect_cleanup_actions = &cp_protect_cleanup_actions;
87 }
88
89 /* Returns an expression to be executed if an unhandled exception is
90    propagated out of a cleanup region.  */
91
92 static tree
93 cp_protect_cleanup_actions (void)
94 {
95   /* [except.terminate]
96
97      When the destruction of an object during stack unwinding exits
98      using an exception ... void terminate(); is called.  */
99   return build_call (terminate_node, NULL_TREE);
100 }     
101
102 static tree
103 prepare_eh_type (tree type)
104 {
105   if (type == NULL_TREE)
106     return type;
107   if (type == error_mark_node)
108     return error_mark_node;
109
110   /* peel back references, so they match.  */
111   if (TREE_CODE (type) == REFERENCE_TYPE)
112     type = TREE_TYPE (type);
113
114   /* Peel off cv qualifiers.  */
115   type = TYPE_MAIN_VARIANT (type);
116
117   return type;
118 }
119
120 /* Build the address of a typeinfo decl for use in the runtime
121    matching field of the exception model.  */
122
123 static tree
124 build_eh_type_type (tree type)
125 {
126   tree exp;
127
128   if (type == NULL_TREE || type == error_mark_node)
129     return type;
130
131   if (decl_is_java_type (type, 0))
132     exp = build_java_class_ref (TREE_TYPE (type));
133   else
134     exp = get_tinfo_decl (type);
135
136   mark_used (exp);
137   exp = build1 (ADDR_EXPR, ptr_type_node, exp);
138
139   return exp;
140 }
141
142 tree
143 build_exc_ptr (void)
144 {
145   return build (EXC_PTR_EXPR, ptr_type_node);
146 }
147
148 /* Build up a call to __cxa_begin_catch, to tell the runtime that the
149    exception has been handled.  */
150
151 static tree
152 do_begin_catch (void)
153 {
154   tree fn;
155
156   fn = get_identifier ("__cxa_begin_catch");
157   if (IDENTIFIER_GLOBAL_VALUE (fn))
158     fn = IDENTIFIER_GLOBAL_VALUE (fn);
159   else
160     {
161       /* Declare void* __cxa_begin_catch (void *).  */
162       tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
163       fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
164     }
165
166   return build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
167                                              NULL_TREE));
168 }
169
170 /* Returns nonzero if cleaning up an exception of type TYPE (which can be
171    NULL_TREE for a ... handler) will not throw an exception.  */
172
173 static int
174 dtor_nothrow (tree type)
175 {
176   if (type == NULL_TREE)
177     return 0;
178
179   if (! TYPE_HAS_DESTRUCTOR (type))
180     return 1;
181
182   return TREE_NOTHROW (CLASSTYPE_DESTRUCTORS (type));
183 }
184
185 /* Build up a call to __cxa_end_catch, to destroy the exception object
186    for the current catch block if no others are currently using it.  */
187
188 static tree
189 do_end_catch (tree type)
190 {
191   tree fn, cleanup;
192
193   fn = get_identifier ("__cxa_end_catch");
194   if (IDENTIFIER_GLOBAL_VALUE (fn))
195     fn = IDENTIFIER_GLOBAL_VALUE (fn);
196   else
197     {
198       /* Declare void __cxa_end_catch ().  */
199       fn = push_void_library_fn (fn, void_list_node);
200       /* This can throw if the destructor for the exception throws.  */
201       TREE_NOTHROW (fn) = 0;
202     }
203
204   cleanup = build_function_call (fn, NULL_TREE);
205   TREE_NOTHROW (cleanup) = dtor_nothrow (type);
206
207   return cleanup;
208 }
209
210 /* This routine creates the cleanup for the current exception.  */
211
212 static void
213 push_eh_cleanup (tree type)
214 {
215   finish_decl_cleanup (NULL_TREE, do_end_catch (type));
216 }
217
218 /* Return nonzero value if DECL is a Java type suitable for catch or
219    throw.  */
220
221 static bool
222 decl_is_java_type (tree decl, int err)
223 {
224   bool r = (TREE_CODE (decl) == POINTER_TYPE
225             && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
226             && TYPE_FOR_JAVA (TREE_TYPE (decl)));
227
228   if (err)
229     {
230       if (TREE_CODE (decl) == REFERENCE_TYPE
231           && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
232           && TYPE_FOR_JAVA (TREE_TYPE (decl)))
233         {
234           /* Can't throw a reference.  */
235           error ("type `%T' is disallowed in Java `throw' or `catch'",
236                     decl);
237         }
238
239       if (r)
240         {
241           tree jthrow_node
242             = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jthrowable"));
243
244           if (jthrow_node == NULL_TREE)
245             fatal_error
246               ("call to Java `catch' or `throw' with `jthrowable' undefined");
247
248           jthrow_node = TREE_TYPE (TREE_TYPE (jthrow_node));
249
250           if (! DERIVED_FROM_P (jthrow_node, TREE_TYPE (decl)))
251             {
252               /* Thrown object must be a Throwable.  */
253               error ("type `%T' is not derived from `java::lang::Throwable'",
254                         TREE_TYPE (decl));
255             }
256         }
257     }
258
259   return r;
260 }
261
262 /* Select the personality routine to be used for exception handling,
263    or issue an error if we need two different ones in the same
264    translation unit.
265    ??? At present eh_personality_libfunc is set to
266    __gxx_personality_(sj|v)0 in init_exception_processing - should it
267    be done here instead?  */
268 void
269 choose_personality_routine (enum languages lang)
270 {
271   static enum {
272     chose_none,
273     chose_cpp,
274     chose_java,
275     gave_error
276   } state;
277
278   switch (state)
279     {
280     case gave_error:
281       return;
282
283     case chose_cpp:
284       if (lang != lang_cplusplus)
285         goto give_error;
286       return;
287
288     case chose_java:
289       if (lang != lang_java)
290         goto give_error;
291       return;
292
293     case chose_none:
294       ; /* proceed to language selection */
295     }
296
297   switch (lang)
298     {
299     case lang_cplusplus:
300       state = chose_cpp;
301       break;
302
303     case lang_java:
304       state = chose_java;
305       eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
306                                                  ? "__gcj_personality_sj0"
307                                                  : "__gcj_personality_v0");
308       break;
309
310     default:
311       abort ();
312     }
313   return;
314
315  give_error:
316   error ("mixing C++ and Java catches in a single translation unit");
317   state = gave_error;
318 }
319
320 /* Initialize the catch parameter DECL.  */
321
322 static void 
323 initialize_handler_parm (tree decl, tree exp)
324 {
325   tree init;
326   tree init_type;
327
328   /* Make sure we mark the catch param as used, otherwise we'll get a
329      warning about an unused ((anonymous)).  */
330   TREE_USED (decl) = 1;
331
332   /* Figure out the type that the initializer is.  Pointers are returned
333      adjusted by value from __cxa_begin_catch.  Others are returned by 
334      reference.  */
335   init_type = TREE_TYPE (decl);
336   if (! TYPE_PTR_P (init_type)
337       && TREE_CODE (init_type) != REFERENCE_TYPE)
338     init_type = build_reference_type (init_type);
339
340   choose_personality_routine (decl_is_java_type (init_type, 0)
341                               ? lang_java : lang_cplusplus);
342
343   /* Since pointers are passed by value, initialize a reference to
344      pointer catch parm with the address of the temporary.  */
345   if (TREE_CODE (init_type) == REFERENCE_TYPE
346       && TYPE_PTR_P (TREE_TYPE (init_type)))
347     exp = build_unary_op (ADDR_EXPR, exp, 1);
348
349   exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
350
351   init = convert_from_reference (exp);
352
353   /* If the constructor for the catch parm exits via an exception, we
354      must call terminate.  See eh23.C.  */
355   if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
356     {
357       /* Generate the copy constructor call directly so we can wrap it.
358          See also expand_default_init.  */
359       init = ocp_convert (TREE_TYPE (decl), init,
360                           CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
361       init = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (init), init);
362     }
363
364   /* Let `cp_finish_decl' know that this initializer is ok.  */
365   DECL_INITIAL (decl) = error_mark_node;
366   decl = pushdecl (decl);
367
368   start_decl_1 (decl);
369   cp_finish_decl (decl, init, NULL_TREE,
370                   LOOKUP_ONLYCONVERTING|DIRECT_BIND);
371 }
372
373 /* Call this to start a catch block.  DECL is the catch parameter.  */
374
375 tree
376 expand_start_catch_block (tree decl)
377 {
378   tree exp = NULL_TREE;
379   tree type;
380   bool is_java;
381
382   if (! doing_eh (1))
383     return NULL_TREE;
384
385   /* Make sure this declaration is reasonable.  */
386   if (decl && !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl), NULL_TREE))
387     decl = NULL_TREE;
388
389   if (decl)
390     type = prepare_eh_type (TREE_TYPE (decl));
391   else
392     type = NULL_TREE;
393
394   is_java = false;
395   if (decl)
396     {
397       tree init;
398
399       if (decl_is_java_type (type, 1))
400         {
401           /* Java only passes object via pointer and doesn't require
402              adjusting.  The java object is immediately before the
403              generic exception header.  */
404           init = build_exc_ptr ();
405           init = build1 (NOP_EXPR, build_pointer_type (type), init);
406           init = build (MINUS_EXPR, TREE_TYPE (init), init,
407                         TYPE_SIZE_UNIT (TREE_TYPE (init)));
408           init = build_indirect_ref (init, NULL);
409           is_java = true;
410         }
411       else
412         {
413           /* C++ requires that we call __cxa_begin_catch to get the
414              pointer to the actual object.  */
415           init = do_begin_catch ();
416         }
417           
418       exp = create_temporary_var (ptr_type_node);
419       DECL_REGISTER (exp) = 1;
420       cp_finish_decl (exp, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
421       finish_expr_stmt (build_modify_expr (exp, INIT_EXPR, init));
422     }
423   else
424     finish_expr_stmt (do_begin_catch ());
425
426   /* C++ requires that we call __cxa_end_catch at the end of
427      processing the exception.  */
428   if (! is_java)
429     push_eh_cleanup (type);
430
431   if (decl)
432     initialize_handler_parm (decl, exp);
433
434   return type;
435 }
436
437
438 /* Call this to end a catch block.  Its responsible for emitting the
439    code to handle jumping back to the correct place, and for emitting
440    the label to jump to if this catch block didn't match.  */
441
442 void
443 expand_end_catch_block (void)
444 {
445   if (! doing_eh (1))
446     return;
447
448   /* The exception being handled is rethrown if control reaches the end of
449      a handler of the function-try-block of a constructor or destructor.  */
450   if (in_function_try_handler
451       && (DECL_CONSTRUCTOR_P (current_function_decl)
452           || DECL_DESTRUCTOR_P (current_function_decl)))
453     finish_expr_stmt (build_throw (NULL_TREE));
454 }
455
456 tree
457 begin_eh_spec_block (void)
458 {
459   tree r = build_stmt (EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
460   add_stmt (r);
461   return r;
462 }
463
464 void
465 finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
466 {
467   tree raises;
468
469   RECHAIN_STMTS (eh_spec_block, EH_SPEC_STMTS (eh_spec_block));
470
471   /* Strip cv quals, etc, from the specification types.  */
472   for (raises = NULL_TREE;
473        raw_raises && TREE_VALUE (raw_raises);
474        raw_raises = TREE_CHAIN (raw_raises))
475     raises = tree_cons (NULL_TREE, prepare_eh_type (TREE_VALUE (raw_raises)),
476                         raises);
477
478   EH_SPEC_RAISES (eh_spec_block) = raises;
479 }
480
481 /* Return a pointer to a buffer for an exception object of type TYPE.  */
482
483 static tree
484 do_allocate_exception (tree type)
485 {
486   tree fn;
487
488   fn = get_identifier ("__cxa_allocate_exception");
489   if (IDENTIFIER_GLOBAL_VALUE (fn))
490     fn = IDENTIFIER_GLOBAL_VALUE (fn);
491   else
492     {
493       /* Declare void *__cxa_allocate_exception(size_t).  */
494       tree tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
495       fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
496     }
497   
498   return build_function_call (fn, tree_cons (NULL_TREE, size_in_bytes (type),
499                                              NULL_TREE));
500 }
501
502 #if 0
503 /* Call __cxa_free_exception from a cleanup.  This is never invoked
504    directly, but see the comment for stabilize_throw_expr.  */
505
506 static tree
507 do_free_exception (tree ptr)
508 {
509   tree fn;
510
511   fn = get_identifier ("__cxa_free_exception");
512   if (IDENTIFIER_GLOBAL_VALUE (fn))
513     fn = IDENTIFIER_GLOBAL_VALUE (fn);
514   else
515     {
516       /* Declare void __cxa_free_exception (void *).  */
517       fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
518                                                 void_list_node));
519     }
520
521   return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
522 }
523 #endif
524
525 /* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
526    Called from build_throw via walk_tree_without_duplicates.  */
527
528 static tree
529 wrap_cleanups_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
530                  void *data ATTRIBUTE_UNUSED)
531 {
532   tree exp = *tp;
533   tree cleanup;
534
535   /* Don't walk into types.  */
536   if (TYPE_P (exp))
537     {
538       *walk_subtrees = 0;
539       return NULL_TREE;
540     }
541   if (TREE_CODE (exp) != TARGET_EXPR)
542     return NULL_TREE;
543
544   cleanup = TARGET_EXPR_CLEANUP (exp);
545   if (cleanup)
546     {
547       cleanup = build1 (MUST_NOT_THROW_EXPR, void_type_node, cleanup);
548       TARGET_EXPR_CLEANUP (exp) = cleanup;
549     }
550
551   /* Keep iterating.  */
552   return NULL_TREE;
553 }
554
555 /* Like stabilize_expr, but specifically for a thrown expression.  When
556    throwing a temporary class object, we want to construct it directly into
557    the thrown exception, so we look past the TARGET_EXPR and stabilize the
558    arguments of the call instead.
559
560    The case where EXP is a call to a function returning a class is a bit of
561    a grey area in the standard; it's unclear whether or not it should be
562    allowed to throw.  I'm going to say no, as that allows us to optimize
563    this case without worrying about deallocating the exception object if it
564    does.  The alternatives would be either not optimizing this case, or
565    wrapping the initialization in a TRY_CATCH_EXPR to call do_free_exception
566    rather than in a MUST_NOT_THROW_EXPR, for this case only.  */
567
568 static tree
569 stabilize_throw_expr (tree exp, tree *initp)
570 {
571   tree init_expr;
572
573   if (TREE_CODE (exp) == TARGET_EXPR
574       && TREE_CODE (TARGET_EXPR_INITIAL (exp)) == AGGR_INIT_EXPR
575       && flag_elide_constructors)
576     {
577       tree aggr_init = AGGR_INIT_EXPR_CHECK (TARGET_EXPR_INITIAL (exp));
578       tree args = TREE_OPERAND (aggr_init, 1);
579       tree newargs = NULL_TREE;
580       tree *p = &newargs;
581
582       init_expr = void_zero_node;
583       for (; args; args = TREE_CHAIN (args))
584         {
585           tree arg = TREE_VALUE (args);
586           tree arg_init_expr;
587
588           arg = stabilize_expr (arg, &arg_init_expr);
589
590           if (TREE_SIDE_EFFECTS (arg_init_expr))
591             init_expr = build (COMPOUND_EXPR, void_type_node, init_expr,
592                                arg_init_expr);
593           *p = tree_cons (NULL_TREE, arg, NULL_TREE);
594           p = &TREE_CHAIN (*p);
595         }
596       TREE_OPERAND (aggr_init, 1) = newargs;
597     }
598   else
599     {
600       exp = stabilize_expr (exp, &init_expr);
601     }
602
603   *initp = init_expr;
604   return exp;
605 }
606
607 /* Build a throw expression.  */
608
609 tree
610 build_throw (tree exp)
611 {
612   tree fn;
613
614   if (exp == error_mark_node)
615     return exp;
616
617   if (processing_template_decl)
618     return build_min (THROW_EXPR, void_type_node, exp);
619
620   if (exp == null_node)
621     warning ("throwing NULL, which has integral, not pointer type");
622   
623   if (exp != NULL_TREE)
624     {
625       if (!is_admissible_throw_operand (exp))
626         return error_mark_node;
627     }
628
629   if (! doing_eh (1))
630     return error_mark_node;
631
632   if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
633     {
634       tree fn = get_identifier ("_Jv_Throw");
635       if (IDENTIFIER_GLOBAL_VALUE (fn))
636         fn = IDENTIFIER_GLOBAL_VALUE (fn);
637       else
638         {
639           /* Declare void _Jv_Throw (void *).  */
640           tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
641           tmp = build_function_type (ptr_type_node, tmp);
642           fn = push_throw_library_fn (fn, tmp);
643         }
644
645       exp = build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE));
646     }
647   else if (exp)
648     {
649       tree throw_type;
650       tree cleanup;
651       tree object, ptr;
652       tree tmp;
653       tree temp_expr, allocate_expr;
654
655       fn = get_identifier ("__cxa_throw");
656       if (IDENTIFIER_GLOBAL_VALUE (fn))
657         fn = IDENTIFIER_GLOBAL_VALUE (fn);
658       else
659         {
660           /* The CLEANUP_TYPE is the internal type of a destructor.  */
661           if (cleanup_type == NULL_TREE)
662             {
663               tmp = void_list_node;
664               tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
665               tmp = build_function_type (void_type_node, tmp);
666               cleanup_type = build_pointer_type (tmp);
667             }
668
669           /* Declare void __cxa_throw (void*, void*, void (*)(void*)).  */
670           /* ??? Second argument is supposed to be "std::type_info*".  */
671           tmp = void_list_node;
672           tmp = tree_cons (NULL_TREE, cleanup_type, tmp);
673           tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
674           tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
675           tmp = build_function_type (void_type_node, tmp);
676           fn = push_throw_library_fn (fn, tmp);
677         }
678
679       /* throw expression */
680       /* First, decay it.  */
681       exp = decay_conversion (exp);
682
683       /* OK, this is kind of wacky.  The standard says that we call
684          terminate when the exception handling mechanism, after
685          completing evaluation of the expression to be thrown but
686          before the exception is caught (_except.throw_), calls a
687          user function that exits via an uncaught exception.
688
689          So we have to protect the actual initialization of the
690          exception object with terminate(), but evaluate the
691          expression first.  Since there could be temps in the
692          expression, we need to handle that, too.  We also expand
693          the call to __cxa_allocate_exception first (which doesn't
694          matter, since it can't throw).  */
695
696       /* Pre-evaluate the thrown expression first, since if we allocated
697          the space first we would have to deal with cleaning it up if
698          evaluating this expression throws.  */
699       exp = stabilize_throw_expr (exp, &temp_expr);
700
701       /* Allocate the space for the exception.  */
702       allocate_expr = do_allocate_exception (TREE_TYPE (exp));
703       allocate_expr = get_target_expr (allocate_expr);
704       ptr = TARGET_EXPR_SLOT (allocate_expr);
705       object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
706       object = build_indirect_ref (object, NULL);
707
708       /* And initialize the exception object.  */
709       exp = build_init (object, exp, LOOKUP_ONLYCONVERTING);
710       if (exp == error_mark_node)
711         {
712           error ("  in thrown expression");
713           return error_mark_node;
714         }
715
716       exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
717       /* Prepend the allocation.  */
718       exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
719       if (temp_expr != void_zero_node)
720         {
721           /* Prepend the calculation of the throw expression.  Also, force
722              any cleanups from the expression to be evaluated here so that
723              we don't have to do them during unwinding.  But first wrap
724              them in MUST_NOT_THROW_EXPR, since they are run after the
725              exception object is initialized.  */
726           walk_tree_without_duplicates (&temp_expr, wrap_cleanups_r, 0);
727           exp = build (COMPOUND_EXPR, TREE_TYPE (exp), temp_expr, exp);
728           exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
729         }
730
731       throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
732
733       if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (object)))
734         {
735           cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
736                                      complete_dtor_identifier, 0);
737           cleanup = BASELINK_FUNCTIONS (cleanup);
738           mark_used (cleanup);
739           cxx_mark_addressable (cleanup);
740           /* Pretend it's a normal function.  */
741           cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);
742         }
743       else
744         {
745           cleanup = build_int_2 (0, 0);
746           TREE_TYPE (cleanup) = cleanup_type;
747         }
748
749       tmp = tree_cons (NULL_TREE, cleanup, NULL_TREE);
750       tmp = tree_cons (NULL_TREE, throw_type, tmp);
751       tmp = tree_cons (NULL_TREE, ptr, tmp);
752       /* ??? Indicate that this function call throws throw_type.  */
753       tmp = build_function_call (fn, tmp);
754
755       /* Tack on the initialization stuff.  */
756       exp = build (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp);
757     }
758   else
759     {
760       /* Rethrow current exception.  */
761
762       tree fn = get_identifier ("__cxa_rethrow");
763       if (IDENTIFIER_GLOBAL_VALUE (fn))
764         fn = IDENTIFIER_GLOBAL_VALUE (fn);
765       else
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   if (TREE_CODE (to) == REFERENCE_TYPE)
877     to = TREE_TYPE (to);
878   if (TREE_CODE (from) == REFERENCE_TYPE)
879     from = TREE_TYPE (from);
880
881   if (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
882     {
883       to = TREE_TYPE (to);
884       from = TREE_TYPE (from);
885
886       if (! at_least_as_qualified_p (to, from))
887         return 0;
888
889       if (TREE_CODE (to) == VOID_TYPE)
890         return 1;
891
892       /* else fall through */
893     }
894
895   if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
896       && PUBLICLY_UNIQUELY_DERIVED_P (to, from))
897     return 1;
898
899   return 0;
900 }
901
902 /* Check whether any of HANDLERS are shadowed by another handler accepting
903    TYPE.  Note that the shadowing may not be complete; even if an exception
904    of type B would be caught by a handler for A, there could be a derived
905    class C for which A is an ambiguous base but B is not, so the handler
906    for B would catch an exception of type C.  */
907
908 static void
909 check_handlers_1 (tree master, tree handlers)
910 {
911   tree type = TREE_TYPE (master);
912   tree handler;
913
914   for (handler = handlers; handler; handler = TREE_CHAIN (handler))
915     if (TREE_TYPE (handler)
916         && can_convert_eh (type, TREE_TYPE (handler)))
917       {
918         input_line = STMT_LINENO (handler);
919         warning ("exception of type `%T' will be caught",
920                     TREE_TYPE (handler));
921         input_line = STMT_LINENO (master);
922         warning ("   by earlier handler for `%T'", type);
923         break;
924       }
925 }
926
927 /* Given a chain of HANDLERs, make sure that they're OK.  */
928
929 void
930 check_handlers (tree handlers)
931 {
932   tree handler;
933   int save_line = input_line;
934   
935   for (handler = handlers; handler; handler = TREE_CHAIN (handler))
936     {
937       if (TREE_CHAIN (handler) == NULL_TREE)
938         /* No more handlers; nothing to shadow.  */;
939       else if (TREE_TYPE (handler) == NULL_TREE)
940         {
941           input_line = STMT_LINENO (handler);
942           pedwarn
943             ("`...' handler must be the last handler for its try block");
944         }
945       else
946         check_handlers_1 (handler, TREE_CHAIN (handler));
947     }
948   input_line = save_line;
949 }