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))