c-decl.c (match_builtin_function_types): New subroutine of duplicate_decls to test whether a redeclaration of a builtin...

* c-decl.c (match_builtin_function_types): New subroutine of
	duplicate_decls to test whether a redeclaration of a builtin
	function is suitably close, i.e. the return type and all of
	the argument types have the same modes as the builtin expects.
	(duplicate_decls): Fuzzy type matching for builtin functions
	moved to match_builtin_function_types.

From-SVN: r69757
This commit is contained in:
Roger Sayle 2003-07-24 20:44:01 +00:00 committed by Roger Sayle
parent 84d45ad160
commit 6907ddd3ba
2 changed files with 56 additions and 37 deletions

View File

@ -1,3 +1,12 @@
2003-07-24 Roger Sayle <roger@eyesopen.com>
* c-decl.c (match_builtin_function_types): New subroutine of
duplicate_decls to test whether a redeclaration of a builtin
function is suitably close, i.e. the return type and all of
the argument types have the same modes as the builtin expects.
(duplicate_decls): Fuzzy type matching for builtin functions
moved to match_builtin_function_types.
2003-07-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* cfgloopmanip.c (duplicate_loop_to_header_edge): Update irreducible

View File

@ -262,6 +262,7 @@ tree static_ctors, static_dtors;
static struct c_scope *make_scope (void);
static void pop_scope (void);
static tree match_builtin_function_types (tree, tree);
static int duplicate_decls (tree, tree, int, int);
static int redeclaration_error_message (tree, tree);
static tree make_label (tree, location_t);
@ -691,6 +692,46 @@ pushtag (tree name, tree type)
TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_STUB_DECL (type));
}
/* Subroutine of duplicate_decls. Allow harmless mismatches in return
and argument types provided that the type modes match. This function
return a unified type given a suitable match, and 0 otherwise. */
static tree
match_builtin_function_types (tree oldtype, tree newtype)
{
tree newrettype, oldrettype;
tree newargs, oldargs;
tree trytype, tryargs;
/* Accept the return type of the new declaration if same modes. */
oldrettype = TREE_TYPE (oldtype);
newrettype = TREE_TYPE (newtype);
if (TYPE_MODE (oldrettype) != TYPE_MODE (newrettype))
return 0;
oldargs = TYPE_ARG_TYPES (oldtype);
newargs = TYPE_ARG_TYPES (newtype);
tryargs = newargs;
while (oldargs || newargs)
{
if (! oldargs
|| ! newargs
|| ! TREE_VALUE (oldargs)
|| ! TREE_VALUE (newargs)
|| TYPE_MODE (TREE_VALUE (oldargs))
!= TYPE_MODE (TREE_VALUE (newargs)))
return 0;
oldargs = TREE_CHAIN (oldargs);
newargs = TREE_CHAIN (newargs);
}
trytype = build_function_type (newrettype, tryargs);
return build_type_attribute_variant (trytype, TYPE_ATTRIBUTES (oldtype));
}
/* Handle when a new declaration NEWDECL
has the same name as an old one OLDDECL
in the same binding contour.
@ -822,49 +863,18 @@ duplicate_decls (tree newdecl, tree olddecl, int different_binding_level,
}
else if (!types_match)
{
/* Accept the return type of the new declaration if same modes. */
tree oldreturntype = TREE_TYPE (oldtype);
tree newreturntype = TREE_TYPE (newtype);
if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
{
/* Function types may be shared, so we can't just modify
the return type of olddecl's function type. */
tree trytype
= build_function_type (newreturntype,
TYPE_ARG_TYPES (oldtype));
trytype = build_type_attribute_variant (trytype,
TYPE_ATTRIBUTES (oldtype));
types_match = comptypes (newtype, trytype, comptype_flags);
if (types_match)
oldtype = trytype;
}
/* Accept harmless mismatch in first argument type also.
/* Accept harmless mismatch in function types.
This is for the ffs and fprintf builtins. */
if (TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0
&& TYPE_ARG_TYPES (oldtype) != 0
&& TREE_VALUE (TYPE_ARG_TYPES (newtype)) != 0
&& TREE_VALUE (TYPE_ARG_TYPES (oldtype)) != 0
&& (TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (newtype)))
== TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (oldtype)))))
{
/* Function types may be shared, so we can't just modify
the return type of olddecl's function type. */
tree trytype
= build_function_type (TREE_TYPE (oldtype),
tree_cons (NULL_TREE,
TREE_VALUE (TYPE_ARG_TYPES (newtype)),
TREE_CHAIN (TYPE_ARG_TYPES (oldtype))));
trytype = build_type_attribute_variant (trytype,
TYPE_ATTRIBUTES (oldtype));
tree trytype = match_builtin_function_types (oldtype, newtype);
if (trytype)
{
types_match = comptypes (newtype, trytype, comptype_flags);
if (types_match)
oldtype = trytype;
if (! different_binding_level)
TREE_TYPE (olddecl) = oldtype;
}
if (! different_binding_level)
TREE_TYPE (olddecl) = oldtype;
}
else if (TYPE_ARG_TYPES (oldtype) == NULL
&& TYPE_ARG_TYPES (newtype) != NULL)