OSDN Git Service

Merge from pch-branch up to tag pch-commit-20020603.
[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 "obstack.h"
35 #include "output.h"
36 #include "except.h"
37 #include "toplev.h"
38 #include "tree-inline.h"
39
40 static void push_eh_cleanup PARAMS ((tree));
41 static tree prepare_eh_type PARAMS ((tree));
42 static tree build_eh_type_type PARAMS ((tree));
43 static tree do_begin_catch PARAMS ((void));
44 static int dtor_nothrow PARAMS ((tree));
45 static tree do_end_catch PARAMS ((tree));
46 static void push_eh_cleanup PARAMS ((tree));
47 static bool decl_is_java_type PARAMS ((tree decl, int err));
48 static void initialize_handler_parm PARAMS ((tree, tree));
49 static tree do_allocate_exception PARAMS ((tree));
50 static tree stabilize_throw_expr PARAMS ((tree, tree *));
51 static tree wrap_cleanups_r PARAMS ((tree *, int *, void *));
52 static int complete_ptr_ref_or_void_ptr_p PARAMS ((tree, tree));
53 static bool is_admissible_throw_operand PARAMS ((tree));
54 static int can_convert_eh PARAMS ((tree, tree));
55 static void check_handlers_1 PARAMS ((tree, tree));
56 static tree cp_protect_cleanup_actions PARAMS ((void));
57
58 /* Sets up all the global eh stuff that needs to be initialized at the
59    start of compilation.  */
60
61 void
62 init_exception_processing ()
63 {
64   tree tmp;
65
66   /* void std::terminate (); */
67   push_namespace (std_identifier);
68   tmp = build_function_type (void_type_node, void_list_node);
69   terminate_node = build_cp_library_fn_ptr ("terminate", tmp);
70   TREE_THIS_VOLATILE (terminate_node) = 1;
71   TREE_NOTHROW (terminate_node) = 1;
72   pop_namespace ();
73
74   /* void __cxa_call_unexpected(void *); */
75   tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
76   tmp = build_function_type (void_type_node, tmp);
77   call_unexpected_node
78     = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
79
80   eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
81                                              ? "__gxx_personality_sj0"
82                                              : "__gxx_personality_v0");
83
84   lang_eh_runtime_type = build_eh_type_type;
85   lang_protect_cleanup_actions = &cp_protect_cleanup_actions;
86 }
87
88 /* Returns an expression to be executed if an unhandled exception is
89    propagated out of a cleanup region.  */
90
91 static tree
92 cp_protect_cleanup_actions ()
93 {
94   /* [except.terminate]
95
96      When the destruction of an object during stack unwinding exits
97      using an exception ... void terminate(); is called.  */
98   return build_call (terminate_node, NULL_TREE);
99 }     
100
101 static tree
102 prepare_eh_type (type)
103      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 (type)
125      tree type;
126 {
127   tree exp;
128
129   if (type == NULL_TREE || type == error_mark_node)
130     return type;
131
132   if (decl_is_java_type (type, 0))
133     exp = build_java_class_ref (TREE_TYPE (type));
134   else
135     exp = get_tinfo_decl (type);
136
137   mark_used (exp);
138   exp = build1 (ADDR_EXPR, ptr_type_node, exp);
139
140   return exp;
141 }
142
143 tree
144 build_exc_ptr ()
145 {
146   return build (EXC_PTR_EXPR, ptr_type_node);
147 }
148
149 /* Build up a call to __cxa_begin_catch, to tell the runtime that the
150    exception has been handled.  */
151
152 static tree
153 do_begin_catch ()
154 {
155   tree fn;
156
157   fn = get_identifier ("__cxa_begin_catch");
158   if (IDENTIFIER_GLOBAL_VALUE (fn))
159     fn = IDENTIFIER_GLOBAL_VALUE (fn);
160   else
161     {
162       /* Declare void* __cxa_begin_catch (void *).  */
163       tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
164       fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
165     }
166
167   return build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
168                                              NULL_TREE));
169 }
170
171 /* Returns nonzero if cleaning up an exception of type TYPE (which can be
172    NULL_TREE for a ... handler) will not throw an exception.  */
173
174 static int
175 dtor_nothrow (type)
176      tree type;
177 {
178   tree fn;
179
180   if (type == NULL_TREE)
181     return 0;
182
183   if (! TYPE_HAS_DESTRUCTOR (type))
184     return 1;
185
186   fn = lookup_member (type, dtor_identifier, 0, 0);
187   fn = TREE_VALUE (fn);
188   return TREE_NOTHROW (fn);
189 }
190
191 /* Build up a call to __cxa_end_catch, to destroy the exception object
192    for the current catch block if no others are currently using it.  */
193
194 static tree
195 do_end_catch (type)
196      tree type;
197 {
198   tree fn, cleanup;
199
200   fn = get_identifier ("__cxa_end_catch");
201   if (IDENTIFIER_GLOBAL_VALUE (fn))
202     fn = IDENTIFIER_GLOBAL_VALUE (fn);
203   else
204     {
205       /* Declare void __cxa_end_catch ().  */
206       fn = push_void_library_fn (fn, void_list_node);
207       /* This can throw if the destructor for the exception throws.  */
208       TREE_NOTHROW (fn) = 0;
209     }
210
211   cleanup = build_function_call (fn, NULL_TREE);
212   TREE_NOTHROW (cleanup) = dtor_nothrow (type);
213
214   return cleanup;
215 }
216
217 /* This routine creates the cleanup for the current exception.  */
218
219 static void
220 push_eh_cleanup (type)
221      tree type;
222 {
223   finish_decl_cleanup (NULL_TREE, do_end_catch (type));
224 }
225
226 /* Return nonzero value if DECL is a Java type suitable for catch or
227    throw.  */
228
229 static bool
230 decl_is_java_type (decl, err)
231      tree decl;
232      int err;
233 {
234   bool r = (TREE_CODE (decl) == POINTER_TYPE
235             && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
236             && TYPE_FOR_JAVA (TREE_TYPE (decl)));
237
238   if (err)
239     {
240       if (TREE_CODE (decl) == REFERENCE_TYPE
241           && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
242           && TYPE_FOR_JAVA (TREE_TYPE (decl)))
243         {
244           /* Can't throw a reference.  */
245           error ("type `%T' is disallowed in Java `throw' or `catch'",
246                     decl);
247         }
248
249       if (r)
250         {
251           tree jthrow_node
252             = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jthrowable"));
253
254           if (jthrow_node == NULL_TREE)
255             fatal_error
256               ("call to Java `catch' or `throw' with `jthrowable' undefined");
257
258           jthrow_node = TREE_TYPE (TREE_TYPE (jthrow_node));
259
260           if (! DERIVED_FROM_P (jthrow_node, TREE_TYPE (decl)))
261             {
262               /* Thrown object must be a Throwable.  */
263               error ("type `%T' is not derived from `java::lang::Throwable'",
264                         TREE_TYPE (decl));
265             }
266         }
267     }
268
269   return r;
270 }
271
272 /* Select the personality routine to be used for exception handling,
273    or issue an error if we need two different ones in the same
274    translation unit.
275    ??? At present eh_personality_libfunc is set to
276    __gxx_personality_(sj|v)0 in init_exception_processing - should it
277    be done here instead?  */
278 void
279 choose_personality_routine (lang)
280      enum languages lang;
281 {
282   static enum {
283     chose_none,
284     chose_cpp,
285     chose_java,
286     gave_error
287   } state;
288
289   switch (state)
290     {
291     case gave_error:
292       return;
293
294     case chose_cpp:
295       if (lang != lang_cplusplus)
296         goto give_error;
297       return;
298
299     case chose_java:
300       if (lang != lang_java)
301         goto give_error;
302       return;
303
304     case chose_none:
305       ; /* proceed to language selection */
306     }
307
308   switch (lang)
309     {
310     case lang_cplusplus:
311       state = chose_cpp;
312       break;
313
314     case lang_java:
315       state = chose_java;
316       eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
317                                                  ? "__gcj_personality_sj0"
318                                                  : "__gcj_personality_v0");
319       break;
320
321     default:
322       abort ();
323     }
324   return;
325
326  give_error:
327   error ("mixing C++ and Java catches in a single translation unit");
328   state = gave_error;
329 }
330
331 /* Initialize the catch parameter DECL.  */
332
333 static void 
334 initialize_handler_parm (decl, exp)
335      tree decl;
336      tree exp;
337 {
338   tree init;
339   tree init_type;
340
341   /* Make sure we mark the catch param as used, otherwise we'll get a
342      warning about an unused ((anonymous)).  */
343   TREE_USED (decl) = 1;
344
345   /* Figure out the type that the initializer is.  Pointers are returned
346      adjusted by value from __cxa_begin_catch.  Others are returned by 
347      reference.  */
348   init_type = TREE_TYPE (decl);
349   if (! TYPE_PTR_P (init_type)
350       && TREE_CODE (init_type) != REFERENCE_TYPE)
351     init_type = build_reference_type (init_type);
352
353   choose_personality_routine (decl_is_java_type (init_type, 0)
354                               ? lang_java : lang_cplusplus);
355
356   /* Since pointers are passed by value, initialize a reference to
357      pointer catch parm with the address of the temporary.  */
358   if (TREE_CODE (init_type) == REFERENCE_TYPE
359       && TYPE_PTR_P (TREE_TYPE (init_type)))
360     exp = build_unary_op (ADDR_EXPR, exp, 1);
361
362   exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
363
364   init = convert_from_reference (exp);
365
366   /* If the constructor for the catch parm exits via an exception, we
367      must call terminate.  See eh23.C.  */
368   if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
369     {
370       /* Generate the copy constructor call directly so we can wrap it.
371          See also expand_default_init.  */
372       init = ocp_convert (TREE_TYPE (decl), init,
373                           CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
374       init = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (init), init);
375     }
376
377   /* Let `cp_finish_decl' know that this initializer is ok.  */
378   DECL_INITIAL (decl) = error_mark_node;
379   decl = pushdecl (decl);
380
381   start_decl_1 (decl);
382   cp_finish_decl (decl, init, NULL_TREE,
383                   LOOKUP_ONLYCONVERTING|DIRECT_BIND);
384 }
385
386 /* Call this to start a catch block.  DECL is the catch parameter.  */
387
388 tree
389 expand_start_catch_block (decl)
390      tree decl;
391 {
392   tree exp = NULL_TREE;
393   tree type;
394   bool is_java;
395
396   if (! doing_eh (1))
397     return NULL_TREE;
398
399   /* Make sure this declaration is reasonable.  */
400   if (decl && !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl), NULL_TREE))
401     decl = NULL_TREE;
402
403   if (decl)
404     type = prepare_eh_type (TREE_TYPE (decl));
405   else
406     type = NULL_TREE;
407
408   is_java = false;
409   if (decl)
410     {
411       tree init;
412
413       if (decl_is_java_type (type, 1))
414         {
415           /* Java only passes object via pointer and doesn't require
416              adjusting.  The java object is immediately before the
417              generic exception header.  */
418           init = build_exc_ptr ();
419           init = build1 (NOP_EXPR, build_pointer_type (type), init);
420           init = build (MINUS_EXPR, TREE_TYPE (init), init,
421                         TYPE_SIZE_UNIT (TREE_TYPE (init)));
422           init = build_indirect_ref (init, NULL);
423           is_java = true;
424         }
425       else
426         {
427           /* C++ requires that we call __cxa_begin_catch to get the
428              pointer to the actual object.  */
429           init = do_begin_catch ();
430         }
431           
432       exp = create_temporary_var (ptr_type_node);
433       DECL_REGISTER (exp) = 1;
434       cp_finish_decl (exp, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
435       finish_expr_stmt (build_modify_expr (exp, INIT_EXPR, init));
436     }
437   else
438     finish_expr_stmt (do_begin_catch ());
439
440   /* C++ requires that we call __cxa_end_catch at the end of
441      processing the exception.  */
442   if (! is_java)
443     push_eh_cleanup (type);
444
445   if (decl)
446     initialize_handler_parm (decl, exp);
447
448   return type;
449 }
450
451
452 /* Call this to end a catch block.  Its responsible for emitting the
453    code to handle jumping back to the correct place, and for emitting
454    the label to jump to if this catch block didn't match.  */
455
456 void
457 expand_end_catch_block ()
458 {
459   if (! doing_eh (1))
460     return;
461
462   /* The exception being handled is rethrown if control reaches the end of
463      a handler of the function-try-block of a constructor or destructor.  */
464   if (in_function_try_handler
465       && (DECL_CONSTRUCTOR_P (current_function_decl)
466           || DECL_DESTRUCTOR_P (current_function_decl)))
467     finish_expr_stmt (build_throw (NULL_TREE));
468 }
469
470 tree
471 begin_eh_spec_block ()
472 {
473   tree r = build_stmt (EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
474   add_stmt (r);
475   return r;
476 }
477
478 void
479 finish_eh_spec_block (raw_raises, eh_spec_block)
480      tree raw_raises;
481      tree eh_spec_block;
482 {
483   tree raises;
484
485   RECHAIN_STMTS (eh_spec_block, EH_SPEC_STMTS (eh_spec_block));
486
487   /* Strip cv quals, etc, from the specification types.  */
488   for (raises = NULL_TREE;
489        raw_raises && TREE_VALUE (raw_raises);
490        raw_raises = TREE_CHAIN (raw_raises))
491     raises = tree_cons (NULL_TREE, prepare_eh_type (TREE_VALUE (raw_raises)),
492                         raises);
493
494   EH_SPEC_RAISES (eh_spec_block) = raises;
495 }
496
497 /* Return a pointer to a buffer for an exception object of type TYPE.  */
498
499 static tree
500 do_allocate_exception (type)
501      tree type;
502 {
503   tree fn;
504
505   fn = get_identifier ("__cxa_allocate_exception");
506   if (IDENTIFIER_GLOBAL_VALUE (fn))
507     fn = IDENTIFIER_GLOBAL_VALUE (fn);
508   else
509     {
510       /* Declare void *__cxa_allocate_exception(size_t).  */
511       tree tmp = tree_cons (NULL_TREE, c_size_type_node, void_list_node);
512       fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
513     }
514   
515   return build_function_call (fn, tree_cons (NULL_TREE, size_in_bytes (type),
516                                              NULL_TREE));
517 }
518
519 #if 0
520 /* Call __cxa_free_exception from a cleanup.  This is never invoked
521    directly, but see the comment for stabilize_throw_expr.  */
522
523 static tree
524 do_free_exception (ptr)
525      tree ptr;
526 {
527   tree fn;
528
529   fn = get_identifier ("__cxa_free_exception");
530   if (IDENTIFIER_GLOBAL_VALUE (fn))
531     fn = IDENTIFIER_GLOBAL_VALUE (fn);
532   else
533     {
534       /* Declare void __cxa_free_exception (void *).  */
535       fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
536                                                 void_list_node));
537     }
538
539   return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
540 }
541 #endif
542
543 /* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
544    Called from build_throw via walk_tree_without_duplicates.  */
545
546 static tree
547 wrap_cleanups_r (tp, walk_subtrees, data)
548      tree *tp;
549      int *walk_subtrees ATTRIBUTE_UNUSED;
550      void *data ATTRIBUTE_UNUSED;
551 {
552   tree exp = *tp;
553   tree cleanup;
554
555   /* Don't walk into types.  */
556   if (TYPE_P (exp))
557     {
558       *walk_subtrees = 0;
559       return NULL_TREE;
560     }
561   if (TREE_CODE (exp) != TARGET_EXPR)
562     return NULL_TREE;
563
564   cleanup = TARGET_EXPR_CLEANUP (exp);
565   if (cleanup)
566     {
567       cleanup = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (cleanup), cleanup);
568       TARGET_EXPR_CLEANUP (exp) = cleanup;
569     }
570
571   /* Keep iterating.  */
572   return NULL_TREE;
573 }
574
575 /* Like stabilize_expr, but specifically for a thrown expression.  When
576    throwing a temporary class object, we want to construct it directly into
577    the thrown exception, so we look past the TARGET_EXPR and stabilize the
578    arguments of the call instead.
579
580    The case where EXP is a call to a function returning a class is a bit of
581    a grey area in the standard; it's unclear whether or not it should be
582    allowed to throw.  I'm going to say no, as that allows us to optimize
583    this case without worrying about deallocating the exception object if it
584    does.  The alternatives would be either not optimizing this case, or
585    wrapping the initialization in a TRY_CATCH_EXPR to call do_free_exception
586    rather than in a MUST_NOT_THROW_EXPR, for this case only.  */
587
588 static tree
589 stabilize_throw_expr (exp, initp)
590      tree exp;
591      tree *initp;
592 {
593   tree init_expr;
594
595   if (TREE_CODE (exp) == TARGET_EXPR
596       && TREE_CODE (TARGET_EXPR_INITIAL (exp)) == AGGR_INIT_EXPR
597       && flag_elide_constructors)
598     {
599       tree aggr_init = AGGR_INIT_EXPR_CHECK (TARGET_EXPR_INITIAL (exp));
600       tree args = TREE_OPERAND (aggr_init, 1);
601       tree newargs = NULL_TREE;
602       tree *p = &newargs;
603
604       init_expr = void_zero_node;
605       for (; args; args = TREE_CHAIN (args))
606         {
607           tree arg_init_expr;
608           tree newarg = stabilize_expr (TREE_VALUE (args), &arg_init_expr);
609
610           if (arg_init_expr != void_zero_node)
611             init_expr = build (COMPOUND_EXPR, void_type_node, arg_init_expr, init_expr);
612           *p = tree_cons (NULL_TREE, newarg, 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 = TREE_VALUE (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 non-zero 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 }