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