Commit b5d32c25 by Kaveh R. Ghazi Committed by Kaveh Ghazi

re PR middle-end/32668 (The type-generic builtins apply default promotions)

	PR middle-end/32668

	* builtin-attrs.def (ATTR_TYPEGENERIC,
	ATTR_CONST_NOTHROW_TYPEGENERIC): New.

	* builtins.def (BUILT_IN_ISINF, BUILT_IN_ISNAN,
	BUILT_IN_ISGREATER, BUILT_IN_ISGREATEREQUAL, BUILT_IN_ISLESS,
	BUILT_IN_ISLESSEQUAL, BUILT_IN_ISLESSGREATER,
	BUILT_IN_ISUNORDERED): Use ATTR_CONST_NOTHROW_TYPEGENERIC.

	* c-common.c (handle_type_generic_attribute): New.
	(c_common_attribute_table): Add "type generic".

	* c-typeck.c (convert_arguments): Handle "type generic" functions.

From-SVN: r126723
parent c3e4e34d
2007-07-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
PR middle-end/32668
* builtin-attrs.def (ATTR_TYPEGENERIC,
ATTR_CONST_NOTHROW_TYPEGENERIC): New.
* builtins.def (BUILT_IN_ISINF, BUILT_IN_ISNAN,
BUILT_IN_ISGREATER, BUILT_IN_ISGREATEREQUAL, BUILT_IN_ISLESS,
BUILT_IN_ISLESSEQUAL, BUILT_IN_ISLESSGREATER,
BUILT_IN_ISUNORDERED): Use ATTR_CONST_NOTHROW_TYPEGENERIC.
* c-common.c (handle_type_generic_attribute): New.
(c_common_attribute_table): Add "type generic".
* c-typeck.c (convert_arguments): Handle "type generic" functions.
2007-07-18 Daniel Berlin <dberlin@dberlin.org> 2007-07-18 Daniel Berlin <dberlin@dberlin.org>
* tree-ssa-sccvn.c (try_to_simplify): Use valid_gimple_expression * tree-ssa-sccvn.c (try_to_simplify): Use valid_gimple_expression
......
...@@ -94,6 +94,7 @@ DEF_ATTR_IDENT (ATTR_SCANF, "scanf") ...@@ -94,6 +94,7 @@ DEF_ATTR_IDENT (ATTR_SCANF, "scanf")
DEF_ATTR_IDENT (ATTR_SENTINEL, "sentinel") DEF_ATTR_IDENT (ATTR_SENTINEL, "sentinel")
DEF_ATTR_IDENT (ATTR_STRFMON, "strfmon") DEF_ATTR_IDENT (ATTR_STRFMON, "strfmon")
DEF_ATTR_IDENT (ATTR_STRFTIME, "strftime") DEF_ATTR_IDENT (ATTR_STRFTIME, "strftime")
DEF_ATTR_IDENT (ATTR_TYPEGENERIC, "type generic")
DEF_ATTR_TREE_LIST (ATTR_NOVOPS_LIST, ATTR_NOVOPS, ATTR_NULL, ATTR_NULL) DEF_ATTR_TREE_LIST (ATTR_NOVOPS_LIST, ATTR_NOVOPS, ATTR_NULL, ATTR_NULL)
...@@ -142,6 +143,9 @@ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_5, ATTR_NONNULL, ATTR_LIST_5, \ ...@@ -142,6 +143,9 @@ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_5, ATTR_NONNULL, ATTR_LIST_5, \
/* Nothrow const functions whose pointer parameter(s) are all nonnull. */ /* Nothrow const functions whose pointer parameter(s) are all nonnull. */
DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_NONNULL, ATTR_CONST, ATTR_NULL, \ DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_NONNULL, ATTR_CONST, ATTR_NULL, \
ATTR_NOTHROW_NONNULL) ATTR_NOTHROW_NONNULL)
/* Nothrow const functions which are type-generic. */
DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_TYPEGENERIC, ATTR_TYPEGENERIC, ATTR_NULL, \
ATTR_CONST_NOTHROW_LIST)
/* Nothrow pure functions whose pointer parameter(s) are all nonnull. */ /* Nothrow pure functions whose pointer parameter(s) are all nonnull. */
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL, ATTR_PURE, ATTR_NULL, \ DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL, ATTR_PURE, ATTR_NULL, \
ATTR_NOTHROW_NONNULL) ATTR_NOTHROW_NONNULL)
......
...@@ -654,24 +654,24 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEL, "finitel", BT_FN_INT_LONGDOUBLE, ATTR_ ...@@ -654,24 +654,24 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEL, "finitel", BT_FN_INT_LONGDOUBLE, ATTR_
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED32, "finited32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED32, "finited32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED64, "finited64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED64, "finited64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED128, "finited128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED128, "finited128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST)
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST) DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFF, "isinff", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFF, "isinff", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFL, "isinfl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFL, "isinfl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD32, "isinfd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD32, "isinfd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD64, "isinfd64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD64, "isinfd64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD128, "isinfd128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD128, "isinfd128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST)
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISNAN, "isnan", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST) DEF_C99_C90RES_BUILTIN (BUILT_IN_ISNAN, "isnan", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANF, "isnanf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANF, "isnanf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANL, "isnanl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANL, "isnanl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND32, "isnand32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND32, "isnand32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND64, "isnand64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND64, "isnand64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND128, "isnand128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND128, "isnand128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_ISGREATER, "isgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_ISGREATER, "isgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
DEF_GCC_BUILTIN (BUILT_IN_ISGREATEREQUAL, "isgreaterequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_ISGREATEREQUAL, "isgreaterequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
DEF_GCC_BUILTIN (BUILT_IN_ISLESS, "isless", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_ISLESS, "isless", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
DEF_GCC_BUILTIN (BUILT_IN_ISLESSEQUAL, "islessequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_ISLESSEQUAL, "islessequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
DEF_GCC_BUILTIN (BUILT_IN_ISLESSGREATER, "islessgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_ISLESSGREATER, "islessgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
DEF_GCC_BUILTIN (BUILT_IN_ISUNORDERED, "isunordered", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_ISUNORDERED, "isunordered", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
DEF_LIB_BUILTIN (BUILT_IN_LABS, "labs", BT_FN_LONG_LONG, ATTR_CONST_NOTHROW_LIST) DEF_LIB_BUILTIN (BUILT_IN_LABS, "labs", BT_FN_LONG_LONG, ATTR_CONST_NOTHROW_LIST)
DEF_C99_BUILTIN (BUILT_IN_LLABS, "llabs", BT_FN_LONGLONG_LONGLONG, ATTR_CONST_NOTHROW_LIST) DEF_C99_BUILTIN (BUILT_IN_LLABS, "llabs", BT_FN_LONGLONG_LONGLONG, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_LONGJMP, "longjmp", BT_FN_VOID_PTR_INT, ATTR_NORETURN_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_LONGJMP, "longjmp", BT_FN_VOID_PTR_INT, ATTR_NORETURN_NOTHROW_LIST)
......
...@@ -555,6 +555,7 @@ static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *); ...@@ -555,6 +555,7 @@ static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);
static tree handle_warn_unused_result_attribute (tree *, tree, tree, int, static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
bool *); bool *);
static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *); static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *); static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
static void check_function_nonnull (tree, int, tree *); static void check_function_nonnull (tree, int, tree *);
...@@ -650,6 +651,10 @@ const struct attribute_spec c_common_attribute_table[] = ...@@ -650,6 +651,10 @@ const struct attribute_spec c_common_attribute_table[] =
handle_warn_unused_result_attribute }, handle_warn_unused_result_attribute },
{ "sentinel", 0, 1, false, true, true, { "sentinel", 0, 1, false, true, true,
handle_sentinel_attribute }, handle_sentinel_attribute },
/* For internal use (marking of builtins) only. The name contains space
to prevent its usage in source code. */
{ "type generic", 0, 0, false, true, true,
handle_type_generic_attribute },
{ "alloc_size", 1, 2, false, true, true, { "alloc_size", 1, 2, false, true, true,
handle_alloc_size_attribute }, handle_alloc_size_attribute },
{ "cold", 0, 0, true, false, false, { "cold", 0, 0, true, false, false,
...@@ -6167,6 +6172,19 @@ handle_sentinel_attribute (tree *node, tree name, tree args, ...@@ -6167,6 +6172,19 @@ handle_sentinel_attribute (tree *node, tree name, tree args,
return NULL_TREE; return NULL_TREE;
} }
/* Handle a "type_generic" attribute. */
static tree
handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
tree ARG_UNUSED (args), int ARG_UNUSED (flags),
bool * ARG_UNUSED (no_add_attrs))
{
/* Ensure we have a function type, with no arguments. */
gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE && ! TYPE_ARG_TYPES (*node));
return NULL_TREE;
}
/* Check for valid arguments being passed to a function. /* Check for valid arguments being passed to a function.
ATTRS is a list of attributes. There are NARGS arguments in the array ATTRS is a list of attributes. There are NARGS arguments in the array
ARGARRAY. TYPELIST is the list of argument types for the function. ARGARRAY. TYPELIST is the list of argument types for the function.
......
...@@ -2394,6 +2394,8 @@ convert_arguments (int nargs, tree *argarray, ...@@ -2394,6 +2394,8 @@ convert_arguments (int nargs, tree *argarray,
{ {
tree typetail, valtail; tree typetail, valtail;
int parmnum; int parmnum;
const bool type_generic = fundecl
&& lookup_attribute ("type generic", TYPE_ATTRIBUTES(TREE_TYPE (fundecl)));
tree selector; tree selector;
/* Change pointer to function to the function itself for /* Change pointer to function to the function itself for
...@@ -2585,8 +2587,13 @@ convert_arguments (int nargs, tree *argarray, ...@@ -2585,8 +2587,13 @@ convert_arguments (int nargs, tree *argarray,
&& (TYPE_PRECISION (TREE_TYPE (val)) && (TYPE_PRECISION (TREE_TYPE (val))
< TYPE_PRECISION (double_type_node)) < TYPE_PRECISION (double_type_node))
&& !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (val)))) && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (val))))
{
if (type_generic)
argarray[parmnum] = val;
else
/* Convert `float' to `double'. */ /* Convert `float' to `double'. */
argarray[parmnum] = convert (double_type_node, val); argarray[parmnum] = convert (double_type_node, val);
}
else if ((invalid_func_diag = else if ((invalid_func_diag =
targetm.calls.invalid_arg_for_unprototyped_fn (typelist, fundecl, val))) targetm.calls.invalid_arg_for_unprototyped_fn (typelist, fundecl, val)))
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment