[PATCH] Fix ccp_fold_builtin (PR middle-end/38360)

Jakub Jelinek jakub@redhat.com
Tue Dec 2 10:25:00 GMT 2008


Hi!

When the various builtin folders have been changed to accept the individual
arguments rather than a CALL from which the number of arguments could be
checked as well, it is caller's responsibility to check the number of
arguments.  fold_call_expr/fold_builtin_n does that by separating the
folders into fold_builtin_{0,1,2,3} etc., so for wrong number of arguments
folding isn't attempted.  But in ccp_fold_builtin only a few calls have
been changed to verify the number of arguments first, before accessing
the individual gimple_call_arg arguments.  In 4.4 we ICE because
gimple_call_arg checks that the argument number isn't greater or equal
to nargs, in 4.3 we ICEd because CALL_EXPR_ARG reads some random value from
memory after the call arguments (if it happened to be valid tree or NULL,
it likely wouldn't be validated by validate_arg, but if it is random
garbage, it can segfault).
I've been able to reproduce this only with fputs and fputs_unlocked
(supposedly because the compiler doesn't have builtin FILE type and so
needs to be forgiving), for other calls trying to call them with
wrong number of arguments when not prototyped resulted in errors,
but I think it is safer to check it always.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2008-12-02  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/38360
	* tree-ssa-ccp.c (ccp_fold_builtin): Bail out if the builtin doesn't
	have the right number of arguments.

	* gcc.c-torture/compile/pr38360.c: New test.

--- gcc/tree-ssa-ccp.c.jj	2008-11-10 10:28:26.000000000 +0100
+++ gcc/tree-ssa-ccp.c	2008-12-02 09:06:08.000000000 +0100
@@ -2517,6 +2517,9 @@ ccp_fold_builtin (gimple stmt)
       return NULL_TREE;
     }
 
+  if (arg_idx >= nargs)
+    return NULL_TREE;
+
   /* Try to use the dataflow information gathered by the CCP process.  */
   visited = BITMAP_ALLOC (NULL);
   bitmap_clear (visited);
@@ -2532,7 +2535,7 @@ ccp_fold_builtin (gimple stmt)
   switch (DECL_FUNCTION_CODE (callee))
     {
     case BUILT_IN_STRLEN:
-      if (val[0])
+      if (val[0] && nargs == 1)
 	{
 	  tree new_val =
               fold_convert (TREE_TYPE (gimple_call_lhs (stmt)), val[0]);
@@ -2564,22 +2567,24 @@ ccp_fold_builtin (gimple stmt)
       break;
 
     case BUILT_IN_FPUTS:
-      result = fold_builtin_fputs (gimple_call_arg (stmt, 0),
-                                   gimple_call_arg (stmt, 1),
-				   ignore, false, val[0]);
+      if (nargs == 2)
+	result = fold_builtin_fputs (gimple_call_arg (stmt, 0),
+				     gimple_call_arg (stmt, 1),
+				     ignore, false, val[0]);
       break;
 
     case BUILT_IN_FPUTS_UNLOCKED:
-      result = fold_builtin_fputs (gimple_call_arg (stmt, 0),
-				   gimple_call_arg (stmt, 1),
-                                   ignore, true, val[0]);
+      if (nargs == 2)
+	result = fold_builtin_fputs (gimple_call_arg (stmt, 0),
+				     gimple_call_arg (stmt, 1),
+				     ignore, true, val[0]);
       break;
 
     case BUILT_IN_MEMCPY_CHK:
     case BUILT_IN_MEMPCPY_CHK:
     case BUILT_IN_MEMMOVE_CHK:
     case BUILT_IN_MEMSET_CHK:
-      if (val[2] && is_gimple_val (val[2]))
+      if (val[2] && is_gimple_val (val[2]) && nargs == 4)
 	result = fold_builtin_memory_chk (callee,
                                           gimple_call_arg (stmt, 0),
                                           gimple_call_arg (stmt, 1),
@@ -2591,7 +2596,7 @@ ccp_fold_builtin (gimple stmt)
 
     case BUILT_IN_STRCPY_CHK:
     case BUILT_IN_STPCPY_CHK:
-      if (val[1] && is_gimple_val (val[1]))
+      if (val[1] && is_gimple_val (val[1]) && nargs == 3)
 	result = fold_builtin_stxcpy_chk (callee,
                                           gimple_call_arg (stmt, 0),
                                           gimple_call_arg (stmt, 1),
@@ -2601,7 +2606,7 @@ ccp_fold_builtin (gimple stmt)
       break;
 
     case BUILT_IN_STRNCPY_CHK:
-      if (val[2] && is_gimple_val (val[2]))
+      if (val[2] && is_gimple_val (val[2]) && nargs == 4)
 	result = fold_builtin_strncpy_chk (gimple_call_arg (stmt, 0),
                                            gimple_call_arg (stmt, 1),
                                            gimple_call_arg (stmt, 2),
--- gcc/testsuite/gcc.c-torture/compile/pr38360.c.jj	2008-12-02 09:08:46.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr38360.c	2008-12-02 09:08:24.000000000 +0100
@@ -0,0 +1,9 @@
+/* PR middle-end/38360 */
+
+int
+main ()
+{
+  fputs ("");
+  fputs_unlocked ("");
+  return 0;
+}

	Jakub



More information about the Gcc-patches mailing list