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> 2003-07-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* cfgloopmanip.c (duplicate_loop_to_header_edge): Update irreducible * 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 struct c_scope *make_scope (void);
static void pop_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 duplicate_decls (tree, tree, int, int);
static int redeclaration_error_message (tree, tree); static int redeclaration_error_message (tree, tree);
static tree make_label (tree, location_t); 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)); 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 /* Handle when a new declaration NEWDECL
has the same name as an old one OLDDECL has the same name as an old one OLDDECL
in the same binding contour. in the same binding contour.
@ -822,49 +863,18 @@ duplicate_decls (tree newdecl, tree olddecl, int different_binding_level,
} }
else if (!types_match) else if (!types_match)
{ {
/* Accept the return type of the new declaration if same modes. */ /* Accept harmless mismatch in function types.
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.
This is for the ffs and fprintf builtins. */ This is for the ffs and fprintf builtins. */
if (TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0 tree trytype = match_builtin_function_types (oldtype, newtype);
&& 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));
if (trytype)
{
types_match = comptypes (newtype, trytype, comptype_flags); types_match = comptypes (newtype, trytype, comptype_flags);
if (types_match) if (types_match)
oldtype = trytype; 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 else if (TYPE_ARG_TYPES (oldtype) == NULL
&& TYPE_ARG_TYPES (newtype) != NULL) && TYPE_ARG_TYPES (newtype) != NULL)