diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/builtins.c | 57 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtins-error.c | 18 |
4 files changed, 86 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0916b1c..86f1f69 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2007-11-27 Richard Guenther <rguenther@suse.de> + + * builtins.c (fold_builtin_1): Verify the argument types + of BUILT_IN_ISNORMAL. + (fold_builtin_n): Verify the number of arguments to variadic + built-in functions. + 2007-11-27 Bernd Schmidt <bernd.schmidt@analog.com> * config/bfin/elf.h (SUBTARGET_DRIVER_SELF_SPECS): New macro. diff --git a/gcc/builtins.c b/gcc/builtins.c index 1eb6cfc..5befd42 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -10063,6 +10063,15 @@ 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: @@ -10408,7 +10417,55 @@ 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/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 10ce3a5..a3c26bf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-11-27 Richard Guenther <rguenther@suse.de> + + * gcc.dg/builtins-error.c: New testcase. + 2007-11-27 Jakub Jelinek <jakub@redhat.com> PR c++/34213 diff --git a/gcc/testsuite/gcc.dg/builtins-error.c b/gcc/testsuite/gcc.dg/builtins-error.c new file mode 100644 index 0000000..6acc215 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtins-error.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +struct X { int x; }; + +int test1(struct X x) +{ + return __builtin_isnormal(x); /* { dg-error "non-floating-point argument" } */ +} + +int test2(double x) +{ + return __builtin_isgreater(x); /* { dg-error "too few arguments" } */ +} + +int test3(double x) +{ + return __builtin_isinf(x, x); /* { dg-error "too many arguments" } */ +} |