diff options
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r-- | gcc/tree-ssa-alias.c | 60 |
1 files changed, 52 insertions, 8 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 10c529b..82307de 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)) |