re PR middle-end/58941 (value modification on zero-length array optimized away)
2013-11-05 Richard Biener <rguenther@suse.de> PR middle-end/58941 * tree-dfa.c (get_ref_base_and_extent): Merge common code in MEM_REF and TARGET_MEM_REF handling. Make sure to process trailing array detection before diving into the view-converted object (and possibly apply some extra offset). * gcc.dg/torture/pr58941.c: New testcase. From-SVN: r204391
This commit is contained in:
parent
254a0760a1
commit
4f94d87c61
4 changed files with 88 additions and 53 deletions
|
@ -1,3 +1,11 @@
|
|||
2013-11-05 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/58941
|
||||
* tree-dfa.c (get_ref_base_and_extent): Merge common code
|
||||
in MEM_REF and TARGET_MEM_REF handling. Make sure to
|
||||
process trailing array detection before diving into the
|
||||
view-converted object (and possibly apply some extra offset).
|
||||
|
||||
2013-11-05 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* config/i386/i386.c (ix86_float_exceptions_rounding_supported_p):
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2013-11-05 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/58941
|
||||
* gcc.dg/torture/pr58941.c: New testcase.
|
||||
|
||||
2013-11-05 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
PR tree-optimization/58958
|
||||
|
|
33
gcc/testsuite/gcc.dg/torture/pr58941.c
Normal file
33
gcc/testsuite/gcc.dg/torture/pr58941.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
typedef struct {
|
||||
int msgLength;
|
||||
unsigned char data[1000];
|
||||
} SMsg;
|
||||
|
||||
typedef struct {
|
||||
int dummy;
|
||||
int d[0];
|
||||
} SData;
|
||||
|
||||
int condition = 3;
|
||||
|
||||
int main()
|
||||
{
|
||||
SMsg msg;
|
||||
SData *pData = (SData*)(msg.data);
|
||||
unsigned int i = 0;
|
||||
for (i = 0; i < 1; i++)
|
||||
{
|
||||
pData->d[i] = 0;
|
||||
if(condition & 1)
|
||||
pData->d[i] |= 0x55;
|
||||
if(condition & 2)
|
||||
pData->d[i] |= 0xaa;
|
||||
}
|
||||
if (pData->d[0] != 0xff)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
|
@ -389,7 +389,6 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
|||
double_int bit_offset = double_int_zero;
|
||||
HOST_WIDE_INT hbit_offset;
|
||||
bool seen_variable_array_ref = false;
|
||||
tree base_type;
|
||||
|
||||
/* First get the final access size from just the outermost expression. */
|
||||
if (TREE_CODE (exp) == COMPONENT_REF)
|
||||
|
@ -420,8 +419,6 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
|||
and find the ultimate containing object. */
|
||||
while (1)
|
||||
{
|
||||
base_type = TREE_TYPE (exp);
|
||||
|
||||
switch (TREE_CODE (exp))
|
||||
{
|
||||
case BIT_FIELD_REF:
|
||||
|
@ -544,42 +541,43 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
|||
case VIEW_CONVERT_EXPR:
|
||||
break;
|
||||
|
||||
case TARGET_MEM_REF:
|
||||
/* Via the variable index or index2 we can reach the
|
||||
whole object. Still hand back the decl here. */
|
||||
if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR
|
||||
&& (TMR_INDEX (exp) || TMR_INDEX2 (exp)))
|
||||
{
|
||||
exp = TREE_OPERAND (TMR_BASE (exp), 0);
|
||||
bit_offset = double_int_zero;
|
||||
maxsize = -1;
|
||||
goto done;
|
||||
}
|
||||
/* Fallthru. */
|
||||
case MEM_REF:
|
||||
/* We need to deal with variable arrays ending structures such as
|
||||
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[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
|
||||
the array. The simplest way to conservatively deal with this
|
||||
is to punt in the case that offset + maxsize reaches the
|
||||
base type boundary. This needs to include possible trailing
|
||||
padding that is there for alignment purposes. */
|
||||
if (seen_variable_array_ref
|
||||
&& maxsize != -1
|
||||
&& (!bit_offset.fits_shwi ()
|
||||
|| !host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
|
||||
|| (bit_offset.to_shwi () + maxsize
|
||||
== (signed) TREE_INT_CST_LOW
|
||||
(TYPE_SIZE (TREE_TYPE (exp))))))
|
||||
maxsize = -1;
|
||||
|
||||
/* Hand back the decl for MEM[&decl, off]. */
|
||||
if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR)
|
||||
{
|
||||
if (integer_zerop (TREE_OPERAND (exp, 1)))
|
||||
exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
|
||||
else
|
||||
{
|
||||
double_int off = mem_ref_offset (exp);
|
||||
off = off.lshift (BITS_PER_UNIT == 8
|
||||
? 3 : exact_log2 (BITS_PER_UNIT));
|
||||
off = off + bit_offset;
|
||||
if (off.fits_shwi ())
|
||||
{
|
||||
bit_offset = off;
|
||||
exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
|
||||
case TARGET_MEM_REF:
|
||||
/* Hand back the decl for MEM[&decl, off]. */
|
||||
if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR)
|
||||
{
|
||||
/* Via the variable index or index2 we can reach the
|
||||
whole object. */
|
||||
if (TMR_INDEX (exp) || TMR_INDEX2 (exp))
|
||||
{
|
||||
exp = TREE_OPERAND (TMR_BASE (exp), 0);
|
||||
bit_offset = double_int_zero;
|
||||
maxsize = -1;
|
||||
goto done;
|
||||
}
|
||||
if (integer_zerop (TMR_OFFSET (exp)))
|
||||
exp = TREE_OPERAND (TMR_BASE (exp), 0);
|
||||
else
|
||||
{
|
||||
double_int off = mem_ref_offset (exp);
|
||||
|
@ -589,7 +587,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
|||
if (off.fits_shwi ())
|
||||
{
|
||||
bit_offset = off;
|
||||
exp = TREE_OPERAND (TMR_BASE (exp), 0);
|
||||
exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -601,8 +599,17 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
|||
|
||||
exp = TREE_OPERAND (exp, 0);
|
||||
}
|
||||
done:
|
||||
|
||||
/* We need to deal with variable arrays ending structures. */
|
||||
if (seen_variable_array_ref
|
||||
&& maxsize != -1
|
||||
&& (!bit_offset.fits_shwi ()
|
||||
|| !host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
|
||||
|| (bit_offset.to_shwi () + maxsize
|
||||
== (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))))
|
||||
maxsize = -1;
|
||||
|
||||
done:
|
||||
if (!bit_offset.fits_shwi ())
|
||||
{
|
||||
*poffset = 0;
|
||||
|
@ -614,24 +621,6 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
|
|||
|
||||
hbit_offset = bit_offset.to_shwi ();
|
||||
|
||||
/* We need to deal with variable arrays ending structures such as
|
||||
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[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
|
||||
the array. The simplest way to conservatively deal with this
|
||||
is to punt in the case that offset + maxsize reaches the
|
||||
base type boundary. This needs to include possible trailing padding
|
||||
that is there for alignment purposes. */
|
||||
|
||||
if (seen_variable_array_ref
|
||||
&& maxsize != -1
|
||||
&& (!host_integerp (TYPE_SIZE (base_type), 1)
|
||||
|| (hbit_offset + maxsize
|
||||
== (signed) TREE_INT_CST_LOW (TYPE_SIZE (base_type)))))
|
||||
maxsize = -1;
|
||||
|
||||
/* In case of a decl or constant base object we can do better. */
|
||||
|
||||
if (DECL_P (exp))
|
||||
|
|
Loading…
Add table
Reference in a new issue