* 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
+1998-11-01 Mark Mitchell <mark@markmitchell.com>
+
+ * 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 <jason@yorick.cygnus.com>
* rtti.c (build_dynamic_cast_1): Fix cut-and-paste error.
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)
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);
}
}
- 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);
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))
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)));
{
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
{
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'",
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
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;
}
}
/* 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));
}
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;
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)
{
--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))
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))
}
}
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]
}
}
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]
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]
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. */
!= 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)
&& 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;
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;
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);
}
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));
}
\f
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'",
/* 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;
}
{
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;
}
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;
}
}
{
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);
#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))
/* 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);
/* 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
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)
types_match = 0;
else
types_match = comptypes (TREE_TYPE (newdecl),
- TREE_TYPE (olddecl), 1);
+ TREE_TYPE (olddecl),
+ COMPARE_REDECLARATION);
}
return types_match;
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);
/* 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'";
&& 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",
}
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
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;
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
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);
}
}
&& 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))
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)
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
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;
}
}
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));
/* 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'",
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;
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. */
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));
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;
}
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;
}
}
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;
}
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;
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))
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;
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;
}
/* The tsubst call is used to handle cases such as
template <class T, template <T> 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;
/* 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);
}
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)
if (strict == DEDUCE_EXACT)
{
- if (comptypes (parm, type, 1))
+ if (same_type_p (parm, type))
continue;
}
else
/* 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));
/* 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)
/* 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
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;
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;
}
drettype = TREE_TYPE (drettype);
}
- if (comptypes (brettype, drettype, 1))
+ if (same_type_p (brettype, drettype))
return 0;
if (! (TREE_CODE (brettype) == TREE_CODE (drettype)
&& 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)))
{
}
}
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);
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.' */
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;
/* 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;
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;
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
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))
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)
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;
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. */
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
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:
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)),
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:
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:
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;
}
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;
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
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;
/* 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;
{
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;
}
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);
}
p1 = TREE_VALUE (t1);
p2 = TREE_VALUE (t2);
- if (comptypes (p1, p2, 1))
+ if (same_type_p (p1, p2))
continue;
if (pedantic)
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)
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
{
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);
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);
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);
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))
}
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)),
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
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)
{
{
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);
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;
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);
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,
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);
}
}
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);
}
}
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));
}
}
{
// 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 -
// 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 *-*-*
// 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];
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;
--- /dev/null
+// 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
+}
--- /dev/null
+// Build don't link:
+
+template <class T>
+struct S : public S<T*> {};
+template <>
+struct S<int**> {};
+
+void g()
+{
+ int S<int*>::*p;
+ int S<int>::*q = p;
+}
// Adapted from testcase by Oskar Enoksson <osken393@student.liu.se>
-// execution test - XFAIL *-*-*
-
extern "C" void abort();
template<int N, class T> // Base class
// Adapted from testcase by Oskar Enoksson <osken393@student.liu.se>
-// execution test - XFAIL *-*-*
-
extern "C" void abort();
template<class T0>
};
int main() {
- if (sizeof(C<3,7>::AC::T) != 7) // gets bogus error - XFAIL *-*-*
+ if (sizeof(C<3,7>::AC::T) != 7)
abort();
}