aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr85244-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr85244-2.c8
-rw-r--r--gcc/tree-dfa.c13
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