mirror of git://gcc.gnu.org/git/gcc.git
re PR bootstrap/41395 (Revision 151800 failed bootstrap)
2009-09-22 Richard Guenther <rguenther@suse.de> PR middle-end/41395 * tree-dfa.c (get_ref_base_and_extent): Handle trailing arrays really properly. * gcc.c-torture/execute/pr41395-1.c: New testcase. * gcc.c-torture/execute/pr41395-2.c: Likewise. From-SVN: r151981
This commit is contained in:
parent
cf76ef1a46
commit
2df373c2eb
|
@ -1,3 +1,9 @@
|
||||||
|
2009-09-22 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR middle-end/41395
|
||||||
|
* tree-dfa.c (get_ref_base_and_extent): Handle trailing
|
||||||
|
arrays really properly.
|
||||||
|
|
||||||
2009-09-22 Jakub Jelinek <jakub@redhat.com>
|
2009-09-22 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* config/rs6000/rs6000.c (bdesc_2arg): Fix CODE_FOR_vector_gt* codes
|
* config/rs6000/rs6000.c (bdesc_2arg): Fix CODE_FOR_vector_gt* codes
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2009-09-22 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR middle-end/41395
|
||||||
|
* gcc.c-torture/execute/pr41395-1.c: New testcase.
|
||||||
|
* gcc.c-torture/execute/pr41395-2.c: Likewise.
|
||||||
|
|
||||||
2009-09-22 Jakub Jelinek <jakub@redhat.com>
|
2009-09-22 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* gcc.dg/20090922-1.c: New test.
|
* gcc.dg/20090922-1.c: New test.
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
struct VEC_char_base
|
||||||
|
{
|
||||||
|
unsigned num;
|
||||||
|
unsigned alloc;
|
||||||
|
short vec[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
short __attribute__((noinline))
|
||||||
|
foo (struct VEC_char_base *p, int i)
|
||||||
|
{
|
||||||
|
short *q;
|
||||||
|
p->vec[i] = 0;
|
||||||
|
q = &p->vec[8];
|
||||||
|
*q = 1;
|
||||||
|
return p->vec[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void abort (void);
|
||||||
|
extern void *malloc (__SIZE_TYPE__);
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
struct VEC_char_base *p = malloc (sizeof (struct VEC_char_base) + 256);
|
||||||
|
if (foo (p, 8) != 1)
|
||||||
|
abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
struct VEC_char_base
|
||||||
|
{
|
||||||
|
unsigned num;
|
||||||
|
unsigned alloc;
|
||||||
|
union {
|
||||||
|
short vec[1];
|
||||||
|
struct {
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
int k;
|
||||||
|
} a;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
short __attribute__((noinline))
|
||||||
|
foo (struct VEC_char_base *p, int i)
|
||||||
|
{
|
||||||
|
short *q;
|
||||||
|
p->u.vec[i] = 0;
|
||||||
|
q = &p->u.vec[16];
|
||||||
|
*q = 1;
|
||||||
|
return p->u.vec[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void abort (void);
|
||||||
|
extern void *malloc (__SIZE_TYPE__);
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
struct VEC_char_base *p = malloc (sizeof (struct VEC_char_base) + 256);
|
||||||
|
if (foo (p, 16) != 1)
|
||||||
|
abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -752,7 +752,6 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
||||||
tree size_tree = NULL_TREE;
|
tree size_tree = NULL_TREE;
|
||||||
HOST_WIDE_INT bit_offset = 0;
|
HOST_WIDE_INT bit_offset = 0;
|
||||||
bool seen_variable_array_ref = false;
|
bool seen_variable_array_ref = false;
|
||||||
bool seen_union = false;
|
|
||||||
|
|
||||||
/* First get the final access size from just the outermost expression. */
|
/* First get the final access size from just the outermost expression. */
|
||||||
if (TREE_CODE (exp) == COMPONENT_REF)
|
if (TREE_CODE (exp) == COMPONENT_REF)
|
||||||
|
@ -794,9 +793,6 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
||||||
tree field = TREE_OPERAND (exp, 1);
|
tree field = TREE_OPERAND (exp, 1);
|
||||||
tree this_offset = component_ref_field_offset (exp);
|
tree this_offset = component_ref_field_offset (exp);
|
||||||
|
|
||||||
if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == UNION_TYPE)
|
|
||||||
seen_union = true;
|
|
||||||
|
|
||||||
if (this_offset
|
if (this_offset
|
||||||
&& TREE_CODE (this_offset) == INTEGER_CST
|
&& TREE_CODE (this_offset) == INTEGER_CST
|
||||||
&& host_integerp (this_offset, 0))
|
&& host_integerp (this_offset, 0))
|
||||||
|
@ -849,6 +845,40 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tree asize = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp, 0)));
|
tree asize = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp, 0)));
|
||||||
|
/* Get at the array size but include trailing padding if
|
||||||
|
the array is the last element of a struct or union. */
|
||||||
|
if (maxsize != -1
|
||||||
|
&& TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF)
|
||||||
|
{
|
||||||
|
tree cref = TREE_OPERAND (exp, 0);
|
||||||
|
tree field = TREE_OPERAND (cref, 1);
|
||||||
|
tree stype = TREE_TYPE (TREE_OPERAND (cref, 0));
|
||||||
|
tree next = TREE_CHAIN (field);
|
||||||
|
while (next && TREE_CODE (next) != FIELD_DECL)
|
||||||
|
next = TREE_CHAIN (next);
|
||||||
|
if (!next
|
||||||
|
|| TREE_CODE (stype) != RECORD_TYPE)
|
||||||
|
{
|
||||||
|
/* The size including padding is the size of
|
||||||
|
the whole structure minus the offset of the
|
||||||
|
array in it. */
|
||||||
|
tree field_offset = component_ref_field_offset (cref);
|
||||||
|
if (field_offset
|
||||||
|
&& host_integerp (field_offset, 0)
|
||||||
|
&& host_integerp (TYPE_SIZE_UNIT (stype), 0))
|
||||||
|
{
|
||||||
|
unsigned HOST_WIDE_INT as;
|
||||||
|
as = (((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (stype))
|
||||||
|
- TREE_INT_CST_LOW (field_offset))
|
||||||
|
* BITS_PER_UNIT)
|
||||||
|
- TREE_INT_CST_LOW
|
||||||
|
(DECL_FIELD_BIT_OFFSET (field)));
|
||||||
|
asize = build_int_cstu (sizetype, as);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
asize = NULL_TREE;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* We need to adjust maxsize to the whole array bitsize.
|
/* We need to adjust maxsize to the whole array bitsize.
|
||||||
But we can subtract any constant offset seen so far,
|
But we can subtract any constant offset seen so far,
|
||||||
because that would get us outside of the array otherwise. */
|
because that would get us outside of the array otherwise. */
|
||||||
|
@ -887,25 +917,18 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
||||||
struct { int length; int a[1]; } x; x.a[d]
|
struct { int length; int a[1]; } x; x.a[d]
|
||||||
struct { struct { int a; int b; } a[1]; } x; x.a[d].a
|
struct { struct { int a; int b; } a[1]; } x; x.a[d].a
|
||||||
struct { struct { int a[1]; } a[1]; } x; x.a[0][d], x.a[d][0]
|
struct { struct { int a[1]; } a[1]; } x; x.a[0][d], x.a[d][0]
|
||||||
|
struct { int len; union { int a[1]; struct X x; } u; } x; x.u.a[d]
|
||||||
where we do not know maxsize for variable index accesses to
|
where we do not know maxsize for variable index accesses to
|
||||||
the array. The simplest way to conservatively deal with this
|
the array. The simplest way to conservatively deal with this
|
||||||
is to punt in the case that offset + maxsize reaches the
|
is to punt in the case that offset + maxsize reaches the
|
||||||
base type boundary.
|
base type boundary. This needs to include possible trailing padding
|
||||||
|
that is there for alignment purposes. */
|
||||||
Unfortunately this is difficult to determine reliably when unions are
|
|
||||||
involved and so we are conservative in such cases.
|
|
||||||
|
|
||||||
FIXME: This approach may be too conservative, we probably want to at least
|
|
||||||
check that the union is the last field/element at its level or even
|
|
||||||
propagate the calculated offsets back up the access chain and check
|
|
||||||
there. */
|
|
||||||
|
|
||||||
if (seen_variable_array_ref
|
if (seen_variable_array_ref
|
||||||
&& (seen_union
|
&& (maxsize != -1
|
||||||
|| (maxsize != -1
|
&& host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
|
||||||
&& host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
|
&& bit_offset + maxsize
|
||||||
&& bit_offset + maxsize
|
== (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp)))))
|
||||||
== (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))))
|
|
||||||
maxsize = -1;
|
maxsize = -1;
|
||||||
|
|
||||||
/* ??? Due to negative offsets in ARRAY_REF we can end up with
|
/* ??? Due to negative offsets in ARRAY_REF we can end up with
|
||||||
|
|
Loading…
Reference in New Issue