From 833229510cb13aa643a6005f60882daec616e2b7 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Thu, 24 Apr 2008 16:18:46 +0000 Subject: [PATCH] c-common.h (check_builtin_function_arguments): Declare. 2008-04-24 Richard Guenther * 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 --- gcc/ChangeLog | 12 ++++ gcc/builtins.c | 68 +----------------- gcc/c-common.c | 79 +++++++++++++++++++++ gcc/c-common.h | 1 + gcc/c-typeck.c | 8 ++- gcc/cp/ChangeLog | 5 ++ gcc/cp/typeck.c | 8 ++- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/builtin-constant_p-1.c | 10 +++ gcc/testsuite/gcc.dg/builtins-error.c | 2 +- 10 files changed, 128 insertions(+), 70 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/builtin-constant_p-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5751c5d10df..c7b850aa4ac 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2008-04-24 Richard Guenther + + * 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 PR tree-optimization/36008 diff --git a/gcc/builtins.c b/gcc/builtins.c index 5b02d8bc6ed..54cbde53e0e 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 6db6f3e9ac8..36e1c3d3442 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 3ca3c8bf0c4..c403bee6343 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 0b1e2852f11..2f8428210d7 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 af183b927a1..cb7e4226dce 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2008-04-24 Richard Guenther + + * typeck.c (cp_build_function_call): Call + check_builtin_function_arguments. + 2008-04-23 Paolo Bonzini * 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 4a5039e7942..cd733bfe326 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 01c423c6667..c747fc1a631 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-04-24 Richard Guenther + + * gcc.dg/builtin-constant_p-1.c: New testcase. + * gcc.dg/builtin-errors.c: Adjust expected error. + 2008-04-24 Jakub Jelinek 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 00000000000..b0b34f4a1e1 --- /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 6acc215a97f..9f401bba1a0 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) -- 2.30.2