aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/builtins.c68
-rw-r--r--gcc/c-common.c79
-rw-r--r--gcc/c-common.h1
-rw-r--r--gcc/c-typeck.c8
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/typeck.c8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/builtin-constant_p-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/builtins-error.c2
10 files changed, 128 insertions, 70 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5751c5d..c7b850a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+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
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 5b02d8b..54cbde5 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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:
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 6db6f3e..36e1c3d 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -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
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 3ca3c8b..c403bee 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -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 *);
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 0b1e285..2f84282 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -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));
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index af183b9..cb7e422 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+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.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 4a5039e..cd733bf 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 01c423c..c747fc1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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
diff --git a/gcc/testsuite/gcc.dg/builtin-constant_p-1.c b/gcc/testsuite/gcc.dg/builtin-constant_p-1.c
new file mode 100644
index 0000000..b0b34f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-constant_p-1.c
@@ -0,0 +1,10 @@
+/* { 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;
+}
diff --git a/gcc/testsuite/gcc.dg/builtins-error.c b/gcc/testsuite/gcc.dg/builtins-error.c
index 6acc215..9f401bb 100644
--- a/gcc/testsuite/gcc.dg/builtins-error.c
+++ b/gcc/testsuite/gcc.dg/builtins-error.c
@@ -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)