OSDN Git Service

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