X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fcp%2Frtti.c;h=4eb2ba74c06db5bbe0890ef50d290e2f7ebfc44e;hp=383c96c794918e4f1c38fcc37078af94eb014006;hb=36a01cad6bf9b76dceb6c1f18c633efa147b918b;hpb=c5d33fc0685467dd4ccf949dc234982481209e92 diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 383c96c7949..4eb2ba74c06 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" +#include "intl.h" #include "coretypes.h" #include "tm.h" #include "tree.h" @@ -187,7 +188,7 @@ build_headof (tree exp) index = build_int_cst (NULL_TREE, -2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE); - offset = build_vtbl_ref (cp_build_indirect_ref (exp, NULL, + offset = build_vtbl_ref (cp_build_indirect_ref (exp, RO_NULL, tf_warning_or_error), index); @@ -254,7 +255,8 @@ get_tinfo_decl_dynamic (tree exp) type = TYPE_MAIN_VARIANT (type); /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics. */ - if (CLASS_TYPE_P (type) || TREE_CODE (type) == UNKNOWN_TYPE) + if (CLASS_TYPE_P (type) || type == unknown_type_node + || type == init_list_type_node) type = complete_type_or_else (type, exp); if (!type) @@ -276,7 +278,7 @@ get_tinfo_decl_dynamic (tree exp) /* Otherwise return the type_info for the static type of the expr. */ t = get_tinfo_ptr (TYPE_MAIN_VARIANT (type)); - return cp_build_indirect_ref (t, NULL, tf_warning_or_error); + return cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error); } static bool @@ -317,7 +319,7 @@ typeid_ok_p (void) tree build_typeid (tree exp) { - tree cond = NULL_TREE; + tree cond = NULL_TREE, initial_expr = exp; int nonnull = 0; if (exp == error_mark_node || !typeid_ok_p ()) @@ -332,6 +334,9 @@ build_typeid (tree exp) && ! resolves_to_fixed_type_p (exp, &nonnull) && ! nonnull) { + /* So we need to look into the vtable of the type of exp. + This is an lvalue use of expr then. */ + exp = mark_lvalue_use (exp); exp = stabilize_reference (exp); cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0)); } @@ -347,6 +352,8 @@ build_typeid (tree exp) exp = build3 (COND_EXPR, TREE_TYPE (exp), cond, exp, bad); } + else + mark_type_use (initial_expr); return exp; } @@ -476,13 +483,14 @@ get_typeid (tree type) type = TYPE_MAIN_VARIANT (type); /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics. */ - if (CLASS_TYPE_P (type) || TREE_CODE (type) == UNKNOWN_TYPE) + if (CLASS_TYPE_P (type) || type == unknown_type_node + || type == init_list_type_node) type = complete_type_or_else (type, NULL_TREE); if (!type) return error_mark_node; - return cp_build_indirect_ref (get_tinfo_ptr (type), NULL, + return cp_build_indirect_ref (get_tinfo_ptr (type), RO_NULL, tf_warning_or_error); } @@ -525,18 +533,18 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) case REFERENCE_TYPE: if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (type))) { - errstr = "target is not pointer or reference to class"; + errstr = _("target is not pointer or reference to class"); goto fail; } if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type)))) { - errstr = "target is not pointer or reference to complete type"; + errstr = _("target is not pointer or reference to complete type"); goto fail; } break; default: - errstr = "target is not pointer or reference"; + errstr = _("target is not pointer or reference"); goto fail; } @@ -545,24 +553,28 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) /* If T is a pointer type, v shall be an rvalue of a pointer to complete class type, and the result is an rvalue of type T. */ + expr = mark_rvalue_use (expr); + if (TREE_CODE (exprtype) != POINTER_TYPE) { - errstr = "source is not a pointer"; + errstr = _("source is not a pointer"); goto fail; } if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (exprtype))) { - errstr = "source is not a pointer to class"; + errstr = _("source is not a pointer to class"); goto fail; } if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype)))) { - errstr = "source is a pointer to incomplete type"; + errstr = _("source is a pointer to incomplete type"); goto fail; } } else { + expr = mark_lvalue_use (expr); + exprtype = build_reference_type (exprtype); /* T is a reference type, v shall be an lvalue of a complete class @@ -570,12 +582,12 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (exprtype))) { - errstr = "source is not of class type"; + errstr = _("source is not of class type"); goto fail; } if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype)))) { - errstr = "source is of incomplete class type"; + errstr = _("source is of incomplete class type"); goto fail; } @@ -588,7 +600,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) if (!at_least_as_qualified_p (TREE_TYPE (type), TREE_TYPE (exprtype))) { - errstr = "conversion casts away constness"; + errstr = _("conversion casts away constness"); goto fail; } @@ -748,7 +760,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) } } else - errstr = "source type is not polymorphic"; + errstr = _("source type is not polymorphic"); fail: if (complain & tf_error) @@ -1036,6 +1048,11 @@ typeinfo_in_lib_p (tree type) case VOID_TYPE: return true; + case LANG_TYPE: + if (NULLPTR_TYPE_P (type)) + return true; + /* else fall through. */ + default: return false; } @@ -1439,6 +1456,8 @@ create_tinfo_types (void) void emit_support_tinfos (void) { + /* Dummy static variable so we can put nullptr in the array; it will be + set before we actually start to walk the array. */ static tree *const fundamentals[] = { &void_type_node, @@ -1451,6 +1470,7 @@ emit_support_tinfos (void) &long_long_integer_type_node, &long_long_unsigned_type_node, &float_type_node, &double_type_node, &long_double_type_node, &dfloat32_type_node, &dfloat64_type_node, &dfloat128_type_node, + &nullptr_type_node, 0 }; int ix;