OSDN Git Service

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