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);
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);
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))
/* 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;
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;
extern tree fold_builtin_fputs (location_t, tree, tree, bool, bool, tree);
extern tree fold_builtin_strcpy (location_t, tree, tree, tree, tree);
extern tree fold_builtin_strncpy (location_t, tree, tree, tree, tree, tree);
+extern tree fold_builtin_strcat (location_t, tree, tree, tree);
extern tree fold_builtin_memory_chk (location_t, tree, tree, tree, tree, tree, tree, bool,
enum built_in_function);
extern tree fold_builtin_stxcpy_chk (location_t, tree, tree, tree, tree, tree, bool,