diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-01-20 18:18:21 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-01-20 18:18:21 +0000 |
commit | b65555c1ab475f6a3757b4ecb1a5970e66bde20b (patch) | |
tree | 840adcd5d5e2cbfaf6b57c07e9227d984e6650a1 /gcc/builtins.c | |
parent | 98fbe28d1ea9be47419a759a1e3c0653309f44fb (diff) | |
download | gcc-b65555c1ab475f6a3757b4ecb1a5970e66bde20b.tar.gz |
PR middle-end/59860
* tree.h (fold_builtin_strcat): New prototype.
* builtins.c (fold_builtin_strcat): No longer static. Add len
argument, if non-NULL, don't call c_strlen. Optimize
directly into __builtin_memcpy instead of __builtin_strcpy.
(fold_builtin_2): Adjust fold_builtin_strcat caller.
* gimple-fold.c (gimple_fold_builtin): Handle BUILT_IN_STRCAT.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206848 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index c597e44e58c..d2ea606260b 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -191,7 +191,6 @@ static tree fold_builtin_varargs (location_t, tree, tree, bool); static tree fold_builtin_strpbrk (location_t, tree, tree, tree); static tree fold_builtin_strstr (location_t, tree, tree, tree); static tree fold_builtin_strrchr (location_t, tree, tree, tree); -static tree fold_builtin_strcat (location_t, tree, tree); static tree fold_builtin_strncat (location_t, tree, tree, tree); static tree fold_builtin_strspn (location_t, tree, tree); static tree fold_builtin_strcspn (location_t, tree, tree); @@ -10787,7 +10786,7 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore) return fold_builtin_strstr (loc, arg0, arg1, type); case BUILT_IN_STRCAT: - return fold_builtin_strcat (loc, arg0, arg1); + return fold_builtin_strcat (loc, arg0, arg1, NULL_TREE); case BUILT_IN_STRSPN: return fold_builtin_strspn (loc, arg0, arg1); @@ -11736,8 +11735,9 @@ fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type) COMPOUND_EXPR in the chain will contain the tree for the simplified form of the builtin function call. */ -static tree -fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src) +tree +fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src, + tree len) { if (!validate_arg (dst, POINTER_TYPE) || !validate_arg (src, POINTER_TYPE)) @@ -11755,14 +11755,15 @@ fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src) /* See if we can store by pieces into (dst + strlen(dst)). */ tree newdst, call; tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN); - tree strcpy_fn = builtin_decl_implicit (BUILT_IN_STRCPY); + tree memcpy_fn = builtin_decl_implicit (BUILT_IN_MEMCPY); - if (!strlen_fn || !strcpy_fn) + if (!strlen_fn || !memcpy_fn) return NULL_TREE; /* If the length of the source string isn't computable don't - split strcat into strlen and strcpy. */ - tree len = c_strlen (src, 1); + split strcat into strlen and memcpy. */ + if (! len) + len = c_strlen (src, 1); if (! len || TREE_SIDE_EFFECTS (len)) return NULL_TREE; @@ -11776,7 +11777,11 @@ fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src) newdst = fold_build_pointer_plus_loc (loc, dst, newdst); newdst = builtin_save_expr (newdst); - call = build_call_expr_loc (loc, strcpy_fn, 2, newdst, src); + len = fold_convert_loc (loc, size_type_node, len); + len = size_binop_loc (loc, PLUS_EXPR, len, + build_int_cst (size_type_node, 1)); + + call = build_call_expr_loc (loc, memcpy_fn, 3, newdst, src, len); return build2 (COMPOUND_EXPR, TREE_TYPE (dst), call, dst); } return NULL_TREE; |