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
This commit is contained in:
Jakub Jelinek 2016-02-19 20:11:58 +01:00 committed by Jakub Jelinek
parent 15fca21a3e
commit 4b6c824a58
4 changed files with 51 additions and 2 deletions

View File

@ -1,5 +1,12 @@
2016-02-19 Jakub Jelinek <jakub@redhat.com>
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.
PR middle-end/69838
* lra.c (lra_process_new_insns): If non-call exceptions are enabled,
call copy_reg_eh_region_note_forward on before and/or after sequences

View File

@ -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;

View File

@ -1,3 +1,8 @@
2016-02-19 Jakub Jelinek <jakub@redhat.com>
PR c++/69851
* g++.dg/torture/pr69851.C: New test.
2016-02-19 Martin Sebor <msebor@redhat.com>
PR testsuite/69573

View File

@ -0,0 +1,24 @@
// PR c++/69851
// { dg-do compile }
// { dg-options "-std=c++11" }
template <typename T>
struct A { T a; };
template <unsigned long, typename...>
struct B;
template <unsigned long N, typename T, typename... U>
struct B<N, T, U...> : B<1, U...>, A<T>
{
B (B &) = default;
B (B &&x) : B(x) {}
};
template <unsigned long N, typename T>
struct B<N, T> {};
struct C { C (C &); };
struct D {};
void
foo (B<0, C, D, int, int> a)
{
B<0, C, D, int, int> b (a);
}