aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2003-07-24 20:44:01 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2003-07-24 20:44:01 +0000
commit6907ddd3babc97c39c88ef55b7d8da4f5d439d56 (patch)
tree86d7822a80307d608a67cf5da2611b3f9510a81b /gcc
parent84d45ad160fc93e5271d3c01f1fe6fd6924584fd (diff)
downloadgcc-6907ddd3babc97c39c88ef55b7d8da4f5d439d56.zip
gcc-6907ddd3babc97c39c88ef55b7d8da4f5d439d56.tar.gz
gcc-6907ddd3babc97c39c88ef55b7d8da4f5d439d56.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/c-decl.c84
2 files changed, 56 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e768565..04e8812 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 62a4bd5..9f84f44 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -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)