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 | |
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')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/expr.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr69851.C | 24 |
4 files changed, 51 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 587a534..c39390c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index adc1072..f753e7b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/g++.dg/torture/pr69851.C b/gcc/testsuite/g++.dg/torture/pr69851.C new file mode 100644 index 0000000..17dbfa6 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr69851.C @@ -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); +} |