]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
builtins.c (expand_builtin_sprintf): Use c_getstr and strlen to obtain the format...
authorRoger Sayle <roger@eyesopen.com>
Fri, 27 Jun 2003 02:50:19 +0000 (02:50 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Fri, 27 Jun 2003 02:50:19 +0000 (02:50 +0000)
* builtins.c (expand_builtin_sprintf): Use c_getstr and strlen to
obtain the format string instead of using TREE_STRING_POINTER and
TREE_STRING_LENGTH.  Only optimize sprintf(dst,"%s",src) when the
return value is unused or the length of src is a known constant.

* gcc.c-torture/execute/string-opt-16.c: Remove test for disabled
sprintf(dst,"%s",src) optimization.
* gcc.c-torture/execute/20030626-1.c: New test case.
* gcc.c-torture/execute/20030626-2.c: New test case.

Co-Authored-By: Jakub Jelinek <jakub@redhat.com>
From-SVN: r68555

gcc/ChangeLog
gcc/builtins.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20030626-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/20030626-2.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/string-opt-16.c

index 90789f4935963b1d56aac12b5381b8f28ccfc1a7..f06e8a6ef66d1aa4864961e1e5677b3d861a6c6d 100644 (file)
@@ -1,3 +1,11 @@
+2003-06-26  Roger Sayle  <roger@eyesopen.com>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       * builtins.c (expand_builtin_sprintf): Use c_getstr and strlen to
+       obtain the format string instead of using TREE_STRING_POINTER and
+       TREE_STRING_LENGTH.  Only optimize sprintf(dst,"%s",src) when the
+       return value is unused or the length of src is a known constant.
+
 2003-06-26  Richard Henderson  <rth@redhat.com>
 
        * config/ia64/ia64.h (REGISTER_NAMES): R0 is really AP.
index 3872fd56c503facce82e28baef045042cda9822e..44ecbdedcf2938ac3fcd24eb59b934f3fa0b5f64 100644 (file)
@@ -4492,8 +4492,8 @@ expand_builtin_cabs (tree arglist, rtx target)
 static rtx
 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
 {
-  tree dest, fmt, stripped;
-  tree orig_arglist;
+  tree orig_arglist, dest, fmt;
+  const char *fmt_str;
 
   orig_arglist = arglist;
 
@@ -4512,36 +4512,33 @@ expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
   arglist = TREE_CHAIN (arglist);
 
   /* Check whether the format is a literal string constant.  */
-  stripped = fmt;
-  STRIP_NOPS (stripped);
-  if (stripped && TREE_CODE (stripped) == ADDR_EXPR)
-    stripped = TREE_OPERAND (stripped, 0);
-  if (TREE_CODE (stripped) != STRING_CST)
+  fmt_str = c_getstr (fmt);
+  if (fmt_str == NULL)
     return 0;
 
   /* If the format doesn't contain % args or %%, use strcpy.  */
-  if (strchr (TREE_STRING_POINTER (stripped), '%') == 0)
+  if (strchr (fmt_str, '%') == 0)
     {
       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
       tree exp;
 
-      if (arglist || !fn)
+      if (arglist || ! fn)
        return 0;
       expand_expr (build_function_call_expr (fn, orig_arglist),
                   const0_rtx, VOIDmode, EXPAND_NORMAL);
       if (target == const0_rtx)
        return const0_rtx;
-      exp = build_int_2 (TREE_STRING_LENGTH (stripped) - 1, 0);
+      exp = build_int_2 (strlen (fmt_str), 0);
       exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
       return expand_expr (exp, target, mode, EXPAND_NORMAL);
     }
-  /* If the format is "%s", use strcpy and possibly strlen.  */
-  else if (strcmp (TREE_STRING_POINTER (stripped), "%s") == 0)
+  /* If the format is "%s", use strcpy if the result isn't used.  */
+  else if (strcmp (fmt_str, "%s") == 0)
     {
-      tree strcpy_fn, strlen_fn, exp, arg;
-      strcpy_fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+      tree fn, arg, len;
+      fn = implicit_built_in_decls[BUILT_IN_STRCPY];
 
-      if (! strcpy_fn)
+      if (! fn)
        return 0;
 
       if (! arglist || TREE_CHAIN (arglist))
@@ -4552,25 +4549,21 @@ expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
 
       if (target != const0_rtx)
        {
-         strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
-         if (! strlen_fn)
+         len = c_strlen (arg);
+         if (! len || TREE_CODE (len) != INTEGER_CST)
            return 0;
-         arg = save_expr (arg);
        }
       else
-       strlen_fn = 0;
+       len = NULL_TREE;
 
       arglist = build_tree_list (NULL_TREE, arg);
       arglist = tree_cons (NULL_TREE, dest, arglist);
-      expand_expr (build_function_call_expr (strcpy_fn, arglist),
+      expand_expr (build_function_call_expr (fn, arglist),
                   const0_rtx, VOIDmode, EXPAND_NORMAL);
 
       if (target == const0_rtx)
        return const0_rtx;
-
-      exp = build_function_call_expr (strlen_fn, TREE_CHAIN (arglist));
-      exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
-      return expand_expr (exp, target, mode, EXPAND_NORMAL);
+      return expand_expr (len, target, mode, EXPAND_NORMAL);
     }
 
   return 0;
index df08e070e654b913e7379d9385b7e4a2c471d30e..51bed0425d697591054716abaadbd2a3c46c76b6 100644 (file)
@@ -1,3 +1,11 @@
+2003-06-26  Roger Sayle  <roger@eyesopen.com>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.c-torture/execute/string-opt-16.c: Remove test for disabled
+       sprintf(dst,"%s",src) optimization.
+       * gcc.c-torture/execute/20030626-1.c: New test case.
+       * gcc.c-torture/execute/20030626-2.c: New test case.
+
 2003-06-26  J"orn Rennecke <joern.rennecke@superh.com>
 
        * gcc.c-torture/execute/multi-ix.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030626-1.c b/gcc/testsuite/gcc.c-torture/execute/20030626-1.c
new file mode 100644 (file)
index 0000000..8b985f0
--- /dev/null
@@ -0,0 +1,13 @@
+char buf[10];
+
+extern void abort (void);
+extern int sprintf (char*, const char*, ...);
+
+int main()
+{
+  int l = sprintf (buf, "foo\0bar");
+  if (l != 3)
+    abort ();
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030626-2.c b/gcc/testsuite/gcc.c-torture/execute/20030626-2.c
new file mode 100644 (file)
index 0000000..5483d0c
--- /dev/null
@@ -0,0 +1,14 @@
+char buf[40];
+
+extern int sprintf (char*, const char*, ...);
+extern void abort (void);
+
+int main()
+{
+  int i = 0;
+  int l = sprintf (buf, "%s", i++ ? "string" : "other string");
+  if (l != sizeof ("other string") - 1 || i != 1)
+    abort ();
+  return 0;
+}
+
index 82f3c418cd077725fbfb646b183e5ccee454f79e..8556b8f6517015fac07bdf51aca428fee28d19b6 100644 (file)
@@ -38,10 +38,6 @@ void test5(char *ptr)
   sprintf(buffer,"%s",ptr);
 }
 
-int test6(char *ptr)
-{
-  return sprintf(buffer,"%s",ptr);
-}
 
 int main()
 {
@@ -72,12 +68,6 @@ int main()
   if (memcmp(buffer, "barf", 5) || buffer[5] != 'A')
     abort ();
 
-  memset (buffer, 'A', 32);
-  if (test6 ("barf") != 4)
-    abort ();
-  if (memcmp(buffer, "barf", 5) || buffer[5] != 'A')
-    abort ();
-
   return 0;
 }