OSDN Git Service

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