re PR c/63554 (ice in "execute_todo, at passes.c:1797" with -O3)
authorRichard Biener <rguenther@suse.de>
Thu, 16 Oct 2014 12:25:52 +0000 (12:25 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 16 Oct 2014 12:25:52 +0000 (12:25 +0000)
2014-10-16  Richard Biener  <rguenther@suse.de>

PR middle-end/63554
* builtins.c (fold_builtin_4): Do not call fold_builtin_strncat_chk.
(fold_builtin_strncat_chk): Move ...
* gimple-fold.c (gimple_fold_builtin_strncat_chk): ... here.
(gimple_fold_builtin): Call gimple_fold_builtin_strncat_chk.

* gcc.dg/torture/pr63554.c: New testcase.

From-SVN: r216315

gcc/ChangeLog
gcc/builtins.c
gcc/gimple-fold.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr63554.c [new file with mode: 0644]

index 94256676d1b67e8b46f58c177602eae82f144e52..9d817c1b24a3cfeb2666a806e6f0a92947fd887e 100644 (file)
@@ -1,3 +1,11 @@
+2014-10-16  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/63554
+       * builtins.c (fold_builtin_4): Do not call fold_builtin_strncat_chk.
+       (fold_builtin_strncat_chk): Move ...
+       * gimple-fold.c (gimple_fold_builtin_strncat_chk): ... here.
+       (gimple_fold_builtin): Call gimple_fold_builtin_strncat_chk.
+
 2014-10-16  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/59401
index 975f696090f54fea1de481ea29c4b584f9ced88c..8d0288fa14a065c7edefa455a85bdb7d35e8e9f1 100644 (file)
@@ -198,7 +198,6 @@ static void maybe_emit_chk_warning (tree, enum built_in_function);
 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
 static void maybe_emit_free_warning (tree);
 static tree fold_builtin_object_size (tree, tree);
-static tree fold_builtin_strncat_chk (location_t, tree, tree, tree, tree, tree);
 static tree fold_builtin_printf (location_t, tree, tree, tree, bool, enum built_in_function);
 static tree fold_builtin_fprintf (location_t, tree, tree, tree, tree, bool,
                                  enum built_in_function);
@@ -10366,9 +10365,6 @@ fold_builtin_4 (location_t loc, tree fndecl,
 
   switch (fcode)
     {
-    case BUILT_IN_STRNCAT_CHK:
-      return fold_builtin_strncat_chk (loc, fndecl, arg0, arg1, arg2, arg3);
-
     case BUILT_IN_FPRINTF_CHK:
     case BUILT_IN_VFPRINTF_CHK:
       if (!validate_arg (arg1, INTEGER_TYPE)
@@ -11584,58 +11580,6 @@ fold_builtin_object_size (tree ptr, tree ost)
   return NULL_TREE;
 }
 
-/* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
-   LEN, and SIZE.  */
-
-static tree
-fold_builtin_strncat_chk (location_t loc, tree fndecl,
-                         tree dest, tree src, tree len, tree size)
-{
-  tree fn;
-  const char *p;
-
-  if (!validate_arg (dest, POINTER_TYPE)
-      || !validate_arg (src, POINTER_TYPE)
-      || !validate_arg (size, INTEGER_TYPE)
-      || !validate_arg (size, INTEGER_TYPE))
-    return NULL_TREE;
-
-  p = c_getstr (src);
-  /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
-  if (p && *p == '\0')
-    return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
-  else if (integer_zerop (len))
-    return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
-
-  if (! tree_fits_uhwi_p (size))
-    return NULL_TREE;
-
-  if (! integer_all_onesp (size))
-    {
-      tree src_len = c_strlen (src, 1);
-      if (src_len
-         && tree_fits_uhwi_p (src_len)
-         && tree_fits_uhwi_p (len)
-         && ! tree_int_cst_lt (len, src_len))
-       {
-         /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
-         fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
-         if (!fn)
-           return NULL_TREE;
-
-         return build_call_expr_loc (loc, fn, 3, dest, src, size);
-       }
-      return NULL_TREE;
-    }
-
-  /* If __builtin_strncat_chk is used, assume strncat is available.  */
-  fn = builtin_decl_explicit (BUILT_IN_STRNCAT);
-  if (!fn)
-    return NULL_TREE;
-
-  return build_call_expr_loc (loc, fn, 3, dest, src, len);
-}
-
 /* Builtins with folding operations that operate on "..." arguments
    need special handling; we need to store the arguments in a convenient
    data structure before attempting any folding.  Fortunately there are
index cc27cb95c5fac35a610bdc1456f0c6d81a2cde15..2c79f8a657322c9a832924972ea2c489593d9cc1 100644 (file)
@@ -1632,6 +1632,62 @@ gimple_fold_builtin_strcat_chk (gimple_stmt_iterator *gsi)
   return true;
 }
 
+/* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
+   LEN, and SIZE.  */
+
+static bool 
+gimple_fold_builtin_strncat_chk (gimple_stmt_iterator *gsi)
+{
+  gimple stmt = gsi_stmt (*gsi);
+  tree dest = gimple_call_arg (stmt, 0);
+  tree src = gimple_call_arg (stmt, 1);
+  tree len = gimple_call_arg (stmt, 2);
+  tree size = gimple_call_arg (stmt, 3);
+  tree fn;
+  const char *p;
+
+  p = c_getstr (src);
+  /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
+  if ((p && *p == '\0')
+      || integer_zerop (len))
+    {
+      replace_call_with_value (gsi, dest);
+      return true;
+    }
+
+  if (! tree_fits_uhwi_p (size))
+    return false;
+
+  if (! integer_all_onesp (size))
+    {
+      tree src_len = c_strlen (src, 1);
+      if (src_len
+         && tree_fits_uhwi_p (src_len)
+         && tree_fits_uhwi_p (len)
+         && ! tree_int_cst_lt (len, src_len))
+       {
+         /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
+         fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
+         if (!fn)
+           return false;
+
+         gimple repl = gimple_build_call (fn, 3, dest, src, size);
+         replace_call_with_call_and_fold (gsi, repl);
+         return true;
+       }
+      return false;
+    }
+
+  /* If __builtin_strncat_chk is used, assume strncat is available.  */
+  fn = builtin_decl_explicit (BUILT_IN_STRNCAT);
+  if (!fn)
+    return false;
+
+  gimple repl = gimple_build_call (fn, 3, dest, src, len);
+  replace_call_with_call_and_fold (gsi, repl);
+  return true;
+}
+
 /* Fold a call to the fputs builtin.  ARG0 and ARG1 are the arguments
    to the call.  IGNORE is true if the value returned
    by the builtin will be ignored.  UNLOCKED is true is true if this
@@ -2457,6 +2513,8 @@ gimple_fold_builtin (gimple_stmt_iterator *gsi)
       return gimple_fold_builtin_sprintf_chk (gsi, DECL_FUNCTION_CODE (callee));
     case BUILT_IN_STRCAT_CHK:
       return gimple_fold_builtin_strcat_chk (gsi);
+    case BUILT_IN_STRNCAT_CHK:
+      return gimple_fold_builtin_strncat_chk (gsi);
     case BUILT_IN_STRLEN:
       return gimple_fold_builtin_strlen (gsi);
     case BUILT_IN_STRCPY:
index d030de341423c56f8c490ee3a6a691128491a729..72ea6213071a6854274572cac0f21b5ac202464a 100644 (file)
@@ -1,3 +1,8 @@
+2014-10-16  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/63554
+       * gcc.dg/torture/pr63554.c: New testcase.
+
 2014-10-16  Marek Polacek  <polacek@redhat.com>
 
        * gcc.target/powerpc/pr58673-1.c: Fix defaulting to int.
diff --git a/gcc/testsuite/gcc.dg/torture/pr63554.c b/gcc/testsuite/gcc.dg/torture/pr63554.c
new file mode 100644 (file)
index 0000000..fa06c5a
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+char *a;
+void
+nssutil_ReadSecmodDB (void)
+{
+  long b = __builtin_object_size (0, 0);
+  a = __builtin___strncat_chk (a, " ", 1, b);
+}