diff options
author | Richard Biener <rguenther@suse.de> | 2025-04-30 10:01:47 +0200 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2025-05-05 15:08:18 +0200 |
commit | 169ad482497ae9c672a825050b8f4b6d54cd5d24 (patch) | |
tree | 7b083ec752d72bb00087d3800f99d039bf5f9c4e | |
parent | b36014e10c95d3ada1dcdf4695626af90fba0a99 (diff) | |
download | gcc-169ad482497ae9c672a825050b8f4b6d54cd5d24.zip gcc-169ad482497ae9c672a825050b8f4b6d54cd5d24.tar.gz gcc-169ad482497ae9c672a825050b8f4b6d54cd5d24.tar.bz2 |
ipa/120006 - wrong code with IPA PTA
When PTA gets support for special-handling more builtins in
find_func_aliases the corresponding code in find_func_clobbers
needs updating as well since for unhandled cases it assumes
the former will populate ESCAPED accordingly. The following
fixes a few omissions, the testcase runs into the missing strdup
handling. I believe the more advanced handling using modref
results and fnspecs opened a larger gap, the proper fix is to
merge both functions, gating the clobber/use part on a parameter
to avoid diverging.
PR ipa/120006
* tree-ssa-structalias.cc (find_func_clobbers): Handle
strdup, strndup, realloc, index, strchr, strrchr, memchr,
strstr, strpbrk builtins like find_func_aliases does.
* gcc.dg/torture/pr120006.c: New testcase.
(cherry picked from commit a85b89e26b1f50997701eb428c2dd71668f216ff)
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr120006.c | 31 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.cc | 36 |
2 files changed, 67 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr120006.c b/gcc/testsuite/gcc.dg/torture/pr120006.c new file mode 100644 index 0000000..c067f0e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr120006.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fipa-pta" } */ + +char *b; +int f = 1; + +char *xstrdup(char *i) { + char *c = __builtin_strdup(i); + if (!c) + __builtin_exit(1); + return c; +} + +int main() { + char g; + char h[8]; + + for (int i = 0; i < 2; i++) { + char c = *__builtin_strdup(""); + b = &g; + + if (f) { + h[0] = '-'; + h[1] = 'a'; + h[2] = '\0'; + b = xstrdup(h); + } + } + if (__builtin_strcmp(b, "-a") != 0) + __builtin_abort(); +} diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc index f79b542..3ad0c69 100644 --- a/gcc/tree-ssa-structalias.cc +++ b/gcc/tree-ssa-structalias.cc @@ -5583,6 +5583,42 @@ find_func_clobbers (struct function *fn, gimple *origt) process_ipa_clobber (fi, gimple_call_arg (t, 2)); return; } + /* The following functions use what their first argument + points to. */ + case BUILT_IN_STRDUP: + case BUILT_IN_STRNDUP: + case BUILT_IN_REALLOC: + case BUILT_IN_INDEX: + case BUILT_IN_STRCHR: + case BUILT_IN_STRRCHR: + case BUILT_IN_MEMCHR: + { + tree src = gimple_call_arg (t, 0); + get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc); + lhs = get_function_part_constraint (fi, fi_uses); + struct constraint_expr *rhsp; + FOR_EACH_VEC_ELT (rhsc, i, rhsp) + process_constraint (new_constraint (lhs, *rhsp)); + return; + } + /* The following functions use what their first and second argument + point to. */ + case BUILT_IN_STRSTR: + case BUILT_IN_STRPBRK: + { + tree src = gimple_call_arg (t, 0); + get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc); + lhs = get_function_part_constraint (fi, fi_uses); + struct constraint_expr *rhsp; + FOR_EACH_VEC_ELT (rhsc, i, rhsp) + process_constraint (new_constraint (lhs, *rhsp)); + rhsc.truncate (0); + src = gimple_call_arg (t, 1); + get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc); + FOR_EACH_VEC_ELT (rhsc, i, rhsp) + process_constraint (new_constraint (lhs, *rhsp)); + return; + } /* The following functions neither read nor clobber memory. */ case BUILT_IN_ASSUME_ALIGNED: case BUILT_IN_FREE: |