From: Richard Biener Date: Fri, 6 Apr 2018 11:47:18 +0000 (+0000) Subject: re PR tree-optimization/85244 (Bad optimisation with flexible array member (may be... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ef2e5ec2d4dbcd865bd62fd887b89e7a42f66222;p=gcc.git re PR tree-optimization/85244 (Bad optimisation with flexible array member (may be related to -ftree-dominator-opts)) 2018-04-06 Richard Biener 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 654a0aa28b4..f95365232dc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-04-06 Richard Biener + + 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 PR sanitizer/85213 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 60d0484fc6d..e52b67c589c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-04-06 Richard Biener + + PR middle-end/85244 + * gcc.dg/torture/pr85244-1.c: New testcase. + * gcc.dg/torture/pr85244-2.c: Likewise. + 2018-04-06 Jakub Jelinek 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 00000000000..44716aa9e04 --- /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 00000000000..d57cb712420 --- /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 b50b9abcd9e..a121b880bb0 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