This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C/C++/ObjC/ObjC++ PATCH] Battle of the comptypes (PR c++/35049)
Here it is. The problem is that C and C++ call two different things
"comptypes". What C calls comptypes, C++ calls same_type_p. In turn,
C++ does have a comptypes but it has an additional third argument;
same_type_p (a, b) == comptypes (a, b, 0) == <C front-end comptypes> (a, b).
The solution is to give the same signature to the C and C++ front-end's
comptypes functions. Furthermore, I moved the same_type_p macro from
C++ to c-common.h so that the whole family of languages can use the same
name for the same thing. Therefore, a large part of the patch renames
comptypes calls to same_type_p or same_type_ignoring_top_level_qualifiers_p.
The patch may seem a little more complicated than Doug's because it
touches multiple languages, but actually it kills more code than it
adds! In particular, it removes an ugly hack in the ObjC++ front-end to
mediate between objc/objc-act.c (which uses a two-argument comptypes)
and cp/typeck.c (which implements a three-argument comptypes).
Bootstrapped/regtested i686-pc-linux-gnu,
C/C++/ObjC/ObjC++/Fortran/Java. Ok for mainline together with reverting
Doug's changes?
Paolo
2008-02-07 Paolo Bonzini <bonzini@gnu.org>
* c-objc-common.c (c_types_compatible_p): Don't use comptypes directly.
* c-tree.h (comptypes): Move prototype...
* c-common.h (comptypes): ... here, adding a third argument.
(same_type_p, same_type_ignoring_top_level_qualifiers_p,
COMPARE_STRICT): Move here from cp/cp-tree.h.
* c-common.c: Don't use comptypes directly.
* c-decl.c: Don't use comptypes directly.
* c-parser.c: Don't use comptypes directly.
* c-typeck.c: Don't use comptypes directly.
(comptypes): Add a third, unused argument for compatibility with C++.
cp:
2008-02-07 Paolo Bonzini <bonzini@gnu.org>
* typeck.c (comptypes): Return int.
* cp-tree.h (same_type_p, same_type_ignoring_top_level_qualifiers_p,
COMPARE_STRICT, comptypes): Remove.
objc:
2008-02-07 Paolo Bonzini <bonzini@gnu.org>
* objc-act.c (check_ivars): Use same_type_p instead of
comptypes.
objcp:
2008-02-07 Paolo Bonzini <bonzini@gnu.org>
* objcp-decl.c (objcp_comptypes): Delete.
* objcp-decl.h (objcp_comptypes): Delete prototype.
(comptypes): Delete.
Index: objc/objc-act.c
===================================================================
--- objc/objc-act.c (revision 131960)
+++ objc/objc-act.c (working copy)
@@ -4983,7 +4983,7 @@ check_ivars (tree inter, tree imp)
t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
- if (!comptypes (t1, t2)
+ if (!same_type_p (t1, t2)
|| !tree_int_cst_equal (DECL_INITIAL (intdecls),
DECL_INITIAL (impdecls)))
{
Index: objcp/objcp-decl.c
===================================================================
--- objcp/objcp-decl.c (revision 131960)
+++ objcp/objcp-decl.c (working copy)
@@ -92,12 +92,6 @@ objcp_xref_tag (enum tree_code code ATTR
return xref_tag (record_type, name, ts_global, false);
}
-int
-objcp_comptypes (tree type1, tree type2)
-{
- return comptypes (type1, type2, COMPARE_STRICT);
-}
-
tree
objcp_begin_compound_stmt (int flags ATTRIBUTE_UNUSED)
{
Index: objcp/objcp-decl.h
===================================================================
--- objcp/objcp-decl.h (revision 131960)
+++ objcp/objcp-decl.h (working copy)
@@ -28,7 +28,6 @@ extern tree objcp_finish_struct (tree, t
extern void objcp_finish_function (void);
extern tree objcp_build_function_call (tree, tree);
extern tree objcp_xref_tag (enum tree_code, tree);
-extern int objcp_comptypes (tree, tree);
extern tree objcp_begin_compound_stmt (int);
extern tree objcp_end_compound_stmt (tree, int);
@@ -45,8 +44,6 @@ extern tree objcp_end_compound_stmt (tre
objcp_finish_function ()
#define xref_tag(code, name) \
objcp_xref_tag (code, name)
-#define comptypes(type1, type2) \
- objcp_comptypes (type1, type2)
#define c_begin_compound_stmt(flags) \
objcp_begin_compound_stmt (flags)
#define c_end_compound_stmt(stmt, flags) \
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 131960)
+++ cp/typeck.c (working copy)
@@ -1102,7 +1102,7 @@ structural_comptypes (tree t1, tree t2,
/* Return true if T1 and T2 are related as allowed by STRICT. STRICT
is a bitwise-or of the COMPARE_* flags. */
-bool
+int
comptypes (tree t1, tree t2, int strict)
{
if (strict == COMPARE_STRICT)
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 131960)
+++ cp/cp-tree.h (working copy)
@@ -278,16 +278,6 @@ typedef struct ptrmem_cst * ptrmem_cst_t
#define STMT_EXPR_NO_SCOPE(NODE) \
TREE_LANG_FLAG_0 (STMT_EXPR_CHECK (NODE))
-/* 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, ignoring
- top-level qualifiers. */
-#define same_type_ignoring_top_level_qualifiers_p(TYPE1, TYPE2) \
- same_type_p (TYPE_MAIN_VARIANT (TYPE1), TYPE_MAIN_VARIANT (TYPE2))
-
/* Nonzero if we are presently building a statement tree, rather
than expanding each statement as we encounter it. */
#define building_stmt_tree() (cur_stmt_list != NULL_TREE)
@@ -3747,8 +3737,6 @@ enum overload_flags { NO_SPECIAL = 0, DT
/* 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. */
#define COMPARE_DERIVED 2 /* Like COMPARE_BASE, but in
@@ -4763,7 +4751,6 @@ extern tree complete_type (tree);
extern tree complete_type_or_else (tree, tree);
extern int type_unknown_p (const_tree);
extern bool comp_except_specs (const_tree, const_tree, bool);
-extern bool comptypes (tree, tree, int);
extern bool compparms (const_tree, const_tree);
extern int comp_cv_qualification (const_tree, const_tree);
extern int comp_cv_qual_signature (tree, tree);
Index: c-objc-common.c
===================================================================
--- c-objc-common.c (revision 131960)
+++ c-objc-common.c (working copy)
@@ -187,7 +187,7 @@ c_initialize_diagnostics (diagnostic_con
int
c_types_compatible_p (tree x, tree y)
{
- return comptypes (TYPE_MAIN_VARIANT (x), TYPE_MAIN_VARIANT (y));
+ return same_type_ignoring_top_level_qualifiers_p (x, y);
}
/* Determine if the type is a vla type for the backend. */
Index: c-tree.h
===================================================================
--- c-tree.h (revision 131960)
+++ c-tree.h (working copy)
@@ -542,7 +542,6 @@ extern struct c_label_context_vm *label_
extern tree require_complete_type (tree);
extern int same_translation_unit_p (const_tree, const_tree);
-extern int comptypes (tree, tree);
extern bool c_vla_type_p (const_tree);
extern bool c_mark_addressable (tree);
extern void c_incomplete_type_error (const_tree, const_tree);
Index: c-decl.c
===================================================================
--- c-decl.c (revision 131960)
+++ c-decl.c (working copy)
@@ -1021,7 +1021,7 @@ diagnose_arglist_conflict (tree newdecl,
tree t;
if (TREE_CODE (olddecl) != FUNCTION_DECL
- || !comptypes (TREE_TYPE (oldtype), TREE_TYPE (newtype))
+ || !same_type_p (TREE_TYPE (oldtype), TREE_TYPE (newtype))
|| !((TYPE_ARG_TYPES (oldtype) == 0 && DECL_INITIAL (olddecl) == 0)
||
(TYPE_ARG_TYPES (newtype) == 0 && DECL_INITIAL (newdecl) == 0)))
@@ -1098,7 +1098,7 @@ validate_proto_after_old_defn (tree newd
/* Type for passing arg must be consistent with that declared
for the arg. */
- else if (!comptypes (oldargtype, newargtype))
+ else if (!same_type_p (oldargtype, newargtype))
{
error ("prototype for %q+D declares argument %d"
" with incompatible type",
@@ -1193,7 +1193,7 @@ diagnose_mismatched_decls (tree newdecl,
return false;
}
- if (!comptypes (oldtype, newtype))
+ if (!same_type_p (oldtype, newtype))
{
if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_BUILT_IN (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl))
@@ -1202,7 +1202,7 @@ diagnose_mismatched_decls (tree newdecl,
This is for the ffs and fprintf builtins. */
tree trytype = match_builtin_function_types (newtype, oldtype);
- if (trytype && comptypes (newtype, trytype))
+ if (trytype && same_type_p (newtype, trytype))
*oldtypep = oldtype = trytype;
else
{
@@ -1649,7 +1649,7 @@ merge_decls (tree newdecl, tree olddecl,
= composite_type (newtype, oldtype);
/* Lay the type out, unless already done. */
- if (!comptypes (oldtype, TREE_TYPE (newdecl)))
+ if (!same_type_p (oldtype, TREE_TYPE (newdecl)))
{
if (TREE_TYPE (newdecl) != error_mark_node)
layout_type (TREE_TYPE (newdecl));
@@ -2138,7 +2138,7 @@ pushdecl (tree x)
/* Save the updated type in the external scope and
restore the proper type for this scope. */
tree thistype;
- if (comptypes (vistype, type))
+ if (same_type_p (vistype, type))
thistype = composite_type (vistype, type);
else
thistype = TREE_TYPE (b_use->decl);
@@ -2240,7 +2240,7 @@ pushdecl (tree x)
tree thistype;
if (vistype)
{
- if (comptypes (vistype, type))
+ if (same_type_p (vistype, type))
thistype = composite_type (vistype, type);
else
thistype = TREE_TYPE (b->decl);
@@ -2411,7 +2411,7 @@ implicitly_declare (tree functionid)
newtype = build_type_attribute_variant (newtype,
TYPE_ATTRIBUTES
(TREE_TYPE (decl)));
- if (!comptypes (newtype, TREE_TYPE (decl)))
+ if (!same_type_p (newtype, TREE_TYPE (decl)))
{
warning (0, "incompatible implicit declaration of built-in"
" function %qD", decl);
@@ -2420,7 +2420,7 @@ implicitly_declare (tree functionid)
}
else
{
- if (!comptypes (newtype, TREE_TYPE (decl)))
+ if (!same_type_p (newtype, TREE_TYPE (decl)))
{
error ("incompatible implicit declaration of function %qD",
decl);
@@ -6146,8 +6146,8 @@ start_function (struct c_declspecs *decl
if (TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0)
{
if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE
- && comptypes (TREE_TYPE (TREE_TYPE (decl1)),
- TREE_TYPE (TREE_TYPE (old_decl))))
+ && same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
+ TREE_TYPE (TREE_TYPE (old_decl))))
{
TREE_TYPE (decl1) = composite_type (TREE_TYPE (old_decl),
TREE_TYPE (decl1));
@@ -6175,8 +6175,8 @@ start_function (struct c_declspecs *decl
ext_decl = b->decl;
ext_type = b->type ? b->type : TREE_TYPE (ext_decl);
if (TREE_CODE (ext_type) == FUNCTION_TYPE
- && comptypes (TREE_TYPE (TREE_TYPE (decl1)),
- TREE_TYPE (ext_type)))
+ && same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
+ TREE_TYPE (ext_type)))
{
current_function_prototype_locus
= DECL_SOURCE_LOCATION (ext_decl);
@@ -6493,8 +6493,8 @@ store_parm_decls_oldstyle (tree fndecl,
/* Type for passing arg must be consistent with that
declared for the arg. ISO C says we take the unqualified
type for parameters declared with qualified type. */
- if (!comptypes (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)),
- TYPE_MAIN_VARIANT (TREE_VALUE (type))))
+ if (!same_type_ignoring_top_level_qualifiers_p (DECL_ARG_TYPE (parm),
+ TREE_VALUE (type)))
{
if (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
== TYPE_MAIN_VARIANT (TREE_VALUE (type)))
Index: c-typeck.c
===================================================================
--- c-typeck.c (revision 131960)
+++ c-typeck.c (working copy)
@@ -466,7 +466,7 @@ composite_type (tree t1, tree t2)
if (mv3 && mv3 != error_mark_node
&& TREE_CODE (mv3) != ARRAY_TYPE)
mv3 = TYPE_MAIN_VARIANT (mv3);
- if (comptypes (mv3, mv2))
+ if (same_type_p (mv3, mv2))
{
TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
TREE_VALUE (p2));
@@ -491,7 +491,7 @@ composite_type (tree t1, tree t2)
if (mv3 && mv3 != error_mark_node
&& TREE_CODE (mv3) != ARRAY_TYPE)
mv3 = TYPE_MAIN_VARIANT (mv3);
- if (comptypes (mv3, mv1))
+ if (same_type_p (mv3, mv1))
{
TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
TREE_VALUE (p1));
@@ -858,7 +858,7 @@ common_type (tree t1, tree t2)
but a warning may be needed if you use them together. */
int
-comptypes (tree type1, tree type2)
+comptypes (tree type1, tree type2, int strict ATTRIBUTE_UNUSED)
{
const struct tagged_tu_seen_cache * tagged_tu_seen_base1 = tagged_tu_seen_base;
int val;
@@ -1037,7 +1037,7 @@ comp_target_types (tree ttl, tree ttr)
mvl = TYPE_MAIN_VARIANT (mvl);
if (TREE_CODE (mvr) != ARRAY_TYPE)
mvr = TYPE_MAIN_VARIANT (mvr);
- val = comptypes (mvl, mvr);
+ val = same_type_p (mvl, mvr);
if (val == 2 && pedantic)
pedwarn ("types are not quite compatible");
@@ -2403,7 +2403,7 @@ build_function_call (tree function, tree
|| TREE_CODE (function) == CONVERT_EXPR)
&& TREE_CODE (tem = TREE_OPERAND (function, 0)) == ADDR_EXPR
&& TREE_CODE (tem = TREE_OPERAND (tem, 0)) == FUNCTION_DECL
- && !comptypes (fntype, TREE_TYPE (tem)))
+ && !same_type_p (fntype, TREE_TYPE (tem)))
{
tree return_type = TREE_TYPE (fntype);
tree trap = build_function_call (built_in_decls[BUILT_IN_TRAP],
@@ -3628,8 +3628,8 @@ build_c_cast (tree type, tree expr)
tree field;
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
- TYPE_MAIN_VARIANT (TREE_TYPE (value))))
+ if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field),
+ TREE_TYPE (value)))
break;
if (field)
@@ -4030,7 +4030,7 @@ convert_for_assignment (tree type, tree
This code doesn't fully support references, it's just for the
special case of va_start and va_copy. */
if (codel == REFERENCE_TYPE
- && comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1)
+ && same_type_p (TREE_TYPE (type), TREE_TYPE (rhs)) == 1)
{
if (!lvalue_p (rhs))
{
@@ -4070,7 +4070,7 @@ convert_for_assignment (tree type, tree
/* Aggregates in different TUs might need conversion. */
if ((codel == RECORD_TYPE || codel == UNION_TYPE)
&& codel == coder
- && comptypes (type, rhstype))
+ && same_type_p (type, rhstype))
return convert_and_check (type, rhs);
/* Conversion to a transparent union from its member types.
@@ -4084,8 +4084,7 @@ convert_for_assignment (tree type, tree
{
tree memb_type = TREE_TYPE (memb);
- if (comptypes (TYPE_MAIN_VARIANT (memb_type),
- TYPE_MAIN_VARIANT (rhstype)))
+ if (same_type_ignoring_top_level_qualifiers_p (memb_type, rhstype))
break;
if (TREE_CODE (memb_type) != POINTER_TYPE)
@@ -4704,7 +4703,7 @@ digest_init (tree type, tree init, bool
bool char_array = (typ1 == char_type_node
|| typ1 == signed_char_type_node
|| typ1 == unsigned_char_type_node);
- bool wchar_array = !!comptypes (typ1, wchar_type_node);
+ bool wchar_array = !!same_type_p (typ1, wchar_type_node);
if (char_array || wchar_array)
{
struct c_expr expr;
@@ -4717,8 +4716,8 @@ digest_init (tree type, tree init, bool
= (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
== char_type_node);
- if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
- TYPE_MAIN_VARIANT (type)))
+ if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (inside_init),
+ type))
return inside_init;
if (!wchar_array && !char_string)
@@ -4767,8 +4766,8 @@ digest_init (tree type, tree init, bool
&& TREE_CONSTANT (inside_init))
{
if (TREE_CODE (inside_init) == VECTOR_CST
- && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
- TYPE_MAIN_VARIANT (type)))
+ && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (inside_init),
+ type))
return inside_init;
if (TREE_CODE (inside_init) == CONSTRUCTOR)
@@ -4796,16 +4795,16 @@ digest_init (tree type, tree init, bool
from an expression of the same type, optionally with braces. */
if (inside_init && TREE_TYPE (inside_init) != 0
- && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
- TYPE_MAIN_VARIANT (type))
+ && (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (inside_init),
+ type)
|| (code == ARRAY_TYPE
- && comptypes (TREE_TYPE (inside_init), type))
+ && same_type_p (TREE_TYPE (inside_init), type))
|| (code == VECTOR_TYPE
- && comptypes (TREE_TYPE (inside_init), type))
+ && same_type_p (TREE_TYPE (inside_init), type))
|| (code == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
- && comptypes (TREE_TYPE (TREE_TYPE (inside_init)),
- TREE_TYPE (type)))))
+ && same_type_p (TREE_TYPE (TREE_TYPE (inside_init)),
+ TREE_TYPE (type)))))
{
if (code == POINTER_TYPE)
{
@@ -6246,8 +6245,7 @@ output_init_element (tree value, bool st
&& !(TREE_CODE (value) == STRING_CST
&& TREE_CODE (type) == ARRAY_TYPE
&& INTEGRAL_TYPE_P (TREE_TYPE (type)))
- && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
- TYPE_MAIN_VARIANT (type)))
+ && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (value), type))
value = array_to_pointer_conversion (value);
if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR
Index: c-common.c
===================================================================
--- c-common.c (revision 131960)
+++ c-common.c (working copy)
@@ -1194,7 +1194,7 @@ vector_types_convertible_p (const_tree t
return convertible_lax;
if (TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
- && comptypes (TREE_TYPE (t1), TREE_TYPE (t2)))
+ && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
return true;
if (emit_lax_note && !emitted_lax_note)
Index: c-common.h
===================================================================
--- c-common.h (revision 131960)
+++ c-common.h (working copy)
@@ -826,6 +826,7 @@ extern tree finish_label_address_expr (t
/* Same function prototype, but the C and C++ front ends have
different implementations. Used in c-common.c. */
+extern int comptypes (tree, tree, int);
extern tree lookup_label (tree);
extern tree lookup_name (tree);
@@ -881,6 +882,22 @@ enum lvalue_use {
lv_asm
};
+/* 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, ignoring
+ top-level qualifiers. */
+#define same_type_ignoring_top_level_qualifiers_p(TYPE1, TYPE2) \
+ same_type_p (TYPE_MAIN_VARIANT (TYPE1), TYPE_MAIN_VARIANT (TYPE2))
+
+/* Used with comptypes, and related functions, to guide type
+ comparison. */
+
+#define COMPARE_STRICT 0 /* Just check if the types are the
+ same. */
+
extern void lvalue_error (enum lvalue_use);
extern int complete_array_type (tree *, tree, bool);
Index: c-parser.c
===================================================================
--- c-parser.c (revision 131960)
+++ c-parser.c (working copy)
@@ -5456,7 +5456,7 @@ c_parser_postfix_expression (c_parser *p
e1 = TYPE_MAIN_VARIANT (groktypename (t1));
e2 = TYPE_MAIN_VARIANT (groktypename (t2));
- expr.value = comptypes (e1, e2)
+ expr.value = same_type_p (e1, e2)
? build_int_cst (NULL_TREE, 1)
: build_int_cst (NULL_TREE, 0);
expr.original_code = ERROR_MARK;