This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix missing argument check for isnormal and argument count for other varargs builtins


isnormal() accepts bogus arguments such as structs, leading to eventually
an ICE during expansion.  The other functions are not checked for the
correct number of arguments.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to mainline.

Richard.

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.

	* gcc.dg/builtins-error.c: New testcase.

Index: builtins.c
===================================================================
*** builtins.c	(revision 130436)
--- builtins.c	(working copy)
*************** fold_builtin_1 (tree fndecl, tree arg0, 
*** 10063,10068 ****
--- 10063,10077 ----
      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:
*************** fold_builtin_4 (tree fndecl, tree arg0, 
*** 10408,10414 ****
--- 10417,10471 ----
  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: testsuite/gcc.dg/builtins-error.c
===================================================================
*** testsuite/gcc.dg/builtins-error.c	(revision 0)
--- testsuite/gcc.dg/builtins-error.c	(revision 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" } */
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]