From: Mark Mitchell Date: Sun, 1 Nov 1998 15:45:11 +0000 (+0000) Subject: cp-tree.h (COMPARE_STRICT): New macro. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3bfdc7190fb8136f0f66108e43f49b0b28e98374;p=gcc.git cp-tree.h (COMPARE_STRICT): New macro. * cp-tree.h (COMPARE_STRICT): New macro. (COMPARE_BASE): Likewise. (COMPARE_RELAXED): Likewise. (COMPARE_REDECLARATION): Likewise. (same_type_p): Likewise. (same_or_base_type_p): Likewise. * call.c (standard_conversion): Use them, in place of comptypes with numeric arguments. (reference_binding): Likewise. (convert_like): Likewise. (build_over_call): Likewise. (is_subseq): Likewise. (is_properly_derived_from): Likewise. (compare_ics): Likewise. (joust): Likewise. * class.c (delete_duplicate_fields_1): Likewise. (resolves_to_fixed_type_p): Likewise. (instantiate_type): Likewise. Remove #if 0'd code. * decl.c (decls_match): Likewise. Use COMPARE_REDECLARATION here. (pushdecl): Likewise. (lookup_name_real): Likewise. (grokdeclarator): Likewise. Check for illegal array declarations. (grokparms): Likewise. (grok_op_properties): Likewise. * decl2.c (check_classfn): Likewise. * friend.c (is_friend): Likewise. (make_friend_class): Likewise. * init.c (expand_aggr_init): Likewise. (expand_vec_init): Likewise. * pt.c (is_member_template_class): Remove declaration. (is_specialization_of): Use COMPARE_* and new macros. (comp_template_parms): Likewise. (convert_nontype_argument): Likewise. (coerce_template_template_parms): Likewise. (template_args_equal): Likewise. (lookup_template_class): Likewise. (type_unification_real): Likewise. (unify): Likewise. (get_bindings_real): Likewise. * search.c (covariant_return_p): Likewise. (get_matching_virtual): Likewise. * sig.c (match_method_types): Likewise. * tree.c (vec_binfo_member): Likewise. (cp_tree_equal): Likewise. * typeck.c (common_type): Likewise. (comp_array_types): Likewise. Get issues involving unknown array bounds right. (comptypes): Update comments. Use new flags. (comp_target_types): Use new macros. (compparms): Likewise. (comp_target_parms): Likewise. (string_conv_p): Likewise. (build_component_ref): Likewise. (build_indirect_ref): Likewise. (build_conditional_expr): Likewise. (build_static_cast): Likewise. (build_reinterpret_cast): Likewise. (build_const_cast): Likewise. (build_modify_expr): Likewise. (convert_for_assignment): Likewise. (comp_ptr_ttypes_real): Likewise. (ptr_reasonably_similar): Likewise. (comp_ptr_ttypes_const): Likewise. From-SVN: r23490 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 085cb3375a3..b977db5bd29 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,69 @@ +1998-11-01 Mark Mitchell + + * cp-tree.h (COMPARE_STRICT): New macro. + (COMPARE_BASE): Likewise. + (COMPARE_RELAXED): Likewise. + (COMPARE_REDECLARATION): Likewise. + (same_type_p): Likewise. + (same_or_base_type_p): Likewise. + * call.c (standard_conversion): Use them, in place of comptypes + with numeric arguments. + (reference_binding): Likewise. + (convert_like): Likewise. + (build_over_call): Likewise. + (is_subseq): Likewise. + (is_properly_derived_from): Likewise. + (compare_ics): Likewise. + (joust): Likewise. + * class.c (delete_duplicate_fields_1): Likewise. + (resolves_to_fixed_type_p): Likewise. + (instantiate_type): Likewise. Remove #if 0'd code. + * decl.c (decls_match): Likewise. Use COMPARE_REDECLARATION here. + (pushdecl): Likewise. + (lookup_name_real): Likewise. + (grokdeclarator): Likewise. Check for illegal array declarations. + (grokparms): Likewise. + (grok_op_properties): Likewise. + * decl2.c (check_classfn): Likewise. + * friend.c (is_friend): Likewise. + (make_friend_class): Likewise. + * init.c (expand_aggr_init): Likewise. + (expand_vec_init): Likewise. + * pt.c (is_member_template_class): Remove declaration. + (is_specialization_of): Use COMPARE_* and new macros. + (comp_template_parms): Likewise. + (convert_nontype_argument): Likewise. + (coerce_template_template_parms): Likewise. + (template_args_equal): Likewise. + (lookup_template_class): Likewise. + (type_unification_real): Likewise. + (unify): Likewise. + (get_bindings_real): Likewise. + * search.c (covariant_return_p): Likewise. + (get_matching_virtual): Likewise. + * sig.c (match_method_types): Likewise. + * tree.c (vec_binfo_member): Likewise. + (cp_tree_equal): Likewise. + * typeck.c (common_type): Likewise. + (comp_array_types): Likewise. Get issues involving unknown array + bounds right. + (comptypes): Update comments. Use new flags. + (comp_target_types): Use new macros. + (compparms): Likewise. + (comp_target_parms): Likewise. + (string_conv_p): Likewise. + (build_component_ref): Likewise. + (build_indirect_ref): Likewise. + (build_conditional_expr): Likewise. + (build_static_cast): Likewise. + (build_reinterpret_cast): Likewise. + (build_const_cast): Likewise. + (build_modify_expr): Likewise. + (convert_for_assignment): Likewise. + (comp_ptr_ttypes_real): Likewise. + (ptr_reasonably_similar): Likewise. + (comp_ptr_ttypes_const): Likewise. + 1998-10-31 Jason Merrill * rtti.c (build_dynamic_cast_1): Fix cut-and-paste error. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 37847845b37..58914e32b66 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -845,8 +845,8 @@ standard_conversion (to, from, expr) enum tree_code ufcode = TREE_CODE (TREE_TYPE (from)); enum tree_code utcode = TREE_CODE (TREE_TYPE (to)); - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (from)), - TYPE_MAIN_VARIANT (TREE_TYPE (to)), 1)) + if (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (from)), + TYPE_MAIN_VARIANT (TREE_TYPE (to)))) ; else if (utcode == VOID_TYPE && ufcode != OFFSET_TYPE && ufcode != FUNCTION_TYPE) @@ -862,9 +862,9 @@ standard_conversion (to, from, expr) tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to)); if (DERIVED_FROM_P (fbase, tbase) - && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))), - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to))), - 1))) + && (same_type_p + (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))), + TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to)))))) { from = build_offset_type (tbase, TREE_TYPE (TREE_TYPE (from))); from = build_pointer_type (from); @@ -884,7 +884,7 @@ standard_conversion (to, from, expr) } } - if (comptypes (from, to, 1)) + if (same_type_p (from, to)) /* OK */; else if (comp_ptr_ttypes (TREE_TYPE (to), TREE_TYPE (from))) conv = build_conv (QUAL_CONV, to, conv); @@ -909,7 +909,7 @@ standard_conversion (to, from, expr) tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn))); if (! DERIVED_FROM_P (fbase, tbase) - || ! comptypes (TREE_TYPE (fromfn), TREE_TYPE (tofn), 1) + || ! same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn)) || ! compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)), TREE_CHAIN (TYPE_ARG_TYPES (tofn))) || CP_TYPE_QUALS (fbase) != CP_TYPE_QUALS (tbase)) @@ -990,8 +990,8 @@ reference_binding (rto, rfrom, expr, flags) else if (! expr || ! real_lvalue_p (expr)) lvalue = 0; - related = (comptypes (TYPE_MAIN_VARIANT (to), - TYPE_MAIN_VARIANT (from), 1) + related = (same_type_p (TYPE_MAIN_VARIANT (to), + TYPE_MAIN_VARIANT (from)) || (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from) && DERIVED_FROM_P (to, from))); @@ -999,8 +999,8 @@ reference_binding (rto, rfrom, expr, flags) { conv = build1 (IDENTITY_CONV, from, expr); - if (comptypes (TYPE_MAIN_VARIANT (to), - TYPE_MAIN_VARIANT (from), 1)) + if (same_type_p (TYPE_MAIN_VARIANT (to), + TYPE_MAIN_VARIANT (from))) conv = build_conv (REF_BIND, rto, conv); else { @@ -3099,7 +3099,7 @@ convert_like (convs, expr) destination type takes a pointer argument. */ if (TYPE_SIZE (TREE_TYPE (expr)) == 0) { - if (comptypes (TREE_TYPE (expr), TREE_TYPE (convs), 1)) + if (same_type_p (TREE_TYPE (expr), TREE_TYPE (convs))) incomplete_type_error (expr, TREE_TYPE (expr)); else cp_error ("could not convert `%E' (with incomplete type `%T') to `%T'", @@ -3369,8 +3369,8 @@ build_over_call (cand, args, flags) if (TREE_CODE (targ) == ADDR_EXPR) { targ = TREE_OPERAND (targ, 0); - if (! comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg))), - TYPE_MAIN_VARIANT (TREE_TYPE (targ)), 1)) + if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg))), + TYPE_MAIN_VARIANT (TREE_TYPE (targ)))) targ = NULL_TREE; } else @@ -3713,9 +3713,9 @@ is_subseq (ics1, ics2) ics2 = TREE_OPERAND (ics2, 0); if (TREE_CODE (ics2) == TREE_CODE (ics1) - && comptypes (TREE_TYPE (ics2), TREE_TYPE (ics1), 1) - && comptypes (TREE_TYPE (TREE_OPERAND (ics2, 0)), - TREE_TYPE (TREE_OPERAND (ics1, 0)), 1)) + && same_type_p (TREE_TYPE (ics2), TREE_TYPE (ics1)) + && same_type_p (TREE_TYPE (TREE_OPERAND (ics2, 0)), + TREE_TYPE (TREE_OPERAND (ics1, 0)))) return 1; } } @@ -3734,8 +3734,8 @@ is_properly_derived_from (derived, base) /* We only allow proper derivation here. The DERIVED_FROM_P macro considers every class derived from itself. */ - return (!comptypes (TYPE_MAIN_VARIANT (derived), - TYPE_MAIN_VARIANT (base), 1) + return (!same_type_p (TYPE_MAIN_VARIANT (derived), + TYPE_MAIN_VARIANT (base)) && DERIVED_FROM_P (base, derived)); } @@ -3948,7 +3948,7 @@ compare_ics (ics1, ics2) from_type2 = TREE_TYPE (from_type2); } - if (comptypes (from_type1, from_type2, 1)) + if (same_type_p (from_type1, from_type2)) { if (is_subseq (ics1, ics2)) return 1; @@ -4048,7 +4048,7 @@ compare_ics (ics1, ics2) else if (TREE_CODE (deref_to_type1) == VOID_TYPE || TREE_CODE (deref_to_type2) == VOID_TYPE) { - if (comptypes (deref_from_type1, deref_from_type2, 1)) + if (same_type_p (deref_from_type1, deref_from_type2)) { if (TREE_CODE (deref_to_type2) == VOID_TYPE) { @@ -4075,7 +4075,7 @@ compare_ics (ics1, ics2) --conversion of B* to A* is better than conversion of C* to A* */ - if (comptypes (deref_from_type1, deref_from_type2, 1)) + if (same_type_p (deref_from_type1, deref_from_type2)) { if (is_properly_derived_from (deref_to_type1, deref_to_type2)) @@ -4084,7 +4084,7 @@ compare_ics (ics1, ics2) deref_to_type1)) return -1; } - else if (comptypes (deref_to_type1, deref_to_type2, 1)) + else if (same_type_p (deref_to_type1, deref_to_type2)) { if (is_properly_derived_from (deref_from_type2, deref_from_type1)) @@ -4096,7 +4096,7 @@ compare_ics (ics1, ics2) } } else if (IS_AGGR_TYPE_CODE (TREE_CODE (from_type1)) - && comptypes (from_type1, from_type2, 1)) + && same_type_p (from_type1, from_type2)) { /* [over.ics.rank] @@ -4115,7 +4115,7 @@ compare_ics (ics1, ics2) } } else if (IS_AGGR_TYPE_CODE (TREE_CODE (to_type1)) - && comptypes (to_type1, to_type2, 1)) + && same_type_p (to_type1, to_type2)) { /* [over.ics.rank] @@ -4142,7 +4142,7 @@ compare_ics (ics1, ics2) qualification signature of type T2 */ if (TREE_CODE (ics1) == QUAL_CONV && TREE_CODE (ics2) == QUAL_CONV - && comptypes (from_type1, from_type2, 1)) + && same_type_p (from_type1, from_type2)) return comp_cv_qual_signature (to_type1, to_type2); /* [over.ics.rank] @@ -4154,8 +4154,8 @@ compare_ics (ics1, ics2) which the reference initialized by S1 refers */ if (ref_binding1 && ref_binding2 - && comptypes (TYPE_MAIN_VARIANT (to_type1), - TYPE_MAIN_VARIANT (to_type2), 1)) + && same_type_p (TYPE_MAIN_VARIANT (to_type1), + TYPE_MAIN_VARIANT (to_type2))) return comp_cv_qualification (target_type2, target_type1); /* Neither conversion sequence is better than the other. */ @@ -4298,8 +4298,8 @@ joust (cand1, cand2, warn) != DECL_CONSTRUCTOR_P (cand2->fn)) /* Don't warn if the two conv ops convert to the same type... */ || (! DECL_CONSTRUCTOR_P (cand1->fn) - && ! comptypes (TREE_TYPE (cand1->second_conv), - TREE_TYPE (cand2->second_conv), 1)))) + && ! same_type_p (TREE_TYPE (cand1->second_conv), + TREE_TYPE (cand2->second_conv))))) { int comp = compare_ics (cand1->second_conv, cand2->second_conv); if (comp != winner) @@ -4355,8 +4355,8 @@ joust (cand1, cand2, warn) && TREE_CODE (cand1->fn) == IDENTIFIER_NODE) { for (i = 0; i < len; ++i) - if (! comptypes (TREE_TYPE (TREE_VEC_ELT (cand1->convs, i)), - TREE_TYPE (TREE_VEC_ELT (cand2->convs, i)), 1)) + if (!same_type_p (TREE_TYPE (TREE_VEC_ELT (cand1->convs, i)), + TREE_TYPE (TREE_VEC_ELT (cand2->convs, i)))) break; if (i == TREE_VEC_LENGTH (cand1->convs)) return 1; @@ -4371,7 +4371,7 @@ joust (cand1, cand2, warn) tree t1 = strip_top_quals (non_reference (TREE_TYPE (c1))); tree t2 = strip_top_quals (non_reference (TREE_TYPE (c2))); - if (comptypes (t1, t2, 1)) + if (same_type_p (t1, t2)) { if (TREE_CODE (c1) == REF_BIND && TREE_CODE (c2) != REF_BIND) return 1; diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 3cd89a6872d..1fd492f5fbe 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1351,7 +1351,7 @@ delete_duplicate_fields_1 (field, fields) else if (DECL_DECLARES_TYPE_P (field) && DECL_DECLARES_TYPE_P (x)) { - if (comptypes (TREE_TYPE (field), TREE_TYPE (x), 1)) + if (same_type_p (TREE_TYPE (field), TREE_TYPE (x))) continue; cp_error_at ("duplicate nested type `%D'", x); } @@ -4592,7 +4592,7 @@ resolves_to_fixed_type_p (instance, nonnull) return 0; if (POINTER_TYPE_P (t)) t = TREE_TYPE (t); - return comptypes (TYPE_MAIN_VARIANT (t), TYPE_MAIN_VARIANT (fixed), 1); + return same_type_p (TYPE_MAIN_VARIANT (t), TYPE_MAIN_VARIANT (fixed)); } @@ -4981,7 +4981,7 @@ instantiate_type (lhstype, rhs, complain) if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs))) { - if (comptypes (lhstype, TREE_TYPE (rhs), 1)) + if (same_type_p (lhstype, TREE_TYPE (rhs))) return rhs; if (complain) cp_error ("argument of type `%T' does not match `%T'", @@ -5049,48 +5049,6 @@ instantiate_type (lhstype, rhs, complain) /* I could not trigger this code. MvL */ my_friendly_abort (980326); -#if 0 - my_friendly_assert (TREE_CODE (field) == FIELD_DECL, 178); - my_friendly_assert (!(TREE_CODE (TREE_TYPE (field)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (field)) == METHOD_TYPE), - 179); - - TREE_TYPE (rhs) = lhstype; - /* First look for an exact match */ - - while (field && TREE_TYPE (field) != lhstype) - field = DECL_CHAIN (field); - if (field) - { - TREE_OPERAND (rhs, 1) = field; - mark_used (field); - return rhs; - } - - /* No exact match found, look for a compatible function. */ - field = TREE_OPERAND (rhs, 1); - while (field && ! comptypes (lhstype, TREE_TYPE (field), 0)) - field = DECL_CHAIN (field); - if (field) - { - TREE_OPERAND (rhs, 1) = field; - field = DECL_CHAIN (field); - while (field && ! comptypes (lhstype, TREE_TYPE (field), 0)) - field = DECL_CHAIN (field); - if (field) - { - if (complain) - error ("ambiguous overload for COMPONENT_REF requested"); - return error_mark_node; - } - } - else - { - if (complain) - error ("no appropriate overload exists for COMPONENT_REF"); - return error_mark_node; - } -#endif return rhs; } @@ -5141,7 +5099,7 @@ instantiate_type (lhstype, rhs, complain) { elem = OVL_FUNCTION (elems); if (TREE_CODE (elem) == FUNCTION_DECL - && comptypes (lhstype, TREE_TYPE (elem), 1)) + && same_type_p (lhstype, TREE_TYPE (elem))) { mark_used (elem); return elem; @@ -5174,8 +5132,8 @@ instantiate_type (lhstype, rhs, complain) } save_elem = instantiate_template (elem, t); /* Check the return type. */ - if (! comptypes (TREE_TYPE (lhstype), - TREE_TYPE (TREE_TYPE (save_elem)), 1)) + if (!same_type_p (TREE_TYPE (lhstype), + TREE_TYPE (TREE_TYPE (save_elem)))) save_elem = 0; } } @@ -5274,7 +5232,7 @@ instantiate_type (lhstype, rhs, complain) { elem = TREE_VALUE (baselink); while (elem) - if (comptypes (lhstype, TREE_TYPE (OVL_CURRENT (elem)), 1)) + if (same_type_p (lhstype, TREE_TYPE (OVL_CURRENT (elem)))) { mark_used (OVL_CURRENT (elem)); return OVL_CURRENT (elem); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7c412734196..aee859a7008 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2431,9 +2431,38 @@ extern tree current_class_name; /* IDENTIFIER_NODE: name of current class */ #define WANT_ENUM 4 /* enumerated types */ #define WANT_POINTER 8 /* pointer types */ #define WANT_NULL 16 /* null pointer constant */ - #define WANT_ARITH (WANT_INT | WANT_FLOAT) +/* Used with comptypes, and related functions, to guide type + comparison. */ + +#define COMPARE_STRICT 0 /* Just check if the types are the + same. */ +#define COMPARE_BASE 1 /* Check to see if the second type is + derived from the first, or if both + are pointers (or references) and + the types pointed to by the second + type is derived from the pointed to + by the first. */ +#define COMPARE_RELAXED 2 /* Like COMPARE_DERIVED, but in + reverse. Also treat enmeration + types as the same as integer types + of the same width. */ +#define COMPARE_REDECLARATION 4 /* The comparsion is being done when + another declaration of an existing + entity is seen. */ + +/* Returns nonzero iff TYPE1 and TYPE2 are the same type, in the usual + sense of `same'. */ +#define same_type_p(type1, type2) \ + comptypes ((type1), (type2), COMPARE_STRICT) + +/* Returns nonzero iff TYPE1 and TYPE2 are the same type, or if TYPE2 + is derived from TYPE1, or if TYPE2 is a pointer (reference) to a + class derived from the type pointed to (referred to) by TYPE1. */ +#define same_or_base_type_p(type1, type2) \ + comptypes ((type1), (type2), COMPARE_BASE) + #define FRIEND_NAME(LIST) (TREE_PURPOSE (LIST)) #define FRIEND_DECLS(LIST) (TREE_VALUE (LIST)) diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 30fb33479fe..84d3c6796ab 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -487,7 +487,8 @@ convert_to_reference (reftype, expr, convtype, flags, decl) /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they meant. */ if (TREE_CODE (intype) == POINTER_TYPE - && (comptypes (TREE_TYPE (intype), type, -1))) + && (comptypes (TREE_TYPE (intype), type, + COMPARE_BASE | COMPARE_RELAXED ))) cp_warning ("casting `%T' to `%T' does not dereference pointer", intype, reftype); @@ -669,7 +670,7 @@ ocp_convert (type, expr, convtype, flags) /* We need a new temporary; don't take this shortcut. */; else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e))) { - if (comptypes (type, TREE_TYPE (e), 1)) + if (same_type_p (type, TREE_TYPE (e))) /* The call to fold will not always remove the NOP_EXPR as might be expected, since if one of the types is a typedef; the comparsion in fold is just equality of pointers, not a diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6e0a409dd44..394984fa3a3 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2552,7 +2552,7 @@ decls_match (newdecl, olddecl) return 0; } - if (comptypes (TREE_TYPE (f1), TREE_TYPE (f2), 1)) + if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2))) { if (! strict_prototypes_lang_c && DECL_LANGUAGE (olddecl) == lang_c && p2 == NULL_TREE) @@ -2595,7 +2595,8 @@ decls_match (newdecl, olddecl) types_match = 0; else types_match = comptypes (TREE_TYPE (newdecl), - TREE_TYPE (olddecl), 1); + TREE_TYPE (olddecl), + COMPARE_REDECLARATION); } return types_match; @@ -3527,7 +3528,7 @@ pushdecl (x) if (decl /* If different sort of thing, we already gave an error. */ && TREE_CODE (decl) == TREE_CODE (x) - && ! comptypes (TREE_TYPE (x), TREE_TYPE (decl), 1)) + && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl))) { cp_pedwarn ("type mismatch with previous external decl", x); cp_pedwarn_at ("previous external decl of `%#D'", decl); @@ -4115,7 +4116,7 @@ redeclaration_error_message (newdecl, olddecl) /* Because C++ can put things into name space for free, constructs like "typedef struct foo { ... } foo" would look like an erroneous redeclaration. */ - if (comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl), 0)) + if (same_type_p (TREE_TYPE (newdecl), TREE_TYPE (olddecl))) return 0; else return "redefinition of `%#D'"; @@ -5241,7 +5242,7 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only) && CLASSTYPE_TEMPLATE_INFO (subtype) && CLASSTYPE_TI_TEMPLATE (subtype) == locval) && ! (TREE_CODE (locval) == TYPE_DECL - && comptypes (TREE_TYPE (locval), subtype, 1))) + && same_type_p (TREE_TYPE (locval), subtype))) { cp_warning ("lookup of `%D' finds `%#D'", name, locval); cp_warning (" instead of `%D' from dependent base class", @@ -9054,7 +9055,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) } else if (return_type == return_conversion) { - if (comptypes (type, ctor_return_type, 1) == 0) + if (!same_type_p (type, ctor_return_type)) cp_error ("operator `%T' declared to return `%T'", ctor_return_type, type); else @@ -9536,6 +9537,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) if (size == error_mark_node) type = error_mark_node; + else if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)) + { + /* [dcl.array] + + the constant expressions that specify the bounds of + the arrays can be omitted only for the first member + of the sequence. */ + cp_error ("declaration of `%D' as multidimensional array", + dname); + cp_error ("must have bounds for all dimensions except the first"); + type = error_mark_node; + } if (type == error_mark_node) continue; @@ -11023,7 +11036,7 @@ grokparms (first_parm, funcdef_flag) TREE_PURPOSE (decl), PARM, init != NULL_TREE, NULL_TREE); - if (! decl) + if (! decl || TREE_TYPE (decl) == error_mark_node) continue; /* Top-level qualifiers on the parameters are @@ -11525,14 +11538,14 @@ grok_op_properties (decl, virtualp, friendp) if (list_length (argtypes) == 2) { if (TREE_CODE (ret) != REFERENCE_TYPE - || !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ret)), - arg, 1)) + || !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)), + arg)) cp_warning ("prefix `%D' should return `%T'", decl, build_reference_type (arg)); } else { - if (!comptypes (TYPE_MAIN_VARIANT (ret), arg, 1)) + if (!same_type_p (TYPE_MAIN_VARIANT (ret), arg)) cp_warning ("postfix `%D' should return `%T'", decl, arg); } } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index cd7d515f33b..7b0ba6d7117 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1406,8 +1406,8 @@ check_classfn (ctype, function) && TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE) p1 = TREE_CHAIN (p1); - if (comptypes (TREE_TYPE (TREE_TYPE (function)), - TREE_TYPE (TREE_TYPE (fndecl)), 1) + if (same_type_p (TREE_TYPE (TREE_TYPE (function)), + TREE_TYPE (TREE_TYPE (fndecl))) && compparms (p1, p2) && (DECL_TEMPLATE_SPECIALIZATION (function) == DECL_TEMPLATE_SPECIALIZATION (fndecl)) diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index c98fd4e2d5f..81b67a56d5a 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -64,7 +64,7 @@ is_friend (type, supplicant) tree friends = TREE_VALUE (list); for (; friends ; friends = TREE_CHAIN (friends)) { - if (comptypes (ctype, TREE_PURPOSE (friends), 1)) + if (same_type_p (ctype, TREE_PURPOSE (friends))) return 1; if (TREE_VALUE (friends) == NULL_TREE) @@ -86,8 +86,8 @@ is_friend (type, supplicant) FUNCTION_MEMBER_P bit can go. */ if ((flag_guiding_decls || DECL_FUNCTION_MEMBER_P (supplicant)) - && comptypes (TREE_TYPE (supplicant), - TREE_TYPE (TREE_VALUE (friends)), 1)) + && same_type_p (TREE_TYPE (supplicant), + TREE_TYPE (TREE_VALUE (friends)))) return 1; if (TREE_CODE (TREE_VALUE (friends)) == TEMPLATE_DECL @@ -112,7 +112,7 @@ is_friend (type, supplicant) if (TREE_CODE (t) == TEMPLATE_DECL ? is_specialization_of (TYPE_MAIN_DECL (supplicant), t) : - comptypes (supplicant, t, 1)) + same_type_p (supplicant, t)) return 1; } } @@ -278,7 +278,7 @@ make_friend_class (type, friend_type) friends with itself; this means that each instantiation is friends with all other instantiations. */ is_template_friend = 1; - else if (comptypes (type, friend_type, 1)) + else if (same_type_p (type, friend_type)) { pedwarn ("class `%s' is implicitly friends with itself", TYPE_NAME_STRING (type)); @@ -297,7 +297,7 @@ make_friend_class (type, friend_type) /* Stop if we find the same type on the list. */ && !(TREE_CODE (TREE_VALUE (classes)) == TEMPLATE_DECL ? friend_type == TREE_VALUE (classes) : - comptypes (TREE_VALUE (classes), friend_type, 1))) + same_type_p (TREE_VALUE (classes), friend_type))) classes = TREE_CHAIN (classes); if (classes) cp_warning ("`%T' is already a friend of `%T'", diff --git a/gcc/cp/init.c b/gcc/cp/init.c index fe1272e0ab4..dbf53a31155 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1082,7 +1082,8 @@ expand_aggr_init (exp, init, flags) return; } expand_vec_init (exp, exp, array_type_nelts (type), init, - init && comptypes (TREE_TYPE (init), TREE_TYPE (exp), 1)); + init && same_type_p (TREE_TYPE (init), + TREE_TYPE (exp))); TREE_READONLY (exp) = was_const; TREE_THIS_VOLATILE (exp) = was_volatile; TREE_TYPE (exp) = type; @@ -2784,8 +2785,7 @@ expand_vec_init (decl, base, maxindex, init, from_array) expand_vec_init_try_block (type); if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR - && (!decl || comptypes (TREE_TYPE (init), - TREE_TYPE (decl), 1))) + && (!decl || same_type_p (TREE_TYPE (init), TREE_TYPE (decl)))) { /* Do non-default initialization resulting from brace-enclosed initializers. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a8b2e8f88b3..d4bdf82b40f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -124,7 +124,6 @@ static int check_cv_quals_for_unify PROTO((int, tree, tree)); static tree tsubst_template_arg_vector PROTO((tree, tree)); static tree tsubst_template_parms PROTO((tree, tree)); static void regenerate_decl_from_template PROTO((tree, tree)); -static int is_member_template_class PROTO((tree)); static tree most_specialized PROTO((tree, tree, tree)); static tree most_specialized_class PROTO((tree, tree)); static tree most_general_template PROTO((tree)); @@ -750,8 +749,8 @@ is_specialization_of (decl, tmpl) t != NULL_TREE; t = CLASSTYPE_USE_TEMPLATE (t) ? TREE_TYPE (CLASSTYPE_TI_TEMPLATE (t)) : NULL_TREE) - if (comptypes (TYPE_MAIN_VARIANT (t), - TYPE_MAIN_VARIANT (TREE_TYPE (tmpl)), 1)) + if (same_type_p (TYPE_MAIN_VARIANT (t), + TYPE_MAIN_VARIANT (TREE_TYPE (tmpl)))) return 1; } @@ -1464,8 +1463,7 @@ int comp_template_parms (parms1, parms2) if (TREE_CODE (parm1) == TEMPLATE_TYPE_PARM) continue; - else if (!comptypes (TREE_TYPE (parm1), - TREE_TYPE (parm2), 1)) + else if (!same_type_p (TREE_TYPE (parm1), TREE_TYPE (parm2))) return 0; } } @@ -2555,7 +2553,7 @@ convert_nontype_argument (type, expr) expr = build_unary_op (ADDR_EXPR, fn, 0); - my_friendly_assert (comptypes (type, TREE_TYPE (expr), 1), + my_friendly_assert (same_type_p (type, TREE_TYPE (expr)), 0); return expr; } @@ -2613,7 +2611,8 @@ convert_nontype_argument (type, expr) goto bad_argument; } - my_friendly_assert (comptypes (type_referred_to, TREE_TYPE (fn), 1), + my_friendly_assert (same_type_p (type_referred_to, + TREE_TYPE (fn)), 0); return fn; @@ -2626,8 +2625,8 @@ convert_nontype_argument (type, expr) identical) type of the template-argument. The template-parameter is bound directly to the template-argument, which must be an lvalue. */ - if (!comptypes (TYPE_MAIN_VARIANT (expr_type), - TYPE_MAIN_VARIANT (type), 1) + if (!same_type_p (TYPE_MAIN_VARIANT (expr_type), + TYPE_MAIN_VARIANT (type)) || !at_least_as_qualified_p (type_referred_to, expr_type) || !real_lvalue_p (expr)) @@ -2664,7 +2663,7 @@ convert_nontype_argument (type, expr) if (TREE_CODE (expr) == CONSTRUCTOR) { /* A ptr-to-member constant. */ - if (!comptypes (type, expr_type, 1)) + if (!same_type_p (type, expr_type)) return error_mark_node; else return expr; @@ -2683,7 +2682,7 @@ convert_nontype_argument (type, expr) expr = build_unary_op (ADDR_EXPR, fn, 0); - my_friendly_assert (comptypes (type, TREE_TYPE (expr), 1), + my_friendly_assert (same_type_p (type, TREE_TYPE (expr)), 0); return expr; } @@ -2762,8 +2761,8 @@ coerce_template_template_parms (parm_parms, arg_parms, in_decl, outer_args) /* The tsubst call is used to handle cases such as template class TT> class D; i.e. the parameter list of TT depends on earlier parameters. */ - if (!comptypes (tsubst (TREE_TYPE (parm), outer_args, in_decl), - TREE_TYPE (arg), 1)) + if (!same_type_p (tsubst (TREE_TYPE (parm), outer_args, in_decl), + TREE_TYPE (arg))) return 0; break; @@ -3089,7 +3088,7 @@ template_args_equal (ot, nt) /* For member templates */ return comp_template_args (ot, nt); else if (TREE_CODE_CLASS (TREE_CODE (ot)) == 't') - return comptypes (ot, nt, 1); + return same_type_p (ot, nt); else return (cp_tree_equal (ot, nt) > 0); } @@ -3540,7 +3539,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) ctx; ctx = (TREE_CODE_CLASS (TREE_CODE (ctx)) == 't') ? TYPE_CONTEXT (ctx) : DECL_CONTEXT (ctx)) - if (comptypes (ctx, template_type, 1)) + if (same_type_p (ctx, template_type)) break; if (!ctx) @@ -6859,7 +6858,7 @@ type_unification_real (tparms, targs, parms, args, subr, if (strict == DEDUCE_EXACT) { - if (comptypes (parm, type, 1)) + if (same_type_p (parm, type)) continue; } else @@ -7187,7 +7186,7 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) /* The PARM is not one we're trying to unify. Just check to see if it matches ARG. */ return (TREE_CODE (arg) == TREE_CODE (parm) - && comptypes (parm, arg, 1)) ? 0 : 1; + && same_type_p (parm, arg)) ? 0 : 1; idx = TEMPLATE_TYPE_IDX (parm); targ = TREE_VEC_ELT (targs, idx); tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx)); @@ -7276,7 +7275,7 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) /* Simple cases: Value already set, does match or doesn't. */ if (targ != NULL_TREE - && (comptypes (targ, arg, 1) + && (same_type_p (targ, arg) || (explicit_mask && explicit_mask[idx]))) return 0; else if (targ) @@ -7391,8 +7390,8 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) /* We use the TYPE_MAIN_VARIANT since we have already checked cv-qualification at the top of the function. */ - else if (!comptypes (TYPE_MAIN_VARIANT (arg), - TYPE_MAIN_VARIANT (parm), 1)) + else if (!same_type_p (TYPE_MAIN_VARIANT (arg), + TYPE_MAIN_VARIANT (parm))) return 1; /* As far as unification is concerned, this wins. Later checks @@ -7462,8 +7461,8 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) CLASSTYPE_TI_ARGS (t), UNIFY_ALLOW_NONE, explicit_mask); } - else if (!comptypes (TYPE_MAIN_VARIANT (parm), - TYPE_MAIN_VARIANT (arg), 1)) + else if (!same_type_p (TYPE_MAIN_VARIANT (parm), + TYPE_MAIN_VARIANT (arg))) return 1; return 0; @@ -7692,7 +7691,7 @@ get_bindings_real (fn, decl, explicit_args, check_rettype) tree t = tsubst (TREE_TYPE (TREE_TYPE (fn)), targs, NULL_TREE); - if (!comptypes (t, TREE_TYPE (TREE_TYPE (decl)), 1)) + if (!same_type_p (t, TREE_TYPE (TREE_TYPE (decl)))) return NULL_TREE; } diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 71298edea15..d9d945fe381 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1740,7 +1740,7 @@ covariant_return_p (brettype, drettype) drettype = TREE_TYPE (drettype); } - if (comptypes (brettype, drettype, 1)) + if (same_type_p (brettype, drettype)) return 0; if (! (TREE_CODE (brettype) == TREE_CODE (drettype) @@ -1850,7 +1850,7 @@ get_matching_virtual (binfo, fndecl, dtorp) && compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes))) { tree brettype = TREE_TYPE (TREE_TYPE (tmp)); - if (comptypes (brettype, drettype, 1)) + if (same_type_p (brettype, drettype)) /* OK */; else if ((i = covariant_return_p (brettype, drettype))) { @@ -1864,7 +1864,7 @@ get_matching_virtual (binfo, fndecl, dtorp) } } else if (IS_AGGR_TYPE_2 (brettype, drettype) - && comptypes (brettype, drettype, 0)) + && same_or_base_type_p (brettype, drettype)) { error ("invalid covariant return type (must use pointer or reference)"); cp_error_at (" overriding `%#D'", tmp); diff --git a/gcc/cp/sig.c b/gcc/cp/sig.c index 9a7b57f1ddd..00ba77076bc 100644 --- a/gcc/cp/sig.c +++ b/gcc/cp/sig.c @@ -408,7 +408,7 @@ match_method_types (sig_mtype, class_mtype) tree class_arg_types = TYPE_ARG_TYPES (class_mtype); /* The return types have to be the same. */ - if (! comptypes (sig_return_type, class_return_type, 1)) + if (!same_type_p (sig_return_type, class_return_type)) return 0; /* Compare the first argument `this.' */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 28e0d1c3e51..2a9b5228425 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2314,7 +2314,7 @@ vec_binfo_member (elem, vec) if (vec) for (i = 0; i < TREE_VEC_LENGTH (vec); ++i) - if (comptypes (elem, BINFO_TYPE (TREE_VEC_ELT (vec, i)), 1)) + if (same_type_p (elem, BINFO_TYPE (TREE_VEC_ELT (vec, i)))) return TREE_VEC_ELT (vec, i); return NULL_TREE; @@ -2387,7 +2387,7 @@ cp_tree_equal (t1, t2) /* We need to do this when determining whether or not two non-type pointer to member function template arguments are the same. */ - if (!(comptypes (TREE_TYPE (t1), TREE_TYPE (t2), 1) + if (!(same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) /* The first operand is RTL. */ && TREE_OPERAND (t1, 0) == TREE_OPERAND (t2, 0))) return 0; @@ -2455,15 +2455,14 @@ cp_tree_equal (t1, t2) if (TREE_CODE (TREE_OPERAND (t1, 0)) != TREE_CODE (TREE_OPERAND (t2, 0))) return 0; if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t1, 0))) == 't') - return comptypes (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0), 1); + return same_type_p (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); break; case PTRMEM_CST: /* Two pointer-to-members are the same if they point to the same field or function in the same class. */ return (PTRMEM_CST_MEMBER (t1) == PTRMEM_CST_MEMBER (t2) - && comptypes (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2), - 1)); + && same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2))); default: break; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 1e391ea79e1..1322078b3bc 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -576,7 +576,7 @@ common_type (t1, t2) tree b1 = TYPE_OFFSET_BASETYPE (t1); tree b2 = TYPE_OFFSET_BASETYPE (t2); - if (comptypes (b1, b2, 1) + if (same_type_p (b1, b2) || (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2))) basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2))); else @@ -611,7 +611,7 @@ common_type (t1, t2) tree b1 = TYPE_OFFSET_BASETYPE (t1); tree b2 = TYPE_OFFSET_BASETYPE (t2); - if (comptypes (b1, b2, 1) + if (same_type_p (b1, b2) || (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2))) return build_type_attribute_variant (t2, attributes); else if (binfo_or_else (b2, b1)) @@ -633,61 +633,58 @@ compexcepttypes (t1, t2) return TYPE_RAISES_EXCEPTIONS (t1) == TYPE_RAISES_EXCEPTIONS (t2); } +/* Compare the array types T1 and T2, using CMP as the type comparison + function for the element types. STRICT is as for comptypes. */ + static int comp_array_types (cmp, t1, t2, strict) register int (*cmp) PROTO((tree, tree, int)); tree t1, t2; int strict; { - tree d1 = TYPE_DOMAIN (t1); - tree d2 = TYPE_DOMAIN (t2); + tree d1; + tree d2; + + if (t1 == t2) + return 1; - /* Target types must match incl. qualifiers. */ + /* The type of the array elements must be the same. */ if (!(TREE_TYPE (t1) == TREE_TYPE (t2) - || (*cmp) (TREE_TYPE (t1), TREE_TYPE (t2), strict))) + || (*cmp) (TREE_TYPE (t1), TREE_TYPE (t2), + strict & ~COMPARE_REDECLARATION))) return 0; - /* Sizes must match unless one is missing or variable. */ - if (d1 == 0 || d2 == 0 || d1 == d2 - || TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST - || TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST - || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST - || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST) + d1 = TYPE_DOMAIN (t1); + d2 = TYPE_DOMAIN (t2); + + if (d1 == d2) return 1; - return ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1)) - == TREE_INT_CST_LOW (TYPE_MIN_VALUE (d2))) - && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d1)) - == TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d2))) - && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (d1)) - == TREE_INT_CST_LOW (TYPE_MAX_VALUE (d2))) - && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d1)) - == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2)))); + /* If one of the arrays is dimensionless, and the other has a + dimension, they are of different types. However, it is legal to + write: + + extern int a[]; + int a[3]; + + by [basic.link]: + + declarations for an array object can specify + array types that differ by the presence or absence of a major + array bound (_dcl.array_). */ + if (!d1 || !d2) + return strict & COMPARE_REDECLARATION; + + /* Check that the dimensions are the same. */ + return (cp_tree_equal (TYPE_MIN_VALUE (d1), + TYPE_MIN_VALUE (d2)) + && cp_tree_equal (TYPE_MAX_VALUE (d1), + TYPE_MAX_VALUE (d2))); } /* Return 1 if TYPE1 and TYPE2 are compatible types for assignment - or various other operations. This is what ANSI C++ speaks of as - "being the same". - - For C++: argument STRICT says we should be strict about this - comparison: - - 2 : strict, except that if one type is a reference and - the other is not, compare the target type of the - reference to the type that's not a reference (ARM, p308). - This is used for checking for invalid overloading. - 1 : strict (compared according to ANSI C) - This is used for checking whether two function decls match. - 0 : <= (compared according to C++) - -1: <= or >= (relaxed) - - Otherwise, pointers involving base classes and derived classes can - be mixed as valid: i.e. a pointer to a derived class may be converted - to a pointer to one of its base classes, as per C++. A pointer to - a derived class may be passed as a parameter to a function expecting a - pointer to a base classes. These allowances do not commute. In this - case, TYPE1 is assumed to be the base class, and TYPE2 is assumed to - be the derived class. */ + or various other operations. STRICT is a bitwise-or of the + COMPARE_* flags. */ int comptypes (type1, type2, strict) @@ -697,9 +694,18 @@ comptypes (type1, type2, strict) register tree t1 = type1; register tree t2 = type2; int attrval, val; + int orig_strict = strict; - /* Suppress errors caused by previously reported errors */ + /* The special exemption for redeclaring array types without an + array bound only applies at the top level: + + extern int (*i)[]; + int (*i)[8]; + + is not legal, for example. */ + strict &= ~COMPARE_REDECLARATION; + /* Suppress errors caused by previously reported errors */ if (t1 == t2) return 1; @@ -709,7 +715,7 @@ comptypes (type1, type2, strict) if (t2 == error_mark_node) return 0; - if (strict < 0) + if (strict & COMPARE_RELAXED) { /* Treat an enum type as the unsigned integer type of the same width. */ @@ -728,28 +734,14 @@ comptypes (type1, type2, strict) t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2); /* Different classes of types can't be compatible. */ - if (TREE_CODE (t1) != TREE_CODE (t2)) - { - if (strict == 2 - && ((TREE_CODE (t1) == REFERENCE_TYPE) - ^ (TREE_CODE (t2) == REFERENCE_TYPE))) - { - if (TREE_CODE (t1) == REFERENCE_TYPE) - return comptypes (TREE_TYPE (t1), t2, 1); - return comptypes (t1, TREE_TYPE (t2), 1); - } - - return 0; - } - if (strict > 1) - strict = 1; + return 0; /* Qualifiers must match. */ - if (CP_TYPE_QUALS (t1) != CP_TYPE_QUALS (t2)) return 0; - if (strict > 0 && TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2)) + if (strict == COMPARE_STRICT + && TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2)) return 0; /* Allow for two different type nodes which have essentially the same @@ -784,7 +776,7 @@ comptypes (type1, type2, strict) if (! CLASSTYPE_TEMPLATE_INFO (t1) && ! CLASSTYPE_TEMPLATE_INFO (t2)) return 1; /* Don't check inheritance. */ - strict = 1; + strict = COMPARE_STRICT; /* fall through */ case RECORD_TYPE: @@ -792,11 +784,20 @@ comptypes (type1, type2, strict) if (CLASSTYPE_TEMPLATE_INFO (t1) && CLASSTYPE_TEMPLATE_INFO (t2) && (CLASSTYPE_TI_TEMPLATE (t1) == CLASSTYPE_TI_TEMPLATE (t2) || TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)) - return comp_template_args (CLASSTYPE_TI_ARGS (t1), - CLASSTYPE_TI_ARGS (t2)); - if (strict <= 0) - goto look_hard; - return 0; + val = comp_template_args (CLASSTYPE_TI_ARGS (t1), + CLASSTYPE_TI_ARGS (t2)); + look_hard: + if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2)) + { + val = 1; + break; + } + if ((strict & COMPARE_RELAXED) && DERIVED_FROM_P (t2, t1)) + { + val = 1; + break; + } + break; case OFFSET_TYPE: val = (comptypes (build_pointer_type (TYPE_OFFSET_BASETYPE (t1)), @@ -826,28 +827,9 @@ comptypes (type1, type2, strict) val = comptypes (t1, t2, strict); if (val) break; - /* if they do not, try more relaxed alternatives */ - if (strict <= 0) - { - if (TREE_CODE (t1) == RECORD_TYPE && TREE_CODE (t2) == RECORD_TYPE) - { - int rval; - look_hard: - rval = t1 == t2 || DERIVED_FROM_P (t1, t2); - - if (rval) - { - val = 1; - break; - } - if (strict < 0) - { - val = DERIVED_FROM_P (t2, t1); - break; - } - } - return 0; - } + if (TREE_CODE (t1) == RECORD_TYPE + && TREE_CODE (t2) == RECORD_TYPE) + goto look_hard; break; case FUNCTION_TYPE: @@ -860,8 +842,10 @@ comptypes (type1, type2, strict) break; case ARRAY_TYPE: - /* Target types must match incl. qualifiers. */ - val = comp_array_types (comptypes, t1, t2, strict); + /* Target types must match incl. qualifiers. We use ORIG_STRICT + here since this is the one place where + COMPARE_REDECLARATION should be used. */ + val = comp_array_types (comptypes, t1, t2, orig_strict); break; case TEMPLATE_TYPE_PARM: @@ -871,7 +855,7 @@ comptypes (type1, type2, strict) case TYPENAME_TYPE: if (TYPE_IDENTIFIER (t1) != TYPE_IDENTIFIER (t2)) return 0; - return comptypes (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2), 1); + return same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2)); default: break; @@ -978,7 +962,7 @@ comp_target_types (ttl, ttr, nptrs) } if (TREE_CODE (ttr) == ARRAY_TYPE) - return comp_array_types (comp_target_types, ttl, ttr, 0); + return comp_array_types (comp_target_types, ttl, ttr, COMPARE_STRICT); else if (TREE_CODE (ttr) == FUNCTION_TYPE || TREE_CODE (ttr) == METHOD_TYPE) { tree argsl, argsr; @@ -986,7 +970,7 @@ comp_target_types (ttl, ttr, nptrs) if (pedantic) { - if (comptypes (TREE_TYPE (ttl), TREE_TYPE (ttr), 1) == 0) + if (!same_type_p (TREE_TYPE (ttl), TREE_TYPE (ttr))) return 0; } else @@ -1009,9 +993,9 @@ comp_target_types (ttl, ttr, nptrs) tree tl = TYPE_METHOD_BASETYPE (ttl); tree tr = TYPE_METHOD_BASETYPE (ttr); - if (comptypes (tr, tl, 0) == 0) + if (!same_or_base_type_p (tr, tl)) { - if (comptypes (tl, tr, 0)) + if (same_or_base_type_p (tl, tr)) saw_contra = 1; else return 0; @@ -1039,11 +1023,11 @@ comp_target_types (ttl, ttr, nptrs) /* Contravariance: we can assign a pointer to base member to a pointer to derived member. Note difference from simple pointer case, where we can pass a pointer to derived to a pointer to base. */ - if (comptypes (TYPE_OFFSET_BASETYPE (ttr), - TYPE_OFFSET_BASETYPE (ttl), 0)) + if (same_or_base_type_p (TYPE_OFFSET_BASETYPE (ttr), + TYPE_OFFSET_BASETYPE (ttl))) base = 1; - else if (comptypes (TYPE_OFFSET_BASETYPE (ttl), - TYPE_OFFSET_BASETYPE (ttr), 0)) + else if (same_or_base_type_p (TYPE_OFFSET_BASETYPE (ttl), + TYPE_OFFSET_BASETYPE (ttr))) { tree tmp = ttl; ttl = ttr; @@ -1074,9 +1058,11 @@ comp_target_types (ttl, ttr, nptrs) { if (nptrs < 0) return 0; - if (comptypes (build_pointer_type (ttl), build_pointer_type (ttr), 0)) + if (same_or_base_type_p (build_pointer_type (ttl), + build_pointer_type (ttr))) return 1; - if (comptypes (build_pointer_type (ttr), build_pointer_type (ttl), 0)) + if (same_or_base_type_p (build_pointer_type (ttr), + build_pointer_type (ttl))) return -1; return 0; } @@ -1225,7 +1211,7 @@ compparms (parms1, parms2) they fail to match. */ if (t1 == 0 || t2 == 0) return 0; - if (! comptypes (TREE_VALUE (t2), TREE_VALUE (t1), 1)) + if (!same_type_p (TREE_VALUE (t2), TREE_VALUE (t1))) return 0; t1 = TREE_CHAIN (t1); @@ -1279,7 +1265,7 @@ comp_target_parms (parms1, parms2, strict) } p1 = TREE_VALUE (t1); p2 = TREE_VALUE (t2); - if (comptypes (p1, p2, 1)) + if (same_type_p (p1, p2)) continue; if (pedantic) @@ -1303,12 +1289,10 @@ comp_target_parms (parms1, parms2, strict) warn_contravariance = 1; continue; } - if (IS_AGGR_TYPE (TREE_TYPE (p1))) - { - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (p1)), - TYPE_MAIN_VARIANT (TREE_TYPE (p2)), 1) == 0) - return 0; - } + if (IS_AGGR_TYPE (TREE_TYPE (p1)) + && !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (p1)), + TYPE_MAIN_VARIANT (TREE_TYPE (p2)))) + return 0; } /* Note backwards order due to contravariance. */ if (comp_target_types (p2, p1, 1) <= 0) @@ -1781,14 +1765,14 @@ string_conv_p (totype, exp, warn) return 0; t = TREE_TYPE (totype); - if (! comptypes (t, char_type_node, 1) - && ! comptypes (t, wchar_type_node, 1)) + if (!same_type_p (t, char_type_node) + && !same_type_p (t, wchar_type_node)) return 0; if (TREE_CODE (exp) != STRING_CST) { t = build_pointer_type (build_qualified_type (t, TYPE_QUAL_CONST)); - if (! comptypes (TREE_TYPE (exp), t, 1)) + if (!same_type_p (TREE_TYPE (exp), t)) return 0; STRIP_NOPS (exp); if (TREE_CODE (exp) != ADDR_EXPR @@ -2110,7 +2094,7 @@ build_component_ref (datum, component, basetype_path, protect) { tree context = DECL_FIELD_CONTEXT (field); tree base = context; - while (!comptypes (base, basetype,1) && TYPE_NAME (base) + while (!same_type_p (base, basetype) && TYPE_NAME (base) && ANON_UNION_TYPE_P (base)) { base = TYPE_CONTEXT (base); @@ -2257,7 +2241,7 @@ build_indirect_ref (ptr, errorstring) if (TREE_CODE (pointer) == ADDR_EXPR && !flag_volatile - && comptypes (t, TREE_TYPE (TREE_OPERAND (pointer, 0)), 1)) + && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0)))) /* The POINTER was something like `&x'. We simplify `*&x' to `x'. */ return TREE_OPERAND (pointer, 0); @@ -5052,7 +5036,7 @@ build_conditional_expr (ifexp, op1, op2) if (code1 == RECORD_TYPE && code2 == RECORD_TYPE && real_lvalue_p (op1) && real_lvalue_p (op2) - && comptypes (type1, type2, -1)) + && comptypes (type1, type2, COMPARE_BASE | COMPARE_RELAXED)) { type1 = build_reference_type (type1); type2 = build_reference_type (type2); @@ -5106,7 +5090,7 @@ build_conditional_expr (ifexp, op1, op2) result_type = qualify_type (type2, type1); } /* C++ */ - else if (comptypes (type2, type1, 0)) + else if (same_or_base_type_p (type2, type1)) result_type = type2; else if (IS_AGGR_TYPE (TREE_TYPE (type1)) && IS_AGGR_TYPE (TREE_TYPE (type2)) @@ -5383,8 +5367,8 @@ build_static_cast (type, expr) } else if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype)) { - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))), - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (intype))), 1) + if (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))), + TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (intype)))) && at_least_as_qualified_p (TREE_TYPE (TREE_TYPE (type)), TREE_TYPE (TREE_TYPE (intype))) && (binfo = get_binfo (TYPE_OFFSET_BASETYPE (TREE_TYPE (type)), @@ -5452,7 +5436,8 @@ build_reinterpret_cast (type, expr) expr = build_indirect_ref (expr, 0); return expr; } - else if (comptypes (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type), 1)) + else if (same_type_p (TYPE_MAIN_VARIANT (intype), + TYPE_MAIN_VARIANT (type))) return build_static_cast (type, expr); if (TYPE_PTR_P (type) && (TREE_CODE (intype) == INTEGER_TYPE @@ -5531,7 +5516,7 @@ build_const_cast (type, expr) intype = TREE_TYPE (expr); - if (comptypes (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type), 1)) + if (same_type_p (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type))) return build_static_cast (type, expr); else if (TREE_CODE (type) == REFERENCE_TYPE) { @@ -6033,7 +6018,7 @@ build_modify_expr (lhs, modifycode, rhs) { int from_array; - if (! comptypes (lhstype, TREE_TYPE (rhs), 0)) + if (!same_or_base_type_p (lhstype, TREE_TYPE (rhs))) { cp_error ("incompatible types in assignment of `%T' to `%T'", TREE_TYPE (rhs), lhstype); @@ -6533,7 +6518,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) else if (TREE_READONLY_DECL_P (rhs)) rhs = decl_constant_value (rhs); - if (comptypes (type, rhstype, 1)) + if (same_type_p (type, rhstype)) { overflow_warning (rhs); return rhs; @@ -6778,7 +6763,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) member function pointers as C. Emit warnings here. */ if (TREE_CODE (ttl) == FUNCTION_TYPE || TREE_CODE (ttl) == METHOD_TYPE) - if (! comptypes (ttl, ttr, 0)) + if (!same_or_base_type_p (ttl, ttr)) { warning ("conflicting function types in %s:", errtype); cp_warning ("\t`%T' != `%T'", type, rhstype); @@ -7363,8 +7348,8 @@ comp_ptr_ttypes_real (to, from, constp) return 0; if (TREE_CODE (from) == OFFSET_TYPE - && comptypes (TYPE_OFFSET_BASETYPE (from), - TYPE_OFFSET_BASETYPE (to), 1)) + && same_type_p (TYPE_OFFSET_BASETYPE (from), + TYPE_OFFSET_BASETYPE (to))) continue; /* Const and volatile mean something different for function types, @@ -7388,7 +7373,7 @@ comp_ptr_ttypes_real (to, from, constp) if (TREE_CODE (to) != POINTER_TYPE) return - comptypes (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), 1) + same_type_p (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from)) && (constp >= 0 || to_more_cv_qualified); } } @@ -7418,12 +7403,14 @@ ptr_reasonably_similar (to, from) if (TREE_CODE (from) == OFFSET_TYPE && comptypes (TYPE_OFFSET_BASETYPE (to), - TYPE_OFFSET_BASETYPE (from), -1)) + TYPE_OFFSET_BASETYPE (from), + COMPARE_BASE | COMPARE_RELAXED)) continue; if (TREE_CODE (to) != POINTER_TYPE) return comptypes - (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), -1); + (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), + COMPARE_BASE | COMPARE_RELAXED); } } @@ -7439,12 +7426,13 @@ comp_ptr_ttypes_const (to, from) return 0; if (TREE_CODE (from) == OFFSET_TYPE - && comptypes (TYPE_OFFSET_BASETYPE (from), - TYPE_OFFSET_BASETYPE (to), 1)) + && same_type_p (TYPE_OFFSET_BASETYPE (from), + TYPE_OFFSET_BASETYPE (to))) continue; if (TREE_CODE (to) != POINTER_TYPE) - return comptypes (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), 1); + return same_type_p (TYPE_MAIN_VARIANT (to), + TYPE_MAIN_VARIANT (from)); } } diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900321_01.C b/gcc/testsuite/g++.old-deja/g++.bugs/900321_01.C index 56a333f532b..489671f24ae 100644 --- a/gcc/testsuite/g++.old-deja/g++.bugs/900321_01.C +++ b/gcc/testsuite/g++.old-deja/g++.bugs/900321_01.C @@ -19,8 +19,8 @@ void function_0 () { // we miss the first two because typeck.c (comp_array_types) deems // it okay if one of the sizes is null - ptr_to_array_of_ints = ptr_to_array_of_3_ints; // ERROR - , XFAIL *-*-* - ptr_to_array_of_3_ints = ptr_to_array_of_ints; // ERROR - , XFAIL *-*-* + ptr_to_array_of_ints = ptr_to_array_of_3_ints; // ERROR - + ptr_to_array_of_3_ints = ptr_to_array_of_ints; // ERROR - ptr_to_array_of_3_ints = ptr_to_array_of_5_ints; // ERROR - ptr_to_array_of_5_ints = ptr_to_array_of_3_ints; // ERROR - diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900322_01.C b/gcc/testsuite/g++.old-deja/g++.bugs/900322_01.C index 961d95c08a9..5f3aa050609 100644 --- a/gcc/testsuite/g++.old-deja/g++.bugs/900322_01.C +++ b/gcc/testsuite/g++.old-deja/g++.bugs/900322_01.C @@ -22,23 +22,23 @@ // keywords: incomplete types, arrays, element types -extern int extern_two_d [] []; // ERROR - , XFAIL *-*-* +extern int extern_two_d [] []; // ERROR - invalid declaration int tenative_two_d [] []; // ERROR - caught by g++ static int static_two_d [] []; // ERROR - caught by g++ -int (*pointer_to_two_d)[][]; // ERROR - , XFAIL *-*-* +int (*pointer_to_two_d)[][]; // ERROR - invalid declaration -void function_0 (int arg [] []) { /* ERROR - */ +void function_0 (int arg [] []) { // ERROR - invalid declaration } typedef int int_one_d_type []; -typedef int_one_d_type int_two_d_type[];// ERROR - , XFAIL *-*-* +typedef int_one_d_type int_two_d_type[];// ERROR - invalid declaration struct s; extern struct s extern_s_array [10]; // ERROR - , XFAIL *-*-* -struct s tenative_s_array [10]; /* ERROR - caught by g++ */ -static struct s static_s_array [10]; /* ERROR - caught by g++ */ +struct s tenative_s_array [10]; // ERROR - caught by g++ +static struct s static_s_array [10]; // ERROR - caught by g++ struct s (*pointer_to_s_array) []; // ERROR - , XFAIL *-*-* diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900520_02.C b/gcc/testsuite/g++.old-deja/g++.bugs/900520_02.C index 05c880d2e3c..80543b67913 100644 --- a/gcc/testsuite/g++.old-deja/g++.bugs/900520_02.C +++ b/gcc/testsuite/g++.old-deja/g++.bugs/900520_02.C @@ -1,13 +1,5 @@ // g++ 1.37.1 bug 900520_02 -// g++ fails to allow a reference to an unbounded array type to be passed -// into a formal parameter whose type is pointer-to-bounded-array type. - -// Cases other than parameter passing in which similar initializations -// take place are allowed however. - -// cfront 2.0 passes this test. - // keywords: reference types, initialization, parameter passing typedef int b_array[3]; @@ -16,17 +8,17 @@ typedef int u_array[]; typedef b_array &b_array_ref; typedef u_array &u_array_ref; -void take_b_array_ref (b_array_ref arg) { } +void take_b_array_ref (b_array_ref arg) { } // ERROR - passed to here extern u_array u_array_gbl_obj; u_array_ref u_array_ref_gbl_obj0 = u_array_gbl_obj; -b_array_ref b_array_ref_gbl_obj0 = u_array_ref_gbl_obj0; // OK +b_array_ref b_array_ref_gbl_obj0 = u_array_ref_gbl_obj0; // ERROR - invalid declaration void test_passing () { - take_b_array_ref (u_array_ref_gbl_obj0); // gets bogus error + take_b_array_ref (u_array_ref_gbl_obj0); // ERROR - invalid call } b_array u_array_gbl_obj; diff --git a/gcc/testsuite/g++.old-deja/g++.other/typeck1.C b/gcc/testsuite/g++.old-deja/g++.other/typeck1.C new file mode 100644 index 00000000000..6dd5fed5c25 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/typeck1.C @@ -0,0 +1,17 @@ +// Build don't link: + +extern int a[][]; // ERROR - invalid multidimensional array +extern int b[7][]; // ERROR - invalid multidimensional array +extern int c[][7]; // OK + +extern int (*i)[]; // ERROR - previous declaration +extern int (*i)[7]; // ERROR - conflicting types for `i' + +extern int m[]; +extern int m[7]; // OK + +void f(int (*j)[3]) +{ + extern int (*k)[]; + f(k); // ERROR - passing wrong type +} diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ptrmem3.C b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem3.C new file mode 100644 index 00000000000..8b7c373c1b7 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem3.C @@ -0,0 +1,12 @@ +// Build don't link: + +template +struct S : public S {}; +template <> +struct S {}; + +void g() +{ + int S::*p; + int S::*q = p; +} diff --git a/gcc/testsuite/g++.old-deja/g++.pt/sizeof2.C b/gcc/testsuite/g++.old-deja/g++.pt/sizeof2.C index fba3ed67b4b..566665af23c 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/sizeof2.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/sizeof2.C @@ -3,8 +3,6 @@ // Adapted from testcase by Oskar Enoksson -// execution test - XFAIL *-*-* - extern "C" void abort(); template // Base class diff --git a/gcc/testsuite/g++.old-deja/g++.pt/sizeof3.C b/gcc/testsuite/g++.old-deja/g++.pt/sizeof3.C index 055ca0da251..cd5f701f20f 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/sizeof3.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/sizeof3.C @@ -1,7 +1,5 @@ // Adapted from testcase by Oskar Enoksson -// execution test - XFAIL *-*-* - extern "C" void abort(); template @@ -22,6 +20,6 @@ public: }; int main() { - if (sizeof(C<3,7>::AC::T) != 7) // gets bogus error - XFAIL *-*-* + if (sizeof(C<3,7>::AC::T) != 7) abort(); }