aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-02-19 20:11:58 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2016-02-19 20:11:58 +0100
commit4b6c824a58ae964920b37e5014793a55b32bc8ce (patch)
treead095f6a8fb1989c26f70257401d09f011e05436 /gcc/expr.c
parent15fca21a3e563ae90a5cc4ae00c36cc0c8e3f6f9 (diff)
downloadgcc-4b6c824a58ae964920b37e5014793a55b32bc8ce.zip
gcc-4b6c824a58ae964920b37e5014793a55b32bc8ce.tar.gz
gcc-4b6c824a58ae964920b37e5014793a55b32bc8ce.tar.bz2
re PR c++/69851 (ICE: in assign_temp, at function.c:961)
PR c++/69851 * expr.c (store_field): Don't use bit-field path if exp is COMPONENT_REF with TREE_ADDRESSABLE type, where TYPE_SIZE is different from bitsize, but DECL_SIZE of FIELD_DECL is bitsize and the assignment can be performed by bitwise copy. Formatting fix. * g++.dg/torture/pr69851.C: New test. From-SVN: r233566
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 29e9356..4ad76e1 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6643,14 +6643,27 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
/* Except for initialization of full bytes from a CONSTRUCTOR, which
we will handle specially below. */
&& !(TREE_CODE (exp) == CONSTRUCTOR
- && bitsize % BITS_PER_UNIT == 0))
+ && bitsize % BITS_PER_UNIT == 0)
+ /* And except for bitwise copying of TREE_ADDRESSABLE types,
+ where the FIELD_DECL has the right bitsize, but TREE_TYPE (exp)
+ includes some extra padding. store_expr / expand_expr will in
+ that case call get_inner_reference that will have the bitsize
+ we check here and thus the block move will not clobber the
+ padding that shouldn't be clobbered. */
+ && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
+ || TREE_CODE (exp) != COMPONENT_REF
+ || TREE_CODE (DECL_SIZE (TREE_OPERAND (exp, 1))) != INTEGER_CST
+ || (bitsize % BITS_PER_UNIT != 0)
+ || (bitpos % BITS_PER_UNIT != 0)
+ || (compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)), bitsize)
+ != 0)))
/* If we are expanding a MEM_REF of a non-BLKmode non-addressable
decl we must use bitfield operations. */
|| (bitsize >= 0
&& TREE_CODE (exp) == MEM_REF
&& TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
&& DECL_P (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
- && !TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (exp, 0),0 ))
+ && !TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
&& DECL_MODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) != BLKmode))
{
rtx temp;