]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/69851 (ICE: in assign_temp, at function.c:961)
authorJakub Jelinek <jakub@redhat.com>
Fri, 19 Feb 2016 19:11:58 +0000 (20:11 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 19 Feb 2016 19:11:58 +0000 (20:11 +0100)
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

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr69851.C [new file with mode: 0644]

index 587a53461cffcc8000a3bfa4071d70c09442ac9b..c39390c3eab5a9068ac56d8e86362c1d2b438d6f 100644 (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
index 29e9356a31e804610e77f01f52c3be2c4a015295..4ad76e10e27d1266adbc96e9dc71e70448de0751 100644 (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),))
+         && !TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
          && DECL_MODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) != BLKmode))
     {
       rtx temp;
index adc10721b3108d683f92322a9a2123b94189557c..f753e7bdec8283e8245c0596044b2f365d461f84 100644 (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
diff --git a/gcc/testsuite/g++.dg/torture/pr69851.C b/gcc/testsuite/g++.dg/torture/pr69851.C
new file mode 100644 (file)
index 0000000..17dbfa6
--- /dev/null
@@ -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);
+}