]> gcc.gnu.org Git - gcc.git/blob - gcc/cp/except.c
Daily bump.
[gcc.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 }
This page took 0.080244 seconds and 6 git commands to generate.