builtins.c (expand_builtin_sprintf): Use c_getstr and strlen to obtain the format string instead of using...
* 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
This commit is contained in:
parent
34cd7ff698
commit
6ba701c8e9
@ -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>
|
2003-06-26 Richard Henderson <rth@redhat.com>
|
||||||
|
|
||||||
* config/ia64/ia64.h (REGISTER_NAMES): R0 is really AP.
|
* config/ia64/ia64.h (REGISTER_NAMES): R0 is really AP.
|
||||||
|
@ -4492,8 +4492,8 @@ expand_builtin_cabs (tree arglist, rtx target)
|
|||||||
static rtx
|
static rtx
|
||||||
expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
|
expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
|
||||||
{
|
{
|
||||||
tree dest, fmt, stripped;
|
tree orig_arglist, dest, fmt;
|
||||||
tree orig_arglist;
|
const char *fmt_str;
|
||||||
|
|
||||||
orig_arglist = arglist;
|
orig_arglist = arglist;
|
||||||
|
|
||||||
@ -4512,36 +4512,33 @@ expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
|
|||||||
arglist = TREE_CHAIN (arglist);
|
arglist = TREE_CHAIN (arglist);
|
||||||
|
|
||||||
/* Check whether the format is a literal string constant. */
|
/* Check whether the format is a literal string constant. */
|
||||||
stripped = fmt;
|
fmt_str = c_getstr (fmt);
|
||||||
STRIP_NOPS (stripped);
|
if (fmt_str == NULL)
|
||||||
if (stripped && TREE_CODE (stripped) == ADDR_EXPR)
|
|
||||||
stripped = TREE_OPERAND (stripped, 0);
|
|
||||||
if (TREE_CODE (stripped) != STRING_CST)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* If the format doesn't contain % args or %%, use strcpy. */
|
/* 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 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
|
||||||
tree exp;
|
tree exp;
|
||||||
|
|
||||||
if (arglist || !fn)
|
if (arglist || ! fn)
|
||||||
return 0;
|
return 0;
|
||||||
expand_expr (build_function_call_expr (fn, orig_arglist),
|
expand_expr (build_function_call_expr (fn, orig_arglist),
|
||||||
const0_rtx, VOIDmode, EXPAND_NORMAL);
|
const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||||
if (target == const0_rtx)
|
if (target == const0_rtx)
|
||||||
return 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));
|
exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
|
||||||
return expand_expr (exp, target, mode, EXPAND_NORMAL);
|
return expand_expr (exp, target, mode, EXPAND_NORMAL);
|
||||||
}
|
}
|
||||||
/* If the format is "%s", use strcpy and possibly strlen. */
|
/* If the format is "%s", use strcpy if the result isn't used. */
|
||||||
else if (strcmp (TREE_STRING_POINTER (stripped), "%s") == 0)
|
else if (strcmp (fmt_str, "%s") == 0)
|
||||||
{
|
{
|
||||||
tree strcpy_fn, strlen_fn, exp, arg;
|
tree fn, arg, len;
|
||||||
strcpy_fn = implicit_built_in_decls[BUILT_IN_STRCPY];
|
fn = implicit_built_in_decls[BUILT_IN_STRCPY];
|
||||||
|
|
||||||
if (! strcpy_fn)
|
if (! fn)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (! arglist || TREE_CHAIN (arglist))
|
if (! arglist || TREE_CHAIN (arglist))
|
||||||
@ -4552,25 +4549,21 @@ expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
|
|||||||
|
|
||||||
if (target != const0_rtx)
|
if (target != const0_rtx)
|
||||||
{
|
{
|
||||||
strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
|
len = c_strlen (arg);
|
||||||
if (! strlen_fn)
|
if (! len || TREE_CODE (len) != INTEGER_CST)
|
||||||
return 0;
|
return 0;
|
||||||
arg = save_expr (arg);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strlen_fn = 0;
|
len = NULL_TREE;
|
||||||
|
|
||||||
arglist = build_tree_list (NULL_TREE, arg);
|
arglist = build_tree_list (NULL_TREE, arg);
|
||||||
arglist = tree_cons (NULL_TREE, dest, arglist);
|
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);
|
const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||||
|
|
||||||
if (target == const0_rtx)
|
if (target == const0_rtx)
|
||||||
return const0_rtx;
|
return const0_rtx;
|
||||||
|
return expand_expr (len, target, mode, EXPAND_NORMAL);
|
||||||
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 0;
|
return 0;
|
||||||
|
@ -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>
|
2003-06-26 J"orn Rennecke <joern.rennecke@superh.com>
|
||||||
|
|
||||||
* gcc.c-torture/execute/multi-ix.c: New test.
|
* gcc.c-torture/execute/multi-ix.c: New test.
|
||||||
|
13
gcc/testsuite/gcc.c-torture/execute/20030626-1.c
Normal file
13
gcc/testsuite/gcc.c-torture/execute/20030626-1.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
14
gcc/testsuite/gcc.c-torture/execute/20030626-2.c
Normal file
14
gcc/testsuite/gcc.c-torture/execute/20030626-2.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -38,10 +38,6 @@ void test5(char *ptr)
|
|||||||
sprintf(buffer,"%s",ptr);
|
sprintf(buffer,"%s",ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int test6(char *ptr)
|
|
||||||
{
|
|
||||||
return sprintf(buffer,"%s",ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -72,12 +68,6 @@ int main()
|
|||||||
if (memcmp(buffer, "barf", 5) || buffer[5] != 'A')
|
if (memcmp(buffer, "barf", 5) || buffer[5] != 'A')
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
memset (buffer, 'A', 32);
|
|
||||||
if (test6 ("barf") != 4)
|
|
||||||
abort ();
|
|
||||||
if (memcmp(buffer, "barf", 5) || buffer[5] != 'A')
|
|
||||||
abort ();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user