1/* Handle exceptional things in C++. 2 Copyright (C) 1989-2022 Free Software Foundation, Inc. 3 Contributed by Michael Tiemann <tiemann@cygnus.com> 4 Rewritten by Mike Stump <mrs@cygnus.com>, based upon an 5 initial re-implementation courtesy Tad Hunt. 6 7This file is part of GCC. 8 9GCC is free software; you can redistribute it and/or modify 10it under the terms of the GNU General Public License as published by 11the Free Software Foundation; either version 3, or (at your option) 12any later version. 13 14GCC is distributed in the hope that it will be useful, 15but WITHOUT ANY WARRANTY; without even the implied warranty of 16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17GNU General Public License for more details. 18 19You should have received a copy of the GNU General Public License 20along with GCC; see the file COPYING3. If not see 21<http://www.gnu.org/licenses/>. */ 22 23 24#include "config.h" 25#include "system.h" 26#include "coretypes.h" 27#include "cp-tree.h" 28#include "stringpool.h" 29#include "trans-mem.h" 30#include "attribs.h" 31#include "tree-iterator.h" 32#include "target.h" 33 34static void push_eh_cleanup (tree); 35static tree prepare_eh_type (tree); 36static tree do_begin_catch (void); 37static int dtor_nothrow (tree); 38static tree do_end_catch (tree); 39static void initialize_handler_parm (tree, tree); 40static tree do_allocate_exception (tree); 41static tree wrap_cleanups_r (tree *, int *, void *); 42static int complete_ptr_ref_or_void_ptr_p (tree, tree); 43static bool is_admissible_throw_operand_or_catch_parameter (tree, bool); 44 45/* Sets up all the global eh stuff that needs to be initialized at the 46 start of compilation. */ 47 48void 49init_exception_processing (void) 50{ 51 tree tmp; 52 53 /* void std::terminate (); */ 54 push_nested_namespace (std_node); 55 tmp = build_function_type_list (void_type_node, NULL_TREE); 56 terminate_fn = build_cp_library_fn_ptr ("terminate", tmp, 57 ECF_NOTHROW | ECF_NORETURN 58 | ECF_COLD); 59 gcc_checking_assert (TREE_THIS_VOLATILE (terminate_fn) 60 && TREE_NOTHROW (terminate_fn)); 61 pop_nested_namespace (std_node); 62 63 /* void __cxa_call_unexpected(void *); */ 64 tmp = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE); 65 call_unexpected_fn 66 = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp); 67} 68 69/* Returns an expression to be executed if an unhandled exception is 70 propagated out of a cleanup region. */ 71 72tree 73cp_protect_cleanup_actions (void) 74{ 75 /* [except.terminate] 76 77 When the destruction of an object during stack unwinding exits 78 using an exception ... void terminate(); is called. */ 79 return terminate_fn; 80} 81 82static tree 83prepare_eh_type (tree type) 84{ 85 if (type == NULL_TREE) 86 return type; 87 if (type == error_mark_node) 88 return error_mark_node; 89 90 /* peel back references, so they match. */ 91 type = non_reference (type); 92 93 /* Peel off cv qualifiers. */ 94 type = TYPE_MAIN_VARIANT (type); 95 96 /* Functions and arrays decay to pointers. */ 97 type = type_decays_to (type); 98 99 return type; 100} 101 102/* Return the type info for TYPE as used by EH machinery. */ 103tree 104eh_type_info (tree type) 105{ 106 if (type == NULL_TREE || type == error_mark_node) 107 return type; 108 109 return get_tinfo_decl (type); 110} 111 112/* Build the address of a typeinfo decl for use in the runtime 113 matching field of the exception model. */ 114 115tree 116build_eh_type_type (tree type) 117{ 118 tree exp = eh_type_info (type); 119 120 if (!exp) 121 return NULL; 122 123 mark_used (exp); 124 125 return convert (ptr_type_node, build_address (exp)); 126} 127 128tree 129build_exc_ptr (void) 130{ 131 return build_call_n (builtin_decl_explicit (BUILT_IN_EH_POINTER), 132 1, integer_zero_node); 133} 134 135/* Declare an exception ABI entry point called NAME. 136 ECF are the library flags, RTYPE the return type and ARGS[NARGS] 137 the parameter types. We return the DECL -- which might be one 138 found via the symbol table pushing, if the user already declared 139 it. If we pushed a new decl, the user will see it. */ 140 141static tree 142declare_library_fn_1 (const char *name, int ecf, 143 tree rtype, int nargs, tree args[]) 144{ 145 tree ident = get_identifier (name); 146 tree except = ecf & ECF_NOTHROW ? empty_except_spec : NULL_TREE; 147 148 /* Make a new decl. */ 149 tree arg_list = void_list_node; 150 for (unsigned ix = nargs; ix--;) 151 arg_list = tree_cons (NULL_TREE, args[ix], arg_list); 152 tree fntype = build_function_type (rtype, arg_list); 153 tree res = push_library_fn (ident, fntype, except, ecf); 154 155 return res; 156} 157 158/* Find or declare a function NAME, returning RTYPE, taking a single 159 parameter PTYPE, with an empty exception specification. ECF are the 160 library fn flags. If TM_ECF is non-zero, also find or create a 161 transaction variant and record it as a replacement, when flag_tm is 162 in effect. 163 164 Note that the C++ ABI document does not have a throw-specifier on 165 the routines declared below via this function. The declarations 166 are consistent with the actual implementations in libsupc++. */ 167 168static tree 169declare_library_fn (const char *name, tree rtype, tree ptype, 170 int ecf, int tm_ecf) 171{ 172 tree res = declare_library_fn_1 (name, ecf, rtype, ptype ? 1 : 0, &ptype); 173 if (res == error_mark_node) 174 return res; 175 176 if (tm_ecf && flag_tm) 177 { 178 char *tm_name = concat ("_ITM_", name + 2, NULL_TREE); 179 180 tree tm_fn = declare_library_fn_1 (tm_name, ecf | tm_ecf, rtype, 181 ptype ? 1 : 0, &ptype); 182 free (tm_name); 183 if (tm_fn != error_mark_node) 184 record_tm_replacement (res, tm_fn); 185 } 186 187 return res; 188} 189 190/* Build up a call to __cxa_get_exception_ptr so that we can build a 191 copy constructor for the thrown object. */ 192 193static tree 194do_get_exception_ptr (void) 195{ 196 if (!get_exception_ptr_fn) 197 /* Declare void* __cxa_get_exception_ptr (void *) throw(). */ 198 get_exception_ptr_fn 199 = declare_library_fn ("__cxa_get_exception_ptr", 200 ptr_type_node, ptr_type_node, 201 ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE, 202 0); 203 204 return cp_build_function_call_nary (get_exception_ptr_fn, 205 tf_warning_or_error, 206 build_exc_ptr (), NULL_TREE); 207} 208 209/* Build up a call to __cxa_begin_catch, to tell the runtime that the 210 exception has been handled. */ 211 212static tree 213do_begin_catch (void) 214{ 215 if (!begin_catch_fn) 216 /* Declare void* __cxa_begin_catch (void *) throw(). */ 217 begin_catch_fn 218 = declare_library_fn ("__cxa_begin_catch", 219 ptr_type_node, ptr_type_node, ECF_NOTHROW, 220 ECF_TM_PURE); 221 222 return cp_build_function_call_nary (begin_catch_fn, tf_warning_or_error, 223 build_exc_ptr (), NULL_TREE); 224} 225 226/* Returns nonzero if cleaning up an exception of type TYPE (which can be 227 NULL_TREE for a ... handler) will not throw an exception. */ 228 229static int 230dtor_nothrow (tree type) 231{ 232 if (type == NULL_TREE || type == error_mark_node) 233 return 0; 234 235 if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type)) 236 return 1; 237 238 if (CLASSTYPE_LAZY_DESTRUCTOR (type)) 239 lazily_declare_fn (sfk_destructor, type); 240 241 return TREE_NOTHROW (CLASSTYPE_DESTRUCTOR (type)); 242} 243 244/* Build up a call to __cxa_end_catch, to destroy the exception object 245 for the current catch block if no others are currently using it. */ 246 247static tree 248do_end_catch (tree type) 249{ 250 if (!end_catch_fn) 251 /* Declare void __cxa_end_catch (). 252 This can throw if the destructor for the exception throws. */ 253 end_catch_fn 254 = declare_library_fn ("__cxa_end_catch", void_type_node, 255 NULL_TREE, 0, ECF_TM_PURE); 256 257 tree cleanup = cp_build_function_call_vec (end_catch_fn, 258 NULL, tf_warning_or_error); 259 if (cleanup != error_mark_node) 260 TREE_NOTHROW (cleanup) = dtor_nothrow (type); 261 262 return cleanup; 263} 264 265/* This routine creates the cleanup for the current exception. */ 266 267static void 268push_eh_cleanup (tree type) 269{ 270 finish_decl_cleanup (NULL_TREE, do_end_catch (type)); 271} 272 273/* Wrap EXPR in a MUST_NOT_THROW_EXPR expressing that EXPR must 274 not throw any exceptions if COND is true. A condition of 275 NULL_TREE is treated as 'true'. */ 276 277tree 278build_must_not_throw_expr (tree body, tree cond) 279{ 280 tree type = body ? TREE_TYPE (body) : void_type_node; 281 282 if (!flag_exceptions) 283 return body; 284 285 if (!cond) 286 /* OK, unconditional. */; 287 else 288 { 289 tree conv = NULL_TREE; 290 if (!type_dependent_expression_p (cond)) 291 conv = perform_implicit_conversion_flags (boolean_type_node, cond, 292 tf_warning_or_error, 293 LOOKUP_NORMAL); 294 if (tree inst = instantiate_non_dependent_or_null (conv)) 295 cond = cxx_constant_value (inst); 296 else 297 require_constant_expression (cond); 298 if (integer_zerop (cond)) 299 return body; 300 else if (integer_onep (cond)) 301 cond = NULL_TREE; 302 } 303 304 return build2 (MUST_NOT_THROW_EXPR, type, body, cond); 305} 306 307 308/* Initialize the catch parameter DECL. */ 309 310static void 311initialize_handler_parm (tree decl, tree exp) 312{ 313 tree init; 314 tree init_type; 315 316 /* Make sure we mark the catch param as used, otherwise we'll get a 317 warning about an unused ((anonymous)). */ 318 TREE_USED (decl) = 1; 319 DECL_READ_P (decl) = 1; 320 321 /* Figure out the type that the initializer is. Pointers are returned 322 adjusted by value from __cxa_begin_catch. Others are returned by 323 reference. */ 324 init_type = TREE_TYPE (decl); 325 if (!INDIRECT_TYPE_P (init_type)) 326 init_type = build_reference_type (init_type); 327 328 /* Since pointers are passed by value, initialize a reference to 329 pointer catch parm with the address of the temporary. */ 330 if (TYPE_REF_P (init_type) 331 && TYPE_PTR_P (TREE_TYPE (init_type))) 332 exp = cp_build_addr_expr (exp, tf_warning_or_error); 333 334 exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0, 335 tf_warning_or_error); 336 337 init = convert_from_reference (exp); 338 339 /* If the constructor for the catch parm exits via an exception, we 340 must call terminate. See eh23.C. */ 341 if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) 342 { 343 /* Generate the copy constructor call directly so we can wrap it. 344 See also expand_default_init. */ 345 init = ocp_convert (TREE_TYPE (decl), init, 346 CONV_IMPLICIT|CONV_FORCE_TEMP, 0, 347 tf_warning_or_error); 348 /* Force cleanups now to avoid nesting problems with the 349 MUST_NOT_THROW_EXPR. */ 350 init = fold_build_cleanup_point_expr (TREE_TYPE (init), init); 351 init = build_must_not_throw_expr (init, NULL_TREE); 352 } 353 354 decl = pushdecl (decl); 355 356 start_decl_1 (decl, true); 357 cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE, 358 LOOKUP_ONLYCONVERTING|DIRECT_BIND); 359} 360 361 362/* Routine to see if exception handling is turned on. 363 DO_WARN is nonzero if we want to inform the user that exception 364 handling is turned off. 365 366 This is used to ensure that -fexceptions has been specified if the 367 compiler tries to use any exception-specific functions. */ 368 369static inline int 370doing_eh (void) 371{ 372 if (! flag_exceptions) 373 { 374 static int warned = 0; 375 if (! warned) 376 { 377 error ("exception handling disabled, use %<-fexceptions%> to enable"); 378 warned = 1; 379 } 380 return 0; 381 } 382 return 1; 383} 384 385/* Call this to start a catch block. DECL is the catch parameter. */ 386 387tree 388expand_start_catch_block (tree decl) 389{ 390 tree exp; 391 tree type, init; 392 393 if (! doing_eh ()) 394 return NULL_TREE; 395 396 if (decl) 397 { 398 if (!is_admissible_throw_operand_or_catch_parameter (decl, false)) 399 decl = error_mark_node; 400 401 type = prepare_eh_type (TREE_TYPE (decl)); 402 mark_used (eh_type_info (type)); 403 } 404 else 405 type = NULL_TREE; 406 407 /* Call __cxa_end_catch at the end of processing the exception. */ 408 push_eh_cleanup (type); 409 410 init = do_begin_catch (); 411 412 /* If there's no decl at all, then all we need to do is make sure 413 to tell the runtime that we've begun handling the exception. */ 414 if (decl == NULL || decl == error_mark_node || init == error_mark_node) 415 finish_expr_stmt (init); 416 417 /* If the C++ object needs constructing, we need to do that before 418 calling __cxa_begin_catch, so that std::uncaught_exception gets 419 the right value during the copy constructor. */ 420 else if (flag_use_cxa_get_exception_ptr 421 && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) 422 { 423 exp = do_get_exception_ptr (); 424 if (exp != error_mark_node) 425 initialize_handler_parm (decl, exp); 426 finish_expr_stmt (init); 427 } 428 429 /* Otherwise the type uses a bitwise copy, and we don't have to worry 430 about the value of std::uncaught_exception and therefore can do the 431 copy with the return value of __cxa_end_catch instead. */ 432 else 433 { 434 tree init_type = type; 435 436 /* Pointers are passed by values, everything else by reference. */ 437 if (!TYPE_PTR_P (type)) 438 init_type = build_pointer_type (type); 439 if (init_type != TREE_TYPE (init)) 440 init = build1 (NOP_EXPR, init_type, init); 441 exp = create_temporary_var (init_type); 442 cp_finish_decl (exp, init, /*init_const_expr=*/false, 443 NULL_TREE, LOOKUP_ONLYCONVERTING); 444 DECL_REGISTER (exp) = 1; 445 initialize_handler_parm (decl, exp); 446 } 447 448 return type; 449} 450 451/* True if we are in a catch block within a catch block. Assumes that we are 452 in function scope. */ 453 454static bool 455in_nested_catch (void) 456{ 457 int catches = 0; 458 459 /* Scan through the template parameter scopes. */ 460 for (cp_binding_level *b = current_binding_level; 461 b->kind != sk_function_parms; 462 b = b->level_chain) 463 if (b->kind == sk_catch 464 && ++catches == 2) 465 return true; 466 return false; 467} 468 469/* Call this to end a catch block. Its responsible for emitting the 470 code to handle jumping back to the correct place, and for emitting 471 the label to jump to if this catch block didn't match. */ 472 473void 474expand_end_catch_block (void) 475{ 476 if (! doing_eh ()) 477 return; 478 479 /* The exception being handled is rethrown if control reaches the end of 480 a handler of the function-try-block of a constructor or destructor. */ 481 if (in_function_try_handler 482 && (DECL_CONSTRUCTOR_P (current_function_decl) 483 || DECL_DESTRUCTOR_P (current_function_decl)) 484 && !in_nested_catch ()) 485 { 486 tree rethrow = build_throw (input_location, NULL_TREE); 487 /* Disable all warnings for the generated rethrow statement. */ 488 suppress_warning (rethrow); 489 finish_expr_stmt (rethrow); 490 } 491} 492 493tree 494begin_eh_spec_block (void) 495{ 496 tree r; 497 location_t spec_location = DECL_SOURCE_LOCATION (current_function_decl); 498 499 /* A noexcept specification (or throw() with -fnothrow-opt) is a 500 MUST_NOT_THROW_EXPR. */ 501 if (TYPE_NOEXCEPT_P (TREE_TYPE (current_function_decl))) 502 { 503 r = build_stmt (spec_location, MUST_NOT_THROW_EXPR, 504 NULL_TREE, NULL_TREE); 505 TREE_SIDE_EFFECTS (r) = 1; 506 } 507 else 508 r = build_stmt (spec_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE); 509 add_stmt (r); 510 TREE_OPERAND (r, 0) = push_stmt_list (); 511 return r; 512} 513 514void 515finish_eh_spec_block (tree raw_raises, tree eh_spec_block) 516{ 517 tree raises; 518 519 TREE_OPERAND (eh_spec_block, 0) 520 = pop_stmt_list (TREE_OPERAND (eh_spec_block, 0)); 521 522 if (TREE_CODE (eh_spec_block) == MUST_NOT_THROW_EXPR) 523 return; 524 525 /* Strip cv quals, etc, from the specification types. */ 526 for (raises = NULL_TREE; 527 raw_raises && TREE_VALUE (raw_raises); 528 raw_raises = TREE_CHAIN (raw_raises)) 529 { 530 tree type = prepare_eh_type (TREE_VALUE (raw_raises)); 531 tree tinfo = eh_type_info (type); 532 533 mark_used (tinfo); 534 raises = tree_cons (NULL_TREE, type, raises); 535 } 536 537 EH_SPEC_RAISES (eh_spec_block) = raises; 538} 539 540/* Return a pointer to a buffer for an exception object of type TYPE. */ 541 542static tree 543do_allocate_exception (tree type) 544{ 545 if (!allocate_exception_fn) 546 /* Declare void *__cxa_allocate_exception(size_t) throw(). */ 547 allocate_exception_fn 548 = declare_library_fn ("__cxa_allocate_exception", 549 ptr_type_node, size_type_node, 550 ECF_NOTHROW | ECF_MALLOC | ECF_COLD, ECF_TM_PURE); 551 552 return cp_build_function_call_nary (allocate_exception_fn, 553 tf_warning_or_error, 554 size_in_bytes (type), NULL_TREE); 555} 556 557/* Call __cxa_free_exception from a cleanup. This is never invoked 558 directly, but see the comment for stabilize_throw_expr. */ 559 560static tree 561do_free_exception (tree ptr) 562{ 563 if (!free_exception_fn) 564 /* Declare void __cxa_free_exception (void *) throw(). */ 565 free_exception_fn 566 = declare_library_fn ("__cxa_free_exception", 567 void_type_node, ptr_type_node, 568 ECF_NOTHROW | ECF_LEAF, ECF_TM_PURE); 569 570 return cp_build_function_call_nary (free_exception_fn, 571 tf_warning_or_error, ptr, NULL_TREE); 572} 573 574/* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR. 575 Called from build_throw via walk_tree_without_duplicates. */ 576 577static tree 578wrap_cleanups_r (tree *tp, int *walk_subtrees, void * /*data*/) 579{ 580 tree exp = *tp; 581 tree cleanup; 582 583 /* Don't walk into types. */ 584 if (TYPE_P (exp)) 585 { 586 *walk_subtrees = 0; 587 return NULL_TREE; 588 } 589 if (TREE_CODE (exp) != TARGET_EXPR) 590 return NULL_TREE; 591 592 cleanup = TARGET_EXPR_CLEANUP (exp); 593 if (cleanup) 594 { 595 cleanup = build2 (MUST_NOT_THROW_EXPR, void_type_node, cleanup, 596 NULL_TREE); 597 TARGET_EXPR_CLEANUP (exp) = cleanup; 598 } 599 600 /* Keep iterating. */ 601 return NULL_TREE; 602} 603 604/* Build a throw expression. */ 605 606tree 607build_throw (location_t loc, tree exp) 608{ 609 if (exp == error_mark_node) 610 return exp; 611 612 if (processing_template_decl) 613 { 614 if (cfun) 615 current_function_returns_abnormally = 1; 616 exp = build_min (THROW_EXPR, void_type_node, exp); 617 SET_EXPR_LOCATION (exp, loc); 618 return exp; 619 } 620 621 if (exp && null_node_p (exp)) 622 warning_at (loc, 0, 623 "throwing NULL, which has integral, not pointer type"); 624 625 if (exp != NULL_TREE) 626 { 627 if (!is_admissible_throw_operand_or_catch_parameter (exp, true)) 628 return error_mark_node; 629 } 630 631 if (! doing_eh ()) 632 return error_mark_node; 633 634 if (exp) 635 { 636 tree throw_type; 637 tree temp_type; 638 tree cleanup; 639 tree object, ptr; 640 tree allocate_expr; 641 642 /* The CLEANUP_TYPE is the internal type of a destructor. */ 643 if (!cleanup_type) 644 { 645 tree tmp = build_function_type_list (void_type_node, 646 ptr_type_node, NULL_TREE); 647 cleanup_type = build_pointer_type (tmp); 648 } 649 650 if (!throw_fn) 651 { 652 tree args[3] = {ptr_type_node, ptr_type_node, cleanup_type}; 653 654 throw_fn = declare_library_fn_1 ("__cxa_throw", 655 ECF_NORETURN | ECF_COLD, 656 void_type_node, 3, args); 657 if (flag_tm && throw_fn != error_mark_node) 658 { 659 tree itm_fn = declare_library_fn_1 ("_ITM_cxa_throw", 660 ECF_NORETURN | ECF_COLD, 661 void_type_node, 3, args); 662 if (itm_fn != error_mark_node) 663 { 664 apply_tm_attr (itm_fn, get_identifier ("transaction_pure")); 665 record_tm_replacement (throw_fn, itm_fn); 666 } 667 } 668 } 669 670 /* [except.throw] 671 672 A throw-expression initializes a temporary object, the type 673 of which is determined by removing any top-level 674 cv-qualifiers from the static type of the operand of throw 675 and adjusting the type from "array of T" or "function return 676 T" to "pointer to T" or "pointer to function returning T" 677 respectively. */ 678 temp_type = is_bitfield_expr_with_lowered_type (exp); 679 if (!temp_type) 680 temp_type = cv_unqualified (type_decays_to (TREE_TYPE (exp))); 681 682 /* OK, this is kind of wacky. The standard says that we call 683 terminate when the exception handling mechanism, after 684 completing evaluation of the expression to be thrown but 685 before the exception is caught (_except.throw_), calls a 686 user function that exits via an uncaught exception. 687 688 So we have to protect the actual initialization of the 689 exception object with terminate(), but evaluate the 690 expression first. Since there could be temps in the 691 expression, we need to handle that, too. We also expand 692 the call to __cxa_allocate_exception first (which doesn't 693 matter, since it can't throw). */ 694 695 /* Allocate the space for the exception. */ 696 allocate_expr = do_allocate_exception (temp_type); 697 if (allocate_expr == error_mark_node) 698 return error_mark_node; 699 allocate_expr = get_target_expr (allocate_expr); 700 ptr = TARGET_EXPR_SLOT (allocate_expr); 701 TARGET_EXPR_CLEANUP (allocate_expr) = do_free_exception (ptr); 702 CLEANUP_EH_ONLY (allocate_expr) = 1; 703 704 object = build_nop (build_pointer_type (temp_type), ptr); 705 object = cp_build_fold_indirect_ref (object); 706 707 /* And initialize the exception object. */ 708 if (CLASS_TYPE_P (temp_type)) 709 { 710 int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING; 711 bool converted = false; 712 location_t exp_loc = cp_expr_loc_or_loc (exp, loc); 713 714 /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes 715 treated as an rvalue for the purposes of overload resolution 716 to favor move constructors over copy constructors. */ 717 if (tree moved = treat_lvalue_as_rvalue_p (exp, /*return*/false)) 718 { 719 if (cxx_dialect < cxx20) 720 { 721 releasing_vec exp_vec (make_tree_vector_single (moved)); 722 moved = (build_special_member_call 723 (object, complete_ctor_identifier, &exp_vec, 724 TREE_TYPE (object), flags|LOOKUP_PREFER_RVALUE, 725 tf_none)); 726 if (moved != error_mark_node) 727 { 728 exp = moved; 729 converted = true; 730 } 731 } 732 else 733 /* In C++20 we just treat the return value as an rvalue that 734 can bind to lvalue refs. */ 735 exp = moved; 736 } 737 738 /* Call the copy constructor. */ 739 if (!converted) 740 { 741 releasing_vec exp_vec (make_tree_vector_single (exp)); 742 exp = (build_special_member_call 743 (object, complete_ctor_identifier, &exp_vec, 744 TREE_TYPE (object), flags, tf_warning_or_error)); 745 } 746 747 if (exp == error_mark_node) 748 { 749 inform (exp_loc, " in thrown expression"); 750 return error_mark_node; 751 } 752 } 753 else 754 { 755 tree tmp = decay_conversion (exp, tf_warning_or_error); 756 if (tmp == error_mark_node) 757 return error_mark_node; 758 exp = build2 (INIT_EXPR, temp_type, object, tmp); 759 } 760 761 /* Mark any cleanups from the initialization as MUST_NOT_THROW, since 762 they are run after the exception object is initialized. */ 763 cp_walk_tree_without_duplicates (&exp, wrap_cleanups_r, 0); 764 765 /* Prepend the allocation. */ 766 exp = build2 (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp); 767 768 /* Force all the cleanups to be evaluated here so that we don't have 769 to do them during unwinding. */ 770 exp = build1 (CLEANUP_POINT_EXPR, void_type_node, exp); 771 772 throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object))); 773 774 cleanup = NULL_TREE; 775 if (type_build_dtor_call (TREE_TYPE (object))) 776 { 777 tree dtor_fn = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)), 778 complete_dtor_identifier, 0, 779 tf_warning_or_error); 780 dtor_fn = BASELINK_FUNCTIONS (dtor_fn); 781 mark_used (dtor_fn); 782 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object))) 783 { 784 cxx_mark_addressable (dtor_fn); 785 /* Pretend it's a normal function. */ 786 cleanup = build1 (ADDR_EXPR, cleanup_type, dtor_fn); 787 } 788 } 789 if (cleanup == NULL_TREE) 790 cleanup = build_int_cst (cleanup_type, 0); 791 792 /* ??? Indicate that this function call throws throw_type. */ 793 tree tmp = cp_build_function_call_nary (throw_fn, tf_warning_or_error, 794 ptr, throw_type, cleanup, 795 NULL_TREE); 796 797 /* Tack on the initialization stuff. */ 798 exp = build2 (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp); 799 } 800 else 801 { 802 /* Rethrow current exception. */ 803 if (!rethrow_fn) 804 { 805 rethrow_fn = declare_library_fn_1 ("__cxa_rethrow", 806 ECF_NORETURN | ECF_COLD, 807 void_type_node, 0, NULL); 808 if (flag_tm && rethrow_fn != error_mark_node) 809 apply_tm_attr (rethrow_fn, get_identifier ("transaction_pure")); 810 } 811 812 /* ??? Indicate that this function call allows exceptions of the type 813 of the enclosing catch block (if known). */ 814 exp = cp_build_function_call_vec (rethrow_fn, NULL, tf_warning_or_error); 815 } 816 817 exp = build1_loc (loc, THROW_EXPR, void_type_node, exp); 818 819 return exp; 820} 821 822/* Make sure TYPE is complete, pointer to complete, reference to 823 complete, or pointer to cv void. Issue diagnostic on failure. 824 Return the zero on failure and nonzero on success. FROM can be 825 the expr or decl from whence TYPE came, if available. */ 826 827static int 828complete_ptr_ref_or_void_ptr_p (tree type, tree from) 829{ 830 int is_ptr; 831 832 /* Check complete. */ 833 type = complete_type_or_else (type, from); 834 if (!type) 835 return 0; 836 837 /* Or a pointer or ref to one, or cv void *. */ 838 is_ptr = TYPE_PTR_P (type); 839 if (is_ptr || TYPE_REF_P (type)) 840 { 841 tree core = TREE_TYPE (type); 842 843 if (is_ptr && VOID_TYPE_P (core)) 844 /* OK */; 845 else if (!complete_type_or_else (core, from)) 846 return 0; 847 } 848 return 1; 849} 850 851/* If IS_THROW is true return truth-value if T is an expression admissible 852 in throw-expression, i.e. if it is not of incomplete type or a pointer/ 853 reference to such a type or of an abstract class type. 854 If IS_THROW is false, likewise for a catch parameter, same requirements 855 for its type plus rvalue reference type is also not admissible. */ 856 857static bool 858is_admissible_throw_operand_or_catch_parameter (tree t, bool is_throw) 859{ 860 tree expr = is_throw ? t : NULL_TREE; 861 tree type = TREE_TYPE (t); 862 863 /* C++11 [except.handle] The exception-declaration shall not denote 864 an incomplete type, an abstract class type, or an rvalue reference 865 type. */ 866 867 /* 15.1/4 [...] The type of the throw-expression shall not be an 868 incomplete type, or a pointer or a reference to an incomplete 869 type, other than void*, const void*, volatile void*, or 870 const volatile void*. Except for these restriction and the 871 restrictions on type matching mentioned in 15.3, the operand 872 of throw is treated exactly as a function argument in a call 873 (5.2.2) or the operand of a return statement. */ 874 if (!complete_ptr_ref_or_void_ptr_p (type, expr)) 875 return false; 876 877 tree nonref_type = non_reference (type); 878 if (!verify_type_context (input_location, TCTX_EXCEPTIONS, nonref_type)) 879 return false; 880 881 /* 10.4/3 An abstract class shall not be used as a parameter type, 882 as a function return type or as type of an explicit 883 conversion. */ 884 else if (abstract_virtuals_error (is_throw ? ACU_THROW : ACU_CATCH, type)) 885 return false; 886 else if (!is_throw 887 && TYPE_REF_P (type) 888 && TYPE_REF_IS_RVALUE (type)) 889 { 890 error ("cannot declare %<catch%> parameter to be of rvalue " 891 "reference type %qT", type); 892 return false; 893 } 894 else if (variably_modified_type_p (type, NULL_TREE)) 895 { 896 if (is_throw) 897 error_at (cp_expr_loc_or_input_loc (expr), 898 "cannot throw expression of type %qT because it involves " 899 "types of variable size", type); 900 else 901 error ("cannot catch type %qT because it involves types of " 902 "variable size", type); 903 return false; 904 } 905 906 return true; 907} 908 909/* Returns nonzero if FN is a declaration of a standard C library 910 function which is known not to throw. 911 912 [lib.res.on.exception.handling]: None of the functions from the 913 Standard C library shall report an error by throwing an 914 exception, unless it calls a program-supplied function that 915 throws an exception. */ 916 917#include "cfns.h" 918 919int 920nothrow_libfn_p (const_tree fn) 921{ 922 tree id; 923 924 if (TREE_PUBLIC (fn) 925 && DECL_EXTERNAL (fn) 926 && DECL_NAMESPACE_SCOPE_P (fn) 927 && DECL_EXTERN_C_P (fn)) 928 /* OK */; 929 else 930 /* Can't be a C library function. */ 931 return 0; 932 933 /* Being a C library function, DECL_ASSEMBLER_NAME == DECL_NAME 934 unless the system headers are playing rename tricks, and if 935 they are, we don't want to be confused by them. */ 936 id = DECL_NAME (fn); 937 const struct libc_name_struct *s 938 = libc_name::libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id)); 939 if (s == NULL) 940 return 0; 941 switch (s->c_ver) 942 { 943 case 89: return 1; 944 case 99: return !flag_iso || flag_isoc99; 945 case 11: return !flag_iso || flag_isoc11; 946 default: gcc_unreachable (); 947 } 948} 949 950/* Returns nonzero if an exception of type FROM will be caught by a 951 handler for type TO, as per [except.handle]. */ 952 953static bool 954can_convert_eh (tree to, tree from) 955{ 956 to = non_reference (to); 957 from = non_reference (from); 958 959 if (same_type_ignoring_top_level_qualifiers_p (to, from)) 960 return true; 961 962 if (TYPE_PTR_P (to) && TYPE_PTR_P (from)) 963 { 964 to = TREE_TYPE (to); 965 from = TREE_TYPE (from); 966 967 if (! at_least_as_qualified_p (to, from)) 968 return false; 969 970 if (VOID_TYPE_P (to)) 971 return true; 972 973 /* Else fall through. */ 974 } 975 976 if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from) 977 && publicly_uniquely_derived_p (to, from)) 978 return true; 979 980 return false; 981} 982 983/* Check whether any of the handlers in I are shadowed by another handler 984 accepting TYPE. Note that the shadowing may not be complete; even if 985 an exception of type B would be caught by a handler for A, there could 986 be a derived class C for which A is an ambiguous base but B is not, so 987 the handler for B would catch an exception of type C. */ 988 989static void 990check_handlers_1 (tree master, tree_stmt_iterator i) 991{ 992 tree type = TREE_TYPE (master); 993 994 for (; !tsi_end_p (i); tsi_next (&i)) 995 { 996 tree handler = tsi_stmt (i); 997 if (TREE_TYPE (handler) && can_convert_eh (type, TREE_TYPE (handler))) 998 { 999 auto_diagnostic_group d; 1000 if (warning_at (EXPR_LOCATION (handler), OPT_Wexceptions, 1001 "exception of type %qT will be caught by earlier " 1002 "handler", TREE_TYPE (handler))) 1003 inform (EXPR_LOCATION (master), "for type %qT", type); 1004 break; 1005 } 1006 } 1007} 1008 1009/* Given a STATEMENT_LIST of HANDLERs, make sure that they're OK. */ 1010 1011void 1012check_handlers (tree handlers) 1013{ 1014 tree_stmt_iterator i; 1015 1016 /* If we don't have a STATEMENT_LIST, then we've just got one 1017 handler, and thus nothing to warn about. */ 1018 if (TREE_CODE (handlers) != STATEMENT_LIST) 1019 return; 1020 1021 i = tsi_start (handlers); 1022 if (!tsi_end_p (i)) 1023 while (1) 1024 { 1025 tree handler = tsi_stmt (i); 1026 tsi_next (&i); 1027 1028 /* No more handlers; nothing to shadow. */ 1029 if (tsi_end_p (i)) 1030 break; 1031 if (TREE_TYPE (handler) == NULL_TREE) 1032 permerror (EXPR_LOCATION (handler), "%<...%>" 1033 " handler must be the last handler for its try block"); 1034 else 1035 check_handlers_1 (handler, i); 1036 } 1037} 1038 1039/* walk_tree helper for finish_noexcept_expr. Returns non-null if the 1040 expression *TP causes the noexcept operator to evaluate to false. 1041 1042 5.3.7 [expr.noexcept]: The result of the noexcept operator is false if 1043 in a potentially-evaluated context the expression would contain 1044 * a potentially evaluated call to a function, member function, 1045 function pointer, or member function pointer that does not have a 1046 non-throwing exception-specification (15.4), 1047 * a potentially evaluated throw-expression (15.1), 1048 * a potentially evaluated dynamic_cast expression dynamic_cast<T>(v), 1049 where T is a reference type, that requires a run-time check (5.2.7), or 1050 * a potentially evaluated typeid expression (5.2.8) applied to a glvalue 1051 expression whose type is a polymorphic class type (10.3). */ 1052 1053static tree 1054check_noexcept_r (tree *tp, int *walk_subtrees, void *) 1055{ 1056 tree t = *tp; 1057 enum tree_code code = TREE_CODE (t); 1058 1059 if (unevaluated_p (code)) 1060 *walk_subtrees = false; 1061 else if ((code == CALL_EXPR && CALL_EXPR_FN (t)) 1062 || code == AGGR_INIT_EXPR) 1063 { 1064 /* We can only use the exception specification of the called function 1065 for determining the value of a noexcept expression; we can't use 1066 TREE_NOTHROW, as it might have a different value in another 1067 translation unit, creating ODR problems. 1068 1069 We could use TREE_NOTHROW (t) for !TREE_PUBLIC fns, though... */ 1070 tree fn = cp_get_callee (t); 1071 if (concept_check_p (fn)) 1072 return NULL_TREE; 1073 tree type = TREE_TYPE (fn); 1074 gcc_assert (INDIRECT_TYPE_P (type)); 1075 type = TREE_TYPE (type); 1076 1077 STRIP_NOPS (fn); 1078 if (TREE_CODE (fn) == ADDR_EXPR) 1079 fn = TREE_OPERAND (fn, 0); 1080 if (TREE_CODE (fn) == FUNCTION_DECL) 1081 { 1082 /* We do use TREE_NOTHROW for ABI internals like __dynamic_cast, 1083 and for C library functions known not to throw. */ 1084 if (DECL_EXTERN_C_P (fn) 1085 && (DECL_ARTIFICIAL (fn) 1086 || nothrow_libfn_p (fn))) 1087 return TREE_NOTHROW (fn) ? NULL_TREE : fn; 1088 /* We used to treat a call to a constexpr function as noexcept if 1089 the call was a constant expression (CWG 1129). This has changed 1090 in P0003 whereby noexcept has no special rule for constant 1091 expressions anymore. Since the current behavior is important for 1092 certain library functionality, we treat this as a DR, therefore 1093 adjusting the behavior for C++11 and C++14. Previously, we had 1094 to evaluate the noexcept-specifier's operand here, but that could 1095 cause instantiations that would fail. */ 1096 } 1097 if (!TYPE_NOTHROW_P (type)) 1098 return fn; 1099 } 1100 1101 return NULL_TREE; 1102} 1103 1104/* If a function that causes a noexcept-expression to be false isn't 1105 defined yet, remember it and check it for TREE_NOTHROW again at EOF. */ 1106 1107struct GTY(()) pending_noexcept { 1108 tree fn; 1109 location_t loc; 1110}; 1111static GTY(()) vec<pending_noexcept, va_gc> *pending_noexcept_checks; 1112 1113/* FN is a FUNCTION_DECL that caused a noexcept-expr to be false. Warn if 1114 it can't throw. 1115 1116 TODO: Consider extending -Wnoexcept to do something like walk_subtrees in the 1117 case of a defaulted function that obtained a noexcept(false) spec. */ 1118 1119static void 1120maybe_noexcept_warning (tree fn) 1121{ 1122 if (TREE_NOTHROW (fn) 1123 && (!DECL_IN_SYSTEM_HEADER (fn) 1124 || global_dc->dc_warn_system_headers)) 1125 { 1126 auto s = make_temp_override (global_dc->dc_warn_system_headers, true); 1127 auto_diagnostic_group d; 1128 if (warning (OPT_Wnoexcept, "noexcept-expression evaluates to %<false%> " 1129 "because of a call to %qD", fn)) 1130 inform (DECL_SOURCE_LOCATION (fn), 1131 "but %qD does not throw; perhaps " 1132 "it should be declared %<noexcept%>", fn); 1133 } 1134} 1135 1136/* Check any functions that weren't defined earlier when they caused a 1137 noexcept expression to evaluate to false. */ 1138 1139void 1140perform_deferred_noexcept_checks (void) 1141{ 1142 int i; 1143 pending_noexcept *p; 1144 location_t saved_loc = input_location; 1145 FOR_EACH_VEC_SAFE_ELT (pending_noexcept_checks, i, p) 1146 { 1147 input_location = p->loc; 1148 maybe_noexcept_warning (p->fn); 1149 } 1150 input_location = saved_loc; 1151} 1152 1153/* Evaluate noexcept ( EXPR ). */ 1154 1155tree 1156finish_noexcept_expr (tree expr, tsubst_flags_t complain) 1157{ 1158 if (expr == error_mark_node) 1159 return error_mark_node; 1160 1161 if (processing_template_decl) 1162 return build_min (NOEXCEPT_EXPR, boolean_type_node, expr); 1163 1164 return (expr_noexcept_p (expr, complain) 1165 ? boolean_true_node : boolean_false_node); 1166} 1167 1168/* Returns whether EXPR is noexcept, possibly warning if allowed by 1169 COMPLAIN. */ 1170 1171bool 1172expr_noexcept_p (tree expr, tsubst_flags_t complain) 1173{ 1174 tree fn; 1175 1176 if (expr == error_mark_node) 1177 return false; 1178 1179 fn = cp_walk_tree_without_duplicates (&expr, check_noexcept_r, 0); 1180 if (fn) 1181 { 1182 if ((complain & tf_warning) && warn_noexcept 1183 && TREE_CODE (fn) == FUNCTION_DECL) 1184 { 1185 if (!DECL_INITIAL (fn)) 1186 { 1187 /* Not defined yet; check again at EOF. */ 1188 pending_noexcept p = {fn, input_location}; 1189 vec_safe_push (pending_noexcept_checks, p); 1190 } 1191 else 1192 maybe_noexcept_warning (fn); 1193 } 1194 return false; 1195 } 1196 else 1197 return true; 1198} 1199 1200/* Return true iff SPEC is throw() or noexcept(true). */ 1201 1202bool 1203nothrow_spec_p (const_tree spec) 1204{ 1205 gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (spec)); 1206 1207 if (spec == empty_except_spec 1208 || spec == noexcept_true_spec) 1209 return true; 1210 1211 gcc_assert (!spec 1212 || TREE_VALUE (spec) 1213 || spec == noexcept_false_spec 1214 || TREE_PURPOSE (spec) == error_mark_node 1215 || UNPARSED_NOEXCEPT_SPEC_P (spec) 1216 || processing_template_decl); 1217 1218 return false; 1219} 1220 1221/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE is noexcept. This is the 1222 case for things declared noexcept(true) and, with -fnothrow-opt, for 1223 throw() functions. */ 1224 1225bool 1226type_noexcept_p (const_tree type) 1227{ 1228 tree spec = TYPE_RAISES_EXCEPTIONS (type); 1229 gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (spec)); 1230 if (flag_nothrow_opt) 1231 return nothrow_spec_p (spec); 1232 else 1233 return spec == noexcept_true_spec; 1234} 1235 1236/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE can throw any type, 1237 i.e. no exception-specification or noexcept(false). */ 1238 1239bool 1240type_throw_all_p (const_tree type) 1241{ 1242 tree spec = TYPE_RAISES_EXCEPTIONS (type); 1243 gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (spec)); 1244 return spec == NULL_TREE || spec == noexcept_false_spec; 1245} 1246 1247/* Create a representation of the noexcept-specification with 1248 constant-expression of EXPR. COMPLAIN is as for tsubst. */ 1249 1250tree 1251build_noexcept_spec (tree expr, tsubst_flags_t complain) 1252{ 1253 if (check_for_bare_parameter_packs (expr)) 1254 return error_mark_node; 1255 if (TREE_CODE (expr) != DEFERRED_NOEXCEPT 1256 && !instantiation_dependent_expression_p (expr)) 1257 { 1258 expr = build_converted_constant_bool_expr (expr, complain); 1259 expr = instantiate_non_dependent_expr_sfinae (expr, complain); 1260 expr = cxx_constant_value (expr); 1261 } 1262 if (TREE_CODE (expr) == INTEGER_CST) 1263 { 1264 if (operand_equal_p (expr, boolean_true_node, 0)) 1265 return noexcept_true_spec; 1266 else 1267 { 1268 gcc_checking_assert (operand_equal_p (expr, boolean_false_node, 0)); 1269 return noexcept_false_spec; 1270 } 1271 } 1272 else if (expr == error_mark_node) 1273 return error_mark_node; 1274 else 1275 { 1276 gcc_assert (processing_template_decl 1277 || TREE_CODE (expr) == DEFERRED_NOEXCEPT); 1278 if (TREE_CODE (expr) != DEFERRED_NOEXCEPT) 1279 /* Avoid problems with a function type built with a dependent typedef 1280 being reused in another scope (c++/84045). */ 1281 expr = strip_typedefs_expr (expr); 1282 return build_tree_list (expr, NULL_TREE); 1283 } 1284} 1285 1286/* If the current function has a cleanup that might throw, and the return value 1287 has a non-trivial destructor, return a MODIFY_EXPR to set 1288 current_retval_sentinel so that we know that the return value needs to be 1289 destroyed on throw. Otherwise, returns NULL_TREE. */ 1290 1291tree 1292maybe_set_retval_sentinel () 1293{ 1294 if (processing_template_decl) 1295 return NULL_TREE; 1296 tree retval = DECL_RESULT (current_function_decl); 1297 if (!TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (retval))) 1298 return NULL_TREE; 1299 if (!cp_function_chain->throwing_cleanup) 1300 return NULL_TREE; 1301 1302 if (!current_retval_sentinel) 1303 { 1304 /* Just create the temporary now, maybe_splice_retval_cleanup 1305 will do the rest. */ 1306 current_retval_sentinel = create_temporary_var (boolean_type_node); 1307 DECL_INITIAL (current_retval_sentinel) = boolean_false_node; 1308 pushdecl_outermost_localscope (current_retval_sentinel); 1309 } 1310 1311 return build2 (MODIFY_EXPR, boolean_type_node, 1312 current_retval_sentinel, boolean_true_node); 1313} 1314 1315/* COMPOUND_STMT is the STATEMENT_LIST for some block. If COMPOUND_STMT is the 1316 current function body or a try block, and current_retval_sentinel was set in 1317 this function, wrap the block in a CLEANUP_STMT to destroy the return value 1318 on throw. */ 1319 1320void 1321maybe_splice_retval_cleanup (tree compound_stmt) 1322{ 1323 /* If we need a cleanup for the return value, add it in at the same level as 1324 pushdecl_outermost_localscope. And also in try blocks. */ 1325 const bool function_body 1326 = (current_binding_level->level_chain 1327 && current_binding_level->level_chain->kind == sk_function_parms 1328 /* When we're processing a default argument, c_f_d may not have been 1329 set. */ 1330 && current_function_decl); 1331 1332 if ((function_body || current_binding_level->kind == sk_try) 1333 && !DECL_CONSTRUCTOR_P (current_function_decl) 1334 && !DECL_DESTRUCTOR_P (current_function_decl) 1335 && current_retval_sentinel) 1336 { 1337 location_t loc = DECL_SOURCE_LOCATION (current_function_decl); 1338 tree_stmt_iterator iter = tsi_start (compound_stmt); 1339 tree retval = DECL_RESULT (current_function_decl); 1340 1341 if (function_body) 1342 { 1343 /* Add a DECL_EXPR for current_retval_sentinel. */ 1344 tree decl_expr = build_stmt (loc, DECL_EXPR, current_retval_sentinel); 1345 tsi_link_before (&iter, decl_expr, TSI_SAME_STMT); 1346 } 1347 1348 /* Skip past other decls, they can't contain a return. */ 1349 while (TREE_CODE (tsi_stmt (iter)) == DECL_EXPR) 1350 tsi_next (&iter); 1351 gcc_assert (!tsi_end_p (iter)); 1352 1353 /* Wrap the rest of the STATEMENT_LIST in a CLEANUP_STMT. */ 1354 tree stmts = NULL_TREE; 1355 while (!tsi_end_p (iter)) 1356 { 1357 append_to_statement_list_force (tsi_stmt (iter), &stmts); 1358 tsi_delink (&iter); 1359 } 1360 tree dtor = build_cleanup (retval); 1361 tree cond = build3 (COND_EXPR, void_type_node, current_retval_sentinel, 1362 dtor, void_node); 1363 tree cleanup = build_stmt (loc, CLEANUP_STMT, 1364 stmts, cond, retval); 1365 CLEANUP_EH_ONLY (cleanup) = true; 1366 append_to_statement_list_force (cleanup, &compound_stmt); 1367 } 1368} 1369 1370#include "gt-cp-except.h" 1371