aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-dfa.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2018-04-06 11:47:18 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2018-04-06 11:47:18 +0000
commitef2e5ec2d4dbcd865bd62fd887b89e7a42f66222 (patch)
tree6b9a5f6c6431c26e9dbdbeff5e32be6928d26f55 /gcc/tree-dfa.c
parent5a98025d8fdd5274cd6e5573424504c60427c56a (diff)
downloadgcc-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.c13
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