OSDN Git Service

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