Commit 83322951 by Richard Guenther Committed by Richard Biener

c-common.h (check_builtin_function_arguments): Declare.

2008-04-24  Richard Guenther  <rguenther@suse.de>

	* c-common.h (check_builtin_function_arguments): Declare.
	* c-common.c (validate_nargs): New function.
	(check_builtin_function_arguments): Likewise.
	* c-typeck.c (build_function_call): Call
	check_builtin_function_arguments.
	* builtins.c (fold_builtin_classify): Remove error reporting code.
	(fold_builtin_unordered_cmp): Likewise.
	(fold_builtin_1): Likewise.
	(fold_builtin_n): Likewise.

	cp/
	* typeck.c (cp_build_function_call): Call
	check_builtin_function_arguments.

	* gcc.dg/builtin-constant_p-1.c: New testcase.
	* gcc.dg/builtin-errors.c: Adjust expected error.

From-SVN: r134635
parent 194ac52a
2008-04-24 Richard Guenther <rguenther@suse.de>
* c-common.h (check_builtin_function_arguments): Declare.
* c-common.c (validate_nargs): New function.
(check_builtin_function_arguments): Likewise.
* c-typeck.c (build_function_call): Call
check_builtin_function_arguments.
* builtins.c (fold_builtin_classify): Remove error reporting code.
(fold_builtin_unordered_cmp): Likewise.
(fold_builtin_1): Likewise.
(fold_builtin_n): Likewise.
2008-04-24 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/36008
......
......@@ -9645,11 +9645,7 @@ fold_builtin_classify (tree fndecl, tree arg, int builtin_index)
REAL_VALUE_TYPE r;
if (!validate_arg (arg, REAL_TYPE))
{
error ("non-floating-point argument to function %qs",
IDENTIFIER_POINTER (DECL_NAME (fndecl)));
return error_mark_node;
}
return NULL_TREE;
switch (builtin_index)
{
......@@ -9733,12 +9729,6 @@ fold_builtin_unordered_cmp (tree fndecl, tree arg0, tree arg1,
cmp_type = type0;
else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
cmp_type = type1;
else
{
error ("non-floating-point argument to function %qs",
IDENTIFIER_POINTER (DECL_NAME (fndecl)));
return error_mark_node;
}
arg0 = fold_convert (cmp_type, arg0);
arg1 = fold_convert (cmp_type, arg1);
......@@ -10087,15 +10077,6 @@ fold_builtin_1 (tree fndecl, tree arg0, bool ignore)
case BUILT_IN_ISNAND128:
return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISNAN);
case BUILT_IN_ISNORMAL:
if (!validate_arg (arg0, REAL_TYPE))
{
error ("non-floating-point argument to function %qs",
IDENTIFIER_POINTER (DECL_NAME (fndecl)));
return error_mark_node;
}
break;
case BUILT_IN_PRINTF:
case BUILT_IN_PRINTF_UNLOCKED:
case BUILT_IN_VPRINTF:
......@@ -10441,55 +10422,8 @@ fold_builtin_4 (tree fndecl, tree arg0, tree arg1, tree arg2, tree arg3,
static tree
fold_builtin_n (tree fndecl, tree *args, int nargs, bool ignore)
{
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
tree ret = NULL_TREE;
/* Verify the number of arguments for type-generic and thus variadic
builtins. */
switch (fcode)
{
case BUILT_IN_ISFINITE:
case BUILT_IN_ISINF:
case BUILT_IN_ISNAN:
case BUILT_IN_ISNORMAL:
if (nargs < 1)
{
error ("too few arguments to function %qs",
IDENTIFIER_POINTER (DECL_NAME (fndecl)));
return error_mark_node;
}
else if (nargs > 1)
{
error ("too many arguments to function %qs",
IDENTIFIER_POINTER (DECL_NAME (fndecl)));
return error_mark_node;
}
break;
case BUILT_IN_ISGREATER:
case BUILT_IN_ISGREATEREQUAL:
case BUILT_IN_ISLESS:
case BUILT_IN_ISLESSEQUAL:
case BUILT_IN_ISLESSGREATER:
case BUILT_IN_ISUNORDERED:
if (nargs < 2)
{
error ("too few arguments to function %qs",
IDENTIFIER_POINTER (DECL_NAME (fndecl)));
return error_mark_node;
}
else if (nargs > 2)
{
error ("too many arguments to function %qs",
IDENTIFIER_POINTER (DECL_NAME (fndecl)));
return error_mark_node;
}
break;
default:
break;
}
switch (nargs)
{
case 0:
......
......@@ -6631,6 +6631,85 @@ check_function_arguments_recurse (void (*callback)
(*callback) (ctx, param, param_num);
}
/* Checks the number of arguments NARGS against the required number
REQUIRED and issues an error if there is a mismatch. Returns true
if the number of arguments is correct, otherwise false. */
static bool
validate_nargs (tree fndecl, int nargs, int required)
{
if (nargs < required)
{
error ("not enough arguments to function %qE", fndecl);
return false;
}
else if (nargs > required)
{
error ("too many arguments to function %qE", fndecl);
return false;
}
return true;
}
/* Verifies the NARGS arguments ARGS to the builtin function FNDECL.
Returns false if there was an error, otherwise true. */
bool
check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
{
if (!DECL_BUILT_IN (fndecl)
|| DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
return true;
switch (DECL_FUNCTION_CODE (fndecl))
{
case BUILT_IN_CONSTANT_P:
return validate_nargs (fndecl, nargs, 1);
case BUILT_IN_ISFINITE:
case BUILT_IN_ISINF:
case BUILT_IN_ISNAN:
case BUILT_IN_ISNORMAL:
if (validate_nargs (fndecl, nargs, 1))
{
if (TREE_CODE (TREE_TYPE (args[0])) != REAL_TYPE)
{
error ("non-floating-point argument in call to "
"function %qE", fndecl);
return false;
}
return true;
}
return false;
case BUILT_IN_ISGREATER:
case BUILT_IN_ISGREATEREQUAL:
case BUILT_IN_ISLESS:
case BUILT_IN_ISLESSEQUAL:
case BUILT_IN_ISLESSGREATER:
case BUILT_IN_ISUNORDERED:
if (validate_nargs (fndecl, nargs, 2))
{
enum tree_code code0, code1;
code0 = TREE_CODE (TREE_TYPE (args[0]));
code1 = TREE_CODE (TREE_TYPE (args[1]));
if (!((code0 == REAL_TYPE && code1 == REAL_TYPE)
|| (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
|| (code0 == INTEGER_TYPE && code1 == REAL_TYPE)))
{
error ("non-floating-point arguments in call to "
"function %qE", fndecl);
return false;
}
return true;
}
return false;
default:
return true;
}
}
/* Function to help qsort sort FIELD_DECLs by name order. */
int
......
......@@ -666,6 +666,7 @@ extern void check_function_arguments_recurse (void (*)
unsigned HOST_WIDE_INT),
void *, tree,
unsigned HOST_WIDE_INT);
extern bool check_builtin_function_arguments (tree, int, tree *);
extern void check_function_format (tree, int, tree *);
extern void set_Wformat (int);
extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
......
......@@ -2443,8 +2443,14 @@ build_function_call (tree function, tree params)
if (nargs < 0)
return error_mark_node;
/* Check that the arguments to the function are valid. */
/* Check that arguments to builtin functions match the expectations. */
if (fundecl
&& DECL_BUILT_IN (fundecl)
&& DECL_BUILT_IN_CLASS (fundecl) == BUILT_IN_NORMAL
&& !check_builtin_function_arguments (fundecl, nargs, argarray))
return error_mark_node;
/* Check that the arguments to the function are valid. */
check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray,
TYPE_ARG_TYPES (fntype));
......
2008-04-24 Richard Guenther <rguenther@suse.de>
* typeck.c (cp_build_function_call): Call
check_builtin_function_arguments.
2008-04-23 Paolo Bonzini <bonzini@gnu.org>
* typeck.c (get_member_function_from_ptrfunc): Don't set TREE_INVARIANT.
......
......@@ -2889,9 +2889,15 @@ cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
if (nargs < 0)
return error_mark_node;
/* Check that arguments to builtin functions match the expectations. */
if (fndecl
&& DECL_BUILT_IN (fndecl)
&& DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
&& !check_builtin_function_arguments (fndecl, nargs, argarray))
return error_mark_node;
/* Check for errors in format strings and inappropriately
null parameters. */
check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray,
parm_types);
......
2008-04-24 Richard Guenther <rguenther@suse.de>
* gcc.dg/builtin-constant_p-1.c: New testcase.
* gcc.dg/builtin-errors.c: Adjust expected error.
2008-04-24 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/36008
/* { dg-do compile } */
int main()
{
if (__builtin_constant_p ()) /* { dg-error "not enough" } */
return 0;
if (__builtin_constant_p (5, 6)) /* { dg-error "too many" } */
return 1;
return 0;
}
......@@ -9,7 +9,7 @@ int test1(struct X x)
int test2(double x)
{
return __builtin_isgreater(x); /* { dg-error "too few arguments" } */
return __builtin_isgreater(x); /* { dg-error "not enough arguments" } */
}
int test3(double x)
......
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