diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-02-19 20:11:58 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-02-19 20:11:58 +0100 |
commit | 4b6c824a58ae964920b37e5014793a55b32bc8ce (patch) | |
tree | ad095f6a8fb1989c26f70257401d09f011e05436 /gcc/expr.c | |
parent | 15fca21a3e563ae90a5cc4ae00c36cc0c8e3f6f9 (diff) | |
download | gcc-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.c | 17 |
1 files changed, 15 insertions, 2 deletions
@@ -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; |