summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-alias.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-09-30 16:58:27 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-09-30 16:58:27 +0200
commit915afed63edcfbc614b3357d0862a4124a156d3a (patch)
tree547d9c6e16c8da1b5c7e98044325a0f5be53cc1e /gcc/tree-ssa-alias.c
parent49f836ba6fdf80354f675af50837fbdb7144e081 (diff)
downloadgcc-915afed63edcfbc614b3357d0862a4124a156d3a.tar.gz
tree-ssa-structalias.c (find_func_aliases_for_builtin_call): Handle BUILT_IN_STRDUP and BUILT_IN_STRNDUP.
* tree-ssa-structalias.c (find_func_aliases_for_builtin_call): Handle BUILT_IN_STRDUP and BUILT_IN_STRNDUP. * tree-ssa-alias.c (call_may_clobber_ref_p_1): Likewise. Fix handling of BUILT_IN_STRNCAT and BUILT_IN_STRNCAT_CHK. (ref_maybe_used_by_call_p_1): Fix handling of BUILT_IN_STRCAT, BUILT_IN_STRNCAT, BUILT_IN_STRCAT_CHK and BUILT_IN_STRNCAT_CHK. * gcc.dg/strlenopt-21.c: New test. Co-Authored-By: Richard Guenther <rguenther@suse.de> From-SVN: r179387
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r--gcc/tree-ssa-alias.c60
1 files changed, 52 insertions, 8 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 10c529b114f..82307decaf4 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -1178,8 +1178,20 @@ ref_maybe_used_by_call_p_1 (gimple call, ao_ref *ref)
&& DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
switch (DECL_FUNCTION_CODE (callee))
{
- /* All the following functions clobber memory pointed to by
- their first argument. */
+ /* All the following functions read memory pointed to by
+ their second argument. strcat/strncat additionally
+ reads memory pointed to by the first argument. */
+ case BUILT_IN_STRCAT:
+ case BUILT_IN_STRNCAT:
+ {
+ ao_ref dref;
+ ao_ref_init_from_ptr_and_size (&dref,
+ gimple_call_arg (call, 0),
+ NULL_TREE);
+ if (refs_may_alias_p_1 (&dref, ref, false))
+ return true;
+ }
+ /* FALLTHRU */
case BUILT_IN_STRCPY:
case BUILT_IN_STRNCPY:
case BUILT_IN_MEMCPY:
@@ -1187,8 +1199,6 @@ ref_maybe_used_by_call_p_1 (gimple call, ao_ref *ref)
case BUILT_IN_MEMPCPY:
case BUILT_IN_STPCPY:
case BUILT_IN_STPNCPY:
- case BUILT_IN_STRCAT:
- case BUILT_IN_STRNCAT:
{
ao_ref dref;
tree size = NULL_TREE;
@@ -1199,14 +1209,23 @@ ref_maybe_used_by_call_p_1 (gimple call, ao_ref *ref)
size);
return refs_may_alias_p_1 (&dref, ref, false);
}
+ case BUILT_IN_STRCAT_CHK:
+ case BUILT_IN_STRNCAT_CHK:
+ {
+ ao_ref dref;
+ ao_ref_init_from_ptr_and_size (&dref,
+ gimple_call_arg (call, 0),
+ NULL_TREE);
+ if (refs_may_alias_p_1 (&dref, ref, false))
+ return true;
+ }
+ /* FALLTHRU */
case BUILT_IN_STRCPY_CHK:
case BUILT_IN_STRNCPY_CHK:
case BUILT_IN_MEMCPY_CHK:
case BUILT_IN_MEMMOVE_CHK:
case BUILT_IN_MEMPCPY_CHK:
case BUILT_IN_STPCPY_CHK:
- case BUILT_IN_STRCAT_CHK:
- case BUILT_IN_STRNCAT_CHK:
{
ao_ref dref;
tree size = NULL_TREE;
@@ -1226,6 +1245,19 @@ ref_maybe_used_by_call_p_1 (gimple call, ao_ref *ref)
size);
return refs_may_alias_p_1 (&dref, ref, false);
}
+ /* These read memory pointed to by the first argument. */
+ case BUILT_IN_STRDUP:
+ case BUILT_IN_STRNDUP:
+ {
+ ao_ref dref;
+ tree size = NULL_TREE;
+ if (gimple_call_num_args (call) == 2)
+ size = gimple_call_arg (call, 1);
+ ao_ref_init_from_ptr_and_size (&dref,
+ gimple_call_arg (call, 0),
+ size);
+ return refs_may_alias_p_1 (&dref, ref, false);
+ }
/* The following builtins do not read from memory. */
case BUILT_IN_FREE:
case BUILT_IN_MALLOC:
@@ -1467,7 +1499,12 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref)
{
ao_ref dref;
tree size = NULL_TREE;
- if (gimple_call_num_args (call) == 3)
+ /* Don't pass in size for strncat, as the maximum size
+ is strlen (dest) + n + 1 instead of n, resp.
+ n + 1 at dest + strlen (dest), but strlen (dest) isn't
+ known. */
+ if (gimple_call_num_args (call) == 3
+ && DECL_FUNCTION_CODE (callee) != BUILT_IN_STRNCAT)
size = gimple_call_arg (call, 2);
ao_ref_init_from_ptr_and_size (&dref,
gimple_call_arg (call, 0),
@@ -1486,7 +1523,12 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref)
{
ao_ref dref;
tree size = NULL_TREE;
- if (gimple_call_num_args (call) == 4)
+ /* Don't pass in size for __strncat_chk, as the maximum size
+ is strlen (dest) + n + 1 instead of n, resp.
+ n + 1 at dest + strlen (dest), but strlen (dest) isn't
+ known. */
+ if (gimple_call_num_args (call) == 4
+ && DECL_FUNCTION_CODE (callee) != BUILT_IN_STRNCAT_CHK)
size = gimple_call_arg (call, 2);
ao_ref_init_from_ptr_and_size (&dref,
gimple_call_arg (call, 0),
@@ -1506,6 +1548,8 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref)
being the definition point for the pointer. */
case BUILT_IN_MALLOC:
case BUILT_IN_CALLOC:
+ case BUILT_IN_STRDUP:
+ case BUILT_IN_STRNDUP:
/* Unix98 specifies that errno is set on allocation failure. */
if (flag_errno_math
&& targetm.ref_may_alias_errno (ref))