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 /gcc/tree-dfa.c | |
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
Diffstat (limited to 'gcc/tree-dfa.c')
-rw-r--r-- | gcc/tree-dfa.c | 13 |
1 files changed, 10 insertions, 3 deletions
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 |