diff options
author | Richard Biener <rguenther@suse.de> | 2018-04-06 11:47:18 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2018-04-06 11:47:18 +0000 |
commit | ef2e5ec2d4dbcd865bd62fd887b89e7a42f66222 (patch) | |
tree | 6b9a5f6c6431c26e9dbdbeff5e32be6928d26f55 | |
parent | 5a98025d8fdd5274cd6e5573424504c60427c56a (diff) | |
download | gcc-ef2e5ec2d4dbcd865bd62fd887b89e7a42f66222.zip gcc-ef2e5ec2d4dbcd865bd62fd887b89e7a42f66222.tar.gz gcc-ef2e5ec2d4dbcd865bd62fd887b89e7a42f66222.tar.bz2 |
re PR tree-optimization/85244 (Bad optimisation with flexible array member (may be related to -ftree-dominator-opts))
2018-04-06 Richard Biener <rguenther@suse.de>
PR middle-end/85244
* tree-dfa.c (get_ref_base_and_extent): Reset seen_variable_array_ref
after seeing a component reference with an adjacent field. Treat
refs to arrays at struct end of external decls similar to
refs to unconstrained commons.
* gcc.dg/torture/pr85244-1.c: New testcase.
* gcc.dg/torture/pr85244-2.c: Likewise.
From-SVN: r259168
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr85244-1.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr85244-2.c | 8 | ||||
-rw-r--r-- | gcc/tree-dfa.c | 13 |
5 files changed, 51 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 654a0aa..f953652 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-04-06 Richard Biener <rguenther@suse.de> + + PR middle-end/85244 + * tree-dfa.c (get_ref_base_and_extent): Reset seen_variable_array_ref + after seeing a component reference with an adjacent field. Treat + refs to arrays at struct end of external decls similar to + refs to unconstrained commons. + 2018-04-06 Jakub Jelinek <jakub@redhat.com> PR sanitizer/85213 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 60d0484..e52b67c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-04-06 Richard Biener <rguenther@suse.de> + + PR middle-end/85244 + * gcc.dg/torture/pr85244-1.c: New testcase. + * gcc.dg/torture/pr85244-2.c: Likewise. + 2018-04-06 Jakub Jelinek <jakub@redhat.com> PR sanitizer/85213 diff --git a/gcc/testsuite/gcc.dg/torture/pr85244-1.c b/gcc/testsuite/gcc.dg/torture/pr85244-1.c new file mode 100644 index 0000000..44716aa --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr85244-1.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-additional-sources "pr85244-2.c" } */ + +struct s { + long a; + int b; + int tab[]; +}; + +extern const struct s val; +extern int idx; +extern void abort (void); + +int main() +{ + if (val.tab[0] != 42 || val.tab[1] != 1337 || val.tab[idx] != 1337) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr85244-2.c b/gcc/testsuite/gcc.dg/torture/pr85244-2.c new file mode 100644 index 0000000..d57cb71 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr85244-2.c @@ -0,0 +1,8 @@ +struct s { + long a; + int b; + int tab[]; +}; + +int idx = 1; +const struct s val = { 0, 0, { 42, 1337 } }; diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index b50b9ab..a121b88 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -438,7 +438,7 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset, referenced the last field of a struct or a union member then we have to adjust maxsize by the padding at the end of our field. */ - if (seen_variable_array_ref && known_size_p (maxsize)) + if (seen_variable_array_ref) { tree stype = TREE_TYPE (TREE_OPERAND (exp, 0)); tree next = DECL_CHAIN (field); @@ -454,7 +454,7 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset, || ssize == NULL || !poly_int_tree_p (ssize)) maxsize = -1; - else + else if (known_size_p (maxsize)) { poly_offset_int tem = (wi::to_poly_offset (ssize) @@ -464,6 +464,11 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset, maxsize += tem; } } + /* An component ref with an adjacent field up in the + structure hierarchy constrains the size of any variable + array ref lower in the access hierarchy. */ + else + seen_variable_array_ref = false; } } else @@ -622,7 +627,9 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset, if (DECL_P (exp)) { - if (flag_unconstrained_commons && VAR_P (exp) && DECL_COMMON (exp)) + if (VAR_P (exp) + && ((flag_unconstrained_commons && DECL_COMMON (exp)) + || (DECL_EXTERNAL (exp) && seen_variable_array_ref))) { tree sz_tree = TYPE_SIZE (TREE_TYPE (exp)); /* If size is unknown, or we have read to the end, assume there |