[PATCH] Fix PR85244
Richard Biener
rguenther@suse.de
Fri Apr 6 11:46:00 GMT 2018
The following fixes PR85244 where we fail to handle a flex-array
reference as such and constrain it with the appearant size of an external
declaration. The fix is to handle this case much like the unconstrained
common one and to not regress some cases the patch adjusts the handling
of flex-array detection when visiting component references.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
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.
Index: gcc/tree-dfa.c
===================================================================
--- gcc/tree-dfa.c (revision 259082)
+++ gcc/tree-dfa.c (working copy)
@@ -438,7 +438,7 @@ get_ref_base_and_extent (tree exp, poly_
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_
|| 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_
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_
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
Index: gcc/testsuite/gcc.dg/torture/pr85244-1.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr85244-1.c (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr85244-1.c (working copy)
@@ -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;
+}
Index: gcc/testsuite/gcc.dg/torture/pr85244-2.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr85244-2.c (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr85244-2.c (working copy)
@@ -0,0 +1,8 @@
+struct s {
+ long a;
+ int b;
+ int tab[];
+};
+
+int idx = 1;
+const struct s val = { 0, 0, { 42, 1337 } };
More information about the Gcc-patches
mailing list