diff options
author | Richard Henderson <rth@redhat.com> | 2005-10-06 13:46:53 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2005-10-06 13:46:53 -0700 |
commit | e2f9fe4298d7cdf587430ecd096d5b3d6b214b76 (patch) | |
tree | b27cc11783abb4d2a33638ffa8c39cee31924335 /gcc | |
parent | 0c7c1604de7009d820bba46fb102b8d3f7d691da (diff) | |
download | gcc-e2f9fe4298d7cdf587430ecd096d5b3d6b214b76.zip gcc-e2f9fe4298d7cdf587430ecd096d5b3d6b214b76.tar.gz gcc-e2f9fe4298d7cdf587430ecd096d5b3d6b214b76.tar.bz2 |
re PR tree-optimization/22237 (struct copy inlining generates overlapping memcpy)
PR tree-opt/22237
* tree-inline.c (declare_return_variable): Handle modify_dest not
being a DECL.
From-SVN: r105057
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/builtins/pr22237-lib.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/builtins/pr22237.c | 44 | ||||
-rw-r--r-- | gcc/tree-inline.c | 19 |
4 files changed, 92 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f7a9c38..79124ff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-10-06 Richard Henderson <rth@redhat.com> + + PR tree-opt/22237 + * tree-inline.c (declare_return_variable): Handle modify_dest not + being a DECL. + 2005-10-06 Daniel Berlin <dberlin@dberlin.org> Fix PR tree-optimization/22488 diff --git a/gcc/testsuite/gcc.c-torture/execute/builtins/pr22237-lib.c b/gcc/testsuite/gcc.c-torture/execute/builtins/pr22237-lib.c new file mode 100644 index 0000000..4403235 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/builtins/pr22237-lib.c @@ -0,0 +1,27 @@ +extern void abort (void); + +void * +memcpy (void *dst, const void *src, __SIZE_TYPE__ n) +{ + const char *srcp; + char *dstp; + + srcp = src; + dstp = dst; + + if (dst < src) + { + if (dst + n > src) + abort (); + } + else + { + if (src + n > dst) + abort (); + } + + while (n-- != 0) + *dstp++ = *srcp++; + + return dst; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/builtins/pr22237.c b/gcc/testsuite/gcc.c-torture/execute/builtins/pr22237.c new file mode 100644 index 0000000..957a47c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/builtins/pr22237.c @@ -0,0 +1,44 @@ +extern void abort (void); +extern void exit (int); +struct s { unsigned char a[256]; }; +union u { struct { struct s b; int c; } d; struct { int c; struct s b; } e; }; +static union u v; +static union u v0; +static struct s *p = &v.d.b; +static struct s *q = &v.e.b; + +static inline struct s rp (void) { return *p; } +static inline struct s rq (void) { return *q; } +static void pq (void) { *p = rq(); } +static void qp (void) { *q = rp(); } + +static void +init (struct s *sp) +{ + int i; + for (i = 0; i < 256; i++) + sp->a[i] = i; +} + +static void +check (struct s *sp) +{ + int i; + for (i = 0; i < 256; i++) + if (sp->a[i] != i) + abort (); +} + +void +main_test (void) +{ + v = v0; + init (p); + qp (); + check (q); + v = v0; + init (q); + pq (); + check (p); + exit (0); +} diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index afec40d..f22785c 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1260,10 +1260,21 @@ declare_return_variable (inline_data *id, tree return_slot_addr, /* If the callee cannot possibly modify MODIFY_DEST, then we can reuse it as the result of the call directly. Don't do this if it would promote MODIFY_DEST to addressable. */ - else if (!TREE_STATIC (modify_dest) - && !TREE_ADDRESSABLE (modify_dest) - && !TREE_ADDRESSABLE (result)) - use_it = true; + else if (TREE_ADDRESSABLE (result)) + use_it = false; + else + { + tree base_m = get_base_address (modify_dest); + + /* If the base isn't a decl, then it's a pointer, and we don't + know where that's going to go. */ + if (!DECL_P (base_m)) + use_it = false; + else if (is_global_var (base_m)) + use_it = false; + else if (!TREE_ADDRESSABLE (base_m)) + use_it = true; + } if (use_it) { |