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
This commit is contained in:
Mark Mitchell 1998-11-01 15:45:11 +00:00 committed by Mark Mitchell
parent 6d8cf409b4
commit 3bfdc7190f
21 changed files with 367 additions and 297 deletions

View File

@ -1,3 +1,69 @@
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.

View File

@ -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;

View File

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

View File

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

View File

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

View File

@ -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);
}
}

View File

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

View File

@ -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'",

View File

@ -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. */

View File

@ -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 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;
@ -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;
}

View File

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

View File

@ -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.' */

View File

@ -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;

View File

@ -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;
/* Target types must match incl. qualifiers. */
if (!(TREE_TYPE (t1) == TREE_TYPE (t2)
|| (*cmp) (TREE_TYPE (t1), TREE_TYPE (t2), strict)))
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)
if (t1 == t2)
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))));
/* 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 & ~COMPARE_REDECLARATION)))
return 0;
d1 = TYPE_DOMAIN (t1);
d2 = TYPE_DOMAIN (t2);
if (d1 == d2)
return 1;
/* 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;
/* 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));
}
}

View File

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

View File

@ -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 *-*-*

View File

@ -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;

View File

@ -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
}

View File

@ -0,0 +1,12 @@
// 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;
}

View File

@ -3,8 +3,6 @@
// Adapted from testcase by Oskar Enoksson <osken393@student.liu.se>
// execution test - XFAIL *-*-*
extern "C" void abort();
template<int N, class T> // Base class

View File

@ -1,7 +1,5 @@
// Adapted from testcase by Oskar Enoksson <osken393@student.liu.se>
// execution test - XFAIL *-*-*
extern "C" void abort();
template<class T0>
@ -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();
}