From: Richard Biener Date: Tue, 5 Nov 2013 13:24:13 +0000 (+0000) Subject: re PR middle-end/58941 (value modification on zero-length array optimized away) X-Git-Tag: upstream/12.2.0~66849 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4f94d87c6171d472fb8f6d2cf0d572d0bd8ebeee;p=platform%2Fupstream%2Fgcc.git re PR middle-end/58941 (value modification on zero-length array optimized away) 2013-11-05 Richard Biener 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 514b97e..757eded 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2013-11-05 Richard Biener + + 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 * config/i386/i386.c (ix86_float_exceptions_rounding_supported_p): diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b33fcad..75abe6d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-11-05 Richard Biener + + PR middle-end/58941 + * gcc.dg/torture/pr58941.c: New testcase. + 2013-11-05 Marc Glisse PR tree-optimization/58958 diff --git a/gcc/testsuite/gcc.dg/torture/pr58941.c b/gcc/testsuite/gcc.dg/torture/pr58941.c new file mode 100644 index 0000000..c0eea07 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr58941.c @@ -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; +} diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index a44cfe8..c8b257e 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -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,7 +541,38 @@ 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) { @@ -555,41 +583,11 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, 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); - off = off.lshift (BITS_PER_UNIT == 8 - ? 3 : exact_log2 (BITS_PER_UNIT)); off += bit_offset; 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))