c-common.h (check_builtin_function_arguments): Declare.
authorRichard Guenther <rguenther@suse.de>
Thu, 24 Apr 2008 16:18:46 +0000 (16:18 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 24 Apr 2008 16:18:46 +0000 (16:18 +0000)
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

gcc/ChangeLog
gcc/builtins.c
gcc/c-common.c
gcc/c-common.h
gcc/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/builtin-constant_p-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/builtins-error.c

index 5751c5d10dfb2a0db57c69659b52d8d0a8c4c3ff..c7b850aa4ac82606810385d8026d1ae1bee90df2 100644 (file)
@@ -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
index 5b02d8bc6ed70e8e40192c9fb2c352af80f3be82..54cbde53e0e8cc231fa11651bb792ac472609c24 100644 (file)
@@ -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:
index 6db6f3e9ac8c0c612973ad4d4b2ee34ca159d6b9..36e1c3d34421e0f6342386baa70e5a3fc6643965 100644 (file)
@@ -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
index 3ca3c8bf0c4ec33e20eb440ca8b9c044c77747de..c403bee634392547d6058a799d3ea96abaea1cb1 100644 (file)
@@ -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 *);
index 0b1e2852f11af9be3c3b65f90f1721ca830c962d..2f8428210d708a7c81baee24bbd9e16d2cd446bb 100644 (file)
@@ -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));
 
index af183b927a10cb657fa0317be72258490e9fc11f..cb7e4226dce2503a5ab1186c9313e01098a2aa42 100644 (file)
@@ -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.
index 4a5039e7942c6be19977b2201e6e41e90af821e7..cd733bfe326d12fc71b85032d69ac8c3d7eb6504 100644 (file)
@@ -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);
 
index 01c423c66678b6bc6a783e8406e68a7b5380ec15..c747fc1a631341a1f898e7c92bdf42fd530c4819 100644 (file)
@@ -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 (file)
index 0000000..b0b34f4
--- /dev/null
@@ -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;
+}
index 6acc215a97f33fcb2e24a6aa34d3823073ce5caa..9f401bba1a02ca377083157a3eb58de950226028 100644 (file)
@@ -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)