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
This commit is contained in:
Richard Biener 2018-04-06 11:47:18 +00:00 committed by Richard Biener
parent 5a98025d8f
commit ef2e5ec2d4
5 changed files with 51 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -0,0 +1,8 @@
struct s {
long a;
int b;
int tab[];
};
int idx = 1;
const struct s val = { 0, 0, { 42, 1337 } };

View File

@ -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