Mercurial > hg > CbC > CbC_gcc
comparison gcc/cp/rtti.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* RunTime Type Identification | 1 /* RunTime Type Identification |
2 Copyright (C) 1995-2018 Free Software Foundation, Inc. | 2 Copyright (C) 1995-2020 Free Software Foundation, Inc. |
3 Mostly written by Jason Merrill (jason@cygnus.com). | 3 Mostly written by Jason Merrill (jason@cygnus.com). |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify | 7 GCC is free software; you can redistribute it and/or modify |
121 and are generated as needed. */ | 121 and are generated as needed. */ |
122 static GTY (()) vec<tinfo_s, va_gc> *tinfo_descs; | 122 static GTY (()) vec<tinfo_s, va_gc> *tinfo_descs; |
123 | 123 |
124 static tree ifnonnull (tree, tree, tsubst_flags_t); | 124 static tree ifnonnull (tree, tree, tsubst_flags_t); |
125 static tree tinfo_name (tree, bool); | 125 static tree tinfo_name (tree, bool); |
126 static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t); | 126 static tree build_dynamic_cast_1 (location_t, tree, tree, tsubst_flags_t); |
127 static tree throw_bad_cast (void); | 127 static tree throw_bad_cast (void); |
128 static tree throw_bad_typeid (void); | 128 static tree throw_bad_typeid (void); |
129 static tree get_tinfo_ptr (tree); | 129 static tree get_tinfo_ptr (tree); |
130 static bool typeid_ok_p (void); | 130 static bool typeid_ok_p (void); |
131 static int qualifier_flags (tree); | 131 static int qualifier_flags (tree); |
166 void | 166 void |
167 init_rtti_processing (void) | 167 init_rtti_processing (void) |
168 { | 168 { |
169 tree type_info_type; | 169 tree type_info_type; |
170 | 170 |
171 push_namespace (std_identifier); | 171 push_nested_namespace (std_node); |
172 type_info_type = xref_tag (class_type, get_identifier ("type_info"), | 172 type_info_type = xref_tag (class_type, get_identifier ("type_info"), |
173 /*tag_scope=*/ts_current, false); | 173 /*tag_scope=*/ts_current, false); |
174 pop_namespace (); | 174 pop_nested_namespace (std_node); |
175 const_type_info_type_node | 175 const_type_info_type_node |
176 = cp_build_qualified_type (type_info_type, TYPE_QUAL_CONST); | 176 = cp_build_qualified_type (type_info_type, TYPE_QUAL_CONST); |
177 type_info_ptr_type = build_pointer_type (const_type_info_type_node); | 177 type_info_ptr_type = build_pointer_type (const_type_info_type_node); |
178 | 178 |
179 vec_alloc (unemitted_tinfo_decls, 124); | 179 vec_alloc (unemitted_tinfo_decls, 124); |
207 -2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE); | 207 -2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE); |
208 | 208 |
209 offset = build_vtbl_ref (cp_build_fold_indirect_ref (exp), | 209 offset = build_vtbl_ref (cp_build_fold_indirect_ref (exp), |
210 index); | 210 index); |
211 | 211 |
212 type = cp_build_qualified_type (ptr_type_node, | 212 cp_build_qualified_type (ptr_type_node, |
213 cp_type_quals (TREE_TYPE (exp))); | 213 cp_type_quals (TREE_TYPE (exp))); |
214 return fold_build_pointer_plus (exp, offset); | 214 return fold_build_pointer_plus (exp, offset); |
215 } | 215 } |
216 | 216 |
217 /* Get a bad_cast node for the program to throw... | 217 /* Get a bad_cast node for the program to throw... |
218 | 218 |
270 if (error_operand_p (exp)) | 270 if (error_operand_p (exp)) |
271 return error_mark_node; | 271 return error_mark_node; |
272 | 272 |
273 exp = resolve_nondeduced_context (exp, complain); | 273 exp = resolve_nondeduced_context (exp, complain); |
274 | 274 |
275 /* peel back references, so they match. */ | 275 /* Peel back references, so they match. */ |
276 type = non_reference (unlowered_expr_type (exp)); | 276 type = non_reference (unlowered_expr_type (exp)); |
277 | 277 |
278 /* Peel off cv qualifiers. */ | 278 /* Peel off cv qualifiers. */ |
279 type = TYPE_MAIN_VARIANT (type); | 279 type = cv_unqualified (type); |
280 | 280 |
281 /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics. */ | 281 /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics. */ |
282 if (CLASS_TYPE_P (type) || type == unknown_type_node | 282 if (CLASS_TYPE_P (type) || type == unknown_type_node |
283 || type == init_list_type_node) | 283 || type == init_list_type_node) |
284 type = complete_type_or_maybe_complain (type, exp, complain); | 284 type = complete_type_or_maybe_complain (type, exp, complain); |
298 t = build_vtbl_ref (exp, index); | 298 t = build_vtbl_ref (exp, index); |
299 t = convert (type_info_ptr_type, t); | 299 t = convert (type_info_ptr_type, t); |
300 } | 300 } |
301 else | 301 else |
302 /* Otherwise return the type_info for the static type of the expr. */ | 302 /* Otherwise return the type_info for the static type of the expr. */ |
303 t = get_tinfo_ptr (TYPE_MAIN_VARIANT (type)); | 303 t = get_tinfo_ptr (type); |
304 | 304 |
305 return cp_build_fold_indirect_ref (t); | 305 return cp_build_fold_indirect_ref (t); |
306 } | 306 } |
307 | 307 |
308 static bool | 308 static bool |
309 typeid_ok_p (void) | 309 typeid_ok_p (void) |
310 { | 310 { |
311 if (! flag_rtti) | 311 if (! flag_rtti) |
312 { | 312 { |
313 error ("cannot use %<typeid%> with -fno-rtti"); | 313 error ("cannot use %<typeid%> with %<-fno-rtti%>"); |
314 return false; | 314 return false; |
315 } | 315 } |
316 | 316 |
317 if (!COMPLETE_TYPE_P (const_type_info_type_node)) | 317 if (!COMPLETE_TYPE_P (const_type_info_type_node)) |
318 { | 318 { |
351 return error_mark_node; | 351 return error_mark_node; |
352 | 352 |
353 if (processing_template_decl) | 353 if (processing_template_decl) |
354 return build_min (TYPEID_EXPR, const_type_info_type_node, exp); | 354 return build_min (TYPEID_EXPR, const_type_info_type_node, exp); |
355 | 355 |
356 /* FIXME when integrating with c_fully_fold, mark | |
357 resolves_to_fixed_type_p case as a non-constant expression. */ | |
358 if (TYPE_POLYMORPHIC_P (TREE_TYPE (exp)) | 356 if (TYPE_POLYMORPHIC_P (TREE_TYPE (exp)) |
359 && ! resolves_to_fixed_type_p (exp, &nonnull) | 357 && ! resolves_to_fixed_type_p (exp, &nonnull) |
360 && ! nonnull) | 358 && ! nonnull) |
361 { | 359 { |
362 /* So we need to look into the vtable of the type of exp. | 360 /* So we need to look into the vtable of the type of exp. |
510 if (TREE_CODE (type) == FUNCTION_TYPE | 508 if (TREE_CODE (type) == FUNCTION_TYPE |
511 && (type_memfn_quals (type) != TYPE_UNQUALIFIED | 509 && (type_memfn_quals (type) != TYPE_UNQUALIFIED |
512 || type_memfn_rqual (type) != REF_QUAL_NONE)) | 510 || type_memfn_rqual (type) != REF_QUAL_NONE)) |
513 { | 511 { |
514 if (complain & tf_error) | 512 if (complain & tf_error) |
515 error ("typeid of qualified function type %qT", type); | 513 error ("%<typeid%> of qualified function type %qT", type); |
516 return error_mark_node; | 514 return error_mark_node; |
517 } | 515 } |
518 | 516 |
519 /* The top-level cv-qualifiers of the lvalue expression or the type-id | 517 /* The top-level cv-qualifiers of the lvalue expression or the type-id |
520 that is the operand of typeid are always ignored. */ | 518 that is the operand of typeid are always ignored. */ |
521 type = TYPE_MAIN_VARIANT (type); | 519 type = cv_unqualified (type); |
522 | 520 |
523 /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics. */ | 521 /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics. */ |
524 if (CLASS_TYPE_P (type) || type == unknown_type_node | 522 if (CLASS_TYPE_P (type) || type == unknown_type_node |
525 || type == init_list_type_node) | 523 || type == init_list_type_node) |
526 type = complete_type_or_maybe_complain (type, NULL_TREE, complain); | 524 type = complete_type_or_maybe_complain (type, NULL_TREE, complain); |
548 | 546 |
549 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working | 547 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working |
550 paper. */ | 548 paper. */ |
551 | 549 |
552 static tree | 550 static tree |
553 build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) | 551 build_dynamic_cast_1 (location_t loc, tree type, tree expr, |
552 tsubst_flags_t complain) | |
554 { | 553 { |
555 enum tree_code tc = TREE_CODE (type); | 554 enum tree_code tc = TREE_CODE (type); |
556 tree exprtype; | 555 tree exprtype; |
557 tree dcast_fn; | 556 tree dcast_fn; |
558 tree old_expr = expr; | 557 tree old_expr = expr; |
646 convert statically. */ | 645 convert statically. */ |
647 { | 646 { |
648 tree binfo = lookup_base (TREE_TYPE (exprtype), TREE_TYPE (type), | 647 tree binfo = lookup_base (TREE_TYPE (exprtype), TREE_TYPE (type), |
649 ba_check, NULL, complain); | 648 ba_check, NULL, complain); |
650 if (binfo) | 649 if (binfo) |
651 return build_static_cast (type, expr, complain); | 650 return build_static_cast (loc, type, expr, complain); |
652 } | 651 } |
653 | 652 |
654 /* Apply trivial conversion T -> T& for dereferenced ptrs. */ | 653 /* Apply trivial conversion T -> T& for dereferenced ptrs. */ |
655 if (tc == REFERENCE_TYPE) | 654 if (tc == REFERENCE_TYPE) |
656 expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT, | 655 expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT, |
691 if (VAR_P (old_expr) | 690 if (VAR_P (old_expr) |
692 && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE) | 691 && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE) |
693 { | 692 { |
694 tree expr = throw_bad_cast (); | 693 tree expr = throw_bad_cast (); |
695 if (complain & tf_warning) | 694 if (complain & tf_warning) |
696 warning (0, "dynamic_cast of %q#D to %q#T can never succeed", | 695 warning_at (loc, 0, |
697 old_expr, type); | 696 "%<dynamic_cast<%#T>(%#D)%> can never succeed", |
697 type, old_expr); | |
698 /* Bash it to the expected type. */ | 698 /* Bash it to the expected type. */ |
699 TREE_TYPE (expr) = type; | 699 TREE_TYPE (expr) = type; |
700 return expr; | 700 return expr; |
701 } | 701 } |
702 } | 702 } |
706 tree op = TREE_OPERAND (expr, 0); | 706 tree op = TREE_OPERAND (expr, 0); |
707 if (VAR_P (op) | 707 if (VAR_P (op) |
708 && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE) | 708 && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE) |
709 { | 709 { |
710 if (complain & tf_warning) | 710 if (complain & tf_warning) |
711 warning (0, "dynamic_cast of %q#D to %q#T can never succeed", | 711 warning_at (loc, 0, |
712 op, type); | 712 "%<dynamic_cast<%#T>(%#D)%> can never succeed", |
713 type, op); | |
713 retval = build_int_cst (type, 0); | 714 retval = build_int_cst (type, 0); |
714 return retval; | 715 return retval; |
715 } | 716 } |
716 } | 717 } |
717 | 718 |
718 /* Use of dynamic_cast when -fno-rtti is prohibited. */ | 719 /* Use of dynamic_cast when -fno-rtti is prohibited. */ |
719 if (!flag_rtti) | 720 if (!flag_rtti) |
720 { | 721 { |
721 if (complain & tf_error) | 722 if (complain & tf_error) |
722 error ("%<dynamic_cast%> not permitted with -fno-rtti"); | 723 error_at (loc, |
724 "%<dynamic_cast%> not permitted with %<-fno-rtti%>"); | |
723 return error_mark_node; | 725 return error_mark_node; |
724 } | 726 } |
725 | 727 |
726 target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); | 728 target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); |
727 static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype)); | 729 static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype)); |
773 ECF_LEAF | ECF_PURE | ECF_NOTHROW); | 775 ECF_LEAF | ECF_PURE | ECF_NOTHROW); |
774 pop_abi_namespace (); | 776 pop_abi_namespace (); |
775 dynamic_cast_node = dcast_fn; | 777 dynamic_cast_node = dcast_fn; |
776 } | 778 } |
777 result = build_cxx_call (dcast_fn, 4, elems, complain); | 779 result = build_cxx_call (dcast_fn, 4, elems, complain); |
780 SET_EXPR_LOCATION (result, loc); | |
778 | 781 |
779 if (tc == REFERENCE_TYPE) | 782 if (tc == REFERENCE_TYPE) |
780 { | 783 { |
781 tree bad = throw_bad_cast (); | 784 tree bad = throw_bad_cast (); |
782 tree neq; | 785 tree neq; |
783 | 786 |
784 result = save_expr (result); | 787 result = save_expr (result); |
785 neq = cp_truthvalue_conversion (result); | 788 neq = cp_truthvalue_conversion (result, complain); |
786 return cp_convert (type, | 789 return cp_convert (type, |
787 build3 (COND_EXPR, TREE_TYPE (result), | 790 build3 (COND_EXPR, TREE_TYPE (result), |
788 neq, result, bad), complain); | 791 neq, result, bad), complain); |
789 } | 792 } |
790 | 793 |
796 else | 799 else |
797 errstr = _("source type is not polymorphic"); | 800 errstr = _("source type is not polymorphic"); |
798 | 801 |
799 fail: | 802 fail: |
800 if (complain & tf_error) | 803 if (complain & tf_error) |
801 error ("cannot dynamic_cast %qE (of type %q#T) to type %q#T (%s)", | 804 error_at (loc, "cannot %<dynamic_cast%> %qE (of type %q#T) " |
802 old_expr, TREE_TYPE (old_expr), type, errstr); | 805 "to type %q#T (%s)", |
806 old_expr, TREE_TYPE (old_expr), type, errstr); | |
803 return error_mark_node; | 807 return error_mark_node; |
804 } | 808 } |
805 | 809 |
806 tree | 810 tree |
807 build_dynamic_cast (tree type, tree expr, tsubst_flags_t complain) | 811 build_dynamic_cast (location_t loc, tree type, tree expr, |
812 tsubst_flags_t complain) | |
808 { | 813 { |
809 tree r; | 814 tree r; |
810 | 815 |
811 if (type == error_mark_node || expr == error_mark_node) | 816 if (type == error_mark_node || expr == error_mark_node) |
812 return error_mark_node; | 817 return error_mark_node; |
813 | 818 |
814 if (processing_template_decl) | 819 if (processing_template_decl) |
815 { | 820 { |
816 expr = build_min (DYNAMIC_CAST_EXPR, type, expr); | 821 expr = build_min (DYNAMIC_CAST_EXPR, type, expr); |
817 TREE_SIDE_EFFECTS (expr) = 1; | 822 TREE_SIDE_EFFECTS (expr) = 1; |
818 return convert_from_reference (expr); | 823 r = convert_from_reference (expr); |
819 } | 824 protected_set_expr_location (r, loc); |
820 | 825 return r; |
821 r = convert_from_reference (build_dynamic_cast_1 (type, expr, complain)); | 826 } |
827 | |
828 r = convert_from_reference (build_dynamic_cast_1 (loc, type, expr, | |
829 complain)); | |
822 if (r != error_mark_node) | 830 if (r != error_mark_node) |
823 maybe_warn_about_useless_cast (type, expr, complain); | 831 maybe_warn_about_useless_cast (loc, type, expr, complain); |
832 protected_set_expr_location (r, loc); | |
824 return r; | 833 return r; |
825 } | 834 } |
826 | 835 |
827 /* Return the runtime bit mask encoding the qualifiers of TYPE. */ | 836 /* Return the runtime bit mask encoding the qualifiers of TYPE. */ |
828 | 837 |
1013 { | 1022 { |
1014 flags |= 0x20; | 1023 flags |= 0x20; |
1015 to = tx_unsafe_fn_variant (to); | 1024 to = tx_unsafe_fn_variant (to); |
1016 } | 1025 } |
1017 if (flag_noexcept_type | 1026 if (flag_noexcept_type |
1018 && (TREE_CODE (to) == FUNCTION_TYPE | 1027 && FUNC_OR_METHOD_TYPE_P (to) |
1019 || TREE_CODE (to) == METHOD_TYPE) | |
1020 && TYPE_NOTHROW_P (to)) | 1028 && TYPE_NOTHROW_P (to)) |
1021 { | 1029 { |
1022 flags |= 0x40; | 1030 flags |= 0x40; |
1023 to = build_exception_variant (to, NULL_TREE); | 1031 to = build_exception_variant (to, NULL_TREE); |
1024 } | 1032 } |
1462 /* Create the pseudo type. */ | 1470 /* Create the pseudo type. */ |
1463 tree pseudo_type = make_class_type (RECORD_TYPE); | 1471 tree pseudo_type = make_class_type (RECORD_TYPE); |
1464 /* Pass the fields chained in reverse. */ | 1472 /* Pass the fields chained in reverse. */ |
1465 finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE); | 1473 finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE); |
1466 CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type; | 1474 CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type; |
1475 xref_basetypes (pseudo_type, /*bases=*/NULL_TREE); | |
1467 | 1476 |
1468 res->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST); | 1477 res->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST); |
1469 res->name = get_identifier (real_name); | 1478 res->name = get_identifier (real_name); |
1470 | 1479 |
1471 /* Pretend this is public so determine_visibility doesn't give vtables | 1480 /* Pretend this is public so determine_visibility doesn't give vtables |
1537 set before we actually start to walk the array. */ | 1546 set before we actually start to walk the array. */ |
1538 static tree *const fundamentals[] = | 1547 static tree *const fundamentals[] = |
1539 { | 1548 { |
1540 &void_type_node, | 1549 &void_type_node, |
1541 &boolean_type_node, | 1550 &boolean_type_node, |
1542 &wchar_type_node, &char16_type_node, &char32_type_node, | 1551 &wchar_type_node, &char8_type_node, &char16_type_node, &char32_type_node, |
1543 &char_type_node, &signed_char_type_node, &unsigned_char_type_node, | 1552 &char_type_node, &signed_char_type_node, &unsigned_char_type_node, |
1544 &short_integer_type_node, &short_unsigned_type_node, | 1553 &short_integer_type_node, &short_unsigned_type_node, |
1545 &integer_type_node, &unsigned_type_node, | 1554 &integer_type_node, &unsigned_type_node, |
1546 &long_integer_type_node, &long_unsigned_type_node, | 1555 &long_integer_type_node, &long_unsigned_type_node, |
1547 &long_long_integer_type_node, &long_long_unsigned_type_node, | 1556 &long_long_integer_type_node, &long_long_unsigned_type_node, |
1552 }; | 1561 }; |
1553 int ix; | 1562 int ix; |
1554 | 1563 |
1555 /* Look for a defined class. */ | 1564 /* Look for a defined class. */ |
1556 tree bltn_type = lookup_qualified_name | 1565 tree bltn_type = lookup_qualified_name |
1557 (abi_node, get_identifier ("__fundamental_type_info"), true, false, false); | 1566 (abi_node, "__fundamental_type_info", true, false); |
1558 if (TREE_CODE (bltn_type) != TYPE_DECL) | 1567 if (TREE_CODE (bltn_type) != TYPE_DECL) |
1559 return; | 1568 return; |
1560 | 1569 |
1561 bltn_type = TREE_TYPE (bltn_type); | 1570 bltn_type = TREE_TYPE (bltn_type); |
1562 if (!COMPLETE_TYPE_P (bltn_type)) | 1571 if (!COMPLETE_TYPE_P (bltn_type)) |