diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-01-20 19:18:21 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-01-20 19:18:21 +0100 |
commit | 9a7eefec743956cfd72de8e2f5e1d42be4f7d20d (patch) | |
tree | 840adcd5d5e2cbfaf6b57c07e9227d984e6650a1 /gcc/builtins.c | |
parent | 3e7291458b963d37a9253cd5319ec50d292d5e72 (diff) | |
download | gcc-9a7eefec743956cfd72de8e2f5e1d42be4f7d20d.zip gcc-9a7eefec743956cfd72de8e2f5e1d42be4f7d20d.tar.gz gcc-9a7eefec743956cfd72de8e2f5e1d42be4f7d20d.tar.bz2 |
re PR tree-optimization/59860 (ICE in compute_may_aliases, at tree-ssa-structalias.c:6843)
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.
From-SVN: r206848
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 c597e44..d2ea606 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; |