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