re PR c++/80534 (7.1 RC - internal compiler error: in finish_member_declaration,...
authorJakub Jelinek <jakub@redhat.com>
Thu, 27 Apr 2017 13:42:37 +0000 (15:42 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 27 Apr 2017 13:42:37 +0000 (15:42 +0200)
PR c++/80534
* tree.c (type_cache_hasher::equal): Only compare
TYPE_TYPELESS_STORAGE flag on non-aggregate element types.
(build_array_type_1): Only hash TYPE_TYPELESS_STORAGE flag on
non-aggregate element types.
* tree.h (TYPE_TYPELESS_STORAGE): Fix comment typo, add more details
about the flag on ARRAY_TYPEs in the comment, formatting fix.
c-family/
* c-common.c (complete_array_type): Only hash TYPE_TYPELESS_STORAGE
flag on non-aggregate element types.
testsuite/
* g++.dg/other/pr80534-1.C: New test.
* g++.dg/other/pr80534-2.C: New test.

From-SVN: r247334

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/pr80534-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/pr80534-2.C [new file with mode: 0644]
gcc/tree.c
gcc/tree.h

index ac9a03c83074bd3c1fa0be11a17716bcc78fe8ee..0197625970976d83f99bb9505e1c02a7df058cd3 100644 (file)
@@ -1,3 +1,13 @@
+2017-04-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/80534
+       * tree.c (type_cache_hasher::equal): Only compare
+       TYPE_TYPELESS_STORAGE flag on non-aggregate element types.
+       (build_array_type_1): Only hash TYPE_TYPELESS_STORAGE flag on
+       non-aggregate element types.
+       * tree.h (TYPE_TYPELESS_STORAGE): Fix comment typo, add more details
+       about the flag on ARRAY_TYPEs in the comment, formatting fix.
+
 2017-04-27  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/80533
index 58f554961b606e413dd43b8de06c5e5e50ed9b3e..8f6f55b73bfcb30548674bd5d3cf1187c85e38fc 100644 (file)
@@ -1,3 +1,9 @@
+2017-04-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/80534
+       * c-common.c (complete_array_type): Only hash TYPE_TYPELESS_STORAGE
+       flag on non-aggregate element types.
+
 2017-04-25  Bernd Edlinger  <bernd.edlinger@hotmail.de>
 
        * c-common.c (c_type_hasher, type_hash_table): Remove.
index 9691da75239d8beff2bb0726d25ab17e511571ed..4c91103f083e231c81e8f8d2fff514139e551ec5 100644 (file)
@@ -6371,7 +6371,8 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
   inchash::hash hstate;
   hstate.add_object (TYPE_HASH (unqual_elt));
   hstate.add_object (TYPE_HASH (TYPE_DOMAIN (main_type)));
-  hstate.add_flag (TYPE_TYPELESS_STORAGE (main_type));
+  if (!AGGREGATE_TYPE_P (unqual_elt))
+    hstate.add_flag (TYPE_TYPELESS_STORAGE (main_type));
   main_type = type_hash_canon (hstate.end (), main_type);
 
   /* Fix the canonical type.  */
index a28e1a90634a1c66542db3db80b62fd3a709c2cd..e97e20ca964d8684b5fa9ab8f3793bd3317d238b 100644 (file)
@@ -1,3 +1,9 @@
+2017-04-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/80534
+       * g++.dg/other/pr80534-1.C: New test.
+       * g++.dg/other/pr80534-2.C: New test.
+
 2017-04-27  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/80539
diff --git a/gcc/testsuite/g++.dg/other/pr80534-1.C b/gcc/testsuite/g++.dg/other/pr80534-1.C
new file mode 100644 (file)
index 0000000..a8545a7
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/80534
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+template <int> struct A {
+  struct type {
+    char __data[0];
+  };
+};
+template <typename _Tp, typename = _Tp> struct B;
+template <typename _Tp, typename _Dp> struct B<_Tp[], _Dp> {
+  _Tp _M_t;
+  using pointer = int;
+  void m_fn1() {}
+};
+struct C {
+  using Storage = A<0>::type;
+  using StorageUniquePointer = B<Storage[]>;
+  void m_fn2() { storageUniquePointer_.m_fn1(); }
+  StorageUniquePointer storageUniquePointer_;
+};
diff --git a/gcc/testsuite/g++.dg/other/pr80534-2.C b/gcc/testsuite/g++.dg/other/pr80534-2.C
new file mode 100644 (file)
index 0000000..e56e7e0
--- /dev/null
@@ -0,0 +1,27 @@
+// PR c++/80534
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+template <int, int> struct aligned_storage {
+  struct type {
+    char __data[0];
+  };
+};
+struct A {};
+template <typename _Tp, typename = _Tp> struct unique_ptr;
+template <typename _Tp, typename _Dp> struct unique_ptr<_Tp[], _Dp> {
+  int _M_t;
+  void get() { _M_t; }
+};
+struct B {
+  using Association = A;
+  using Storage = aligned_storage<sizeof(Association), alignof(Association)>::type;
+  using StorageUniquePointer = unique_ptr<Storage[]>;
+  void getAssociationsBegin() { storageUniquePointer_.get(); }
+  StorageUniquePointer storageUniquePointer_;
+};
+struct C {};
+using MainThreadStaticSignalsReceiver = C;
+aligned_storage<sizeof(MainThreadStaticSignalsReceiver),
+                alignof(MainThreadStaticSignalsReceiver)>::type
+    mainThreadStaticSignalsReceiverStorage;
index 826af99a9b937532520cb911a030117d97971203..bef0071d08777a36ac308e140d662ffa86ea155b 100644 (file)
@@ -7073,9 +7073,16 @@ type_cache_hasher::equal (type_hash *a, type_hash *b)
         break;
       return 0;
     case ARRAY_TYPE:
-      return (TYPE_TYPELESS_STORAGE (a->type)
-             == TYPE_TYPELESS_STORAGE (b->type)
-             && TYPE_DOMAIN (a->type) == TYPE_DOMAIN (b->type));
+      /* Don't compare TYPE_TYPELESS_STORAGE flag on aggregates,
+        where the flag should be inherited from the element type
+        and can change after ARRAY_TYPEs are created; on non-aggregates
+        compare it and hash it, scalars will never have that flag set
+        and we need to differentiate between arrays created by different
+        front-ends or middle-end created arrays.  */
+      return (TYPE_DOMAIN (a->type) == TYPE_DOMAIN (b->type)
+             && (AGGREGATE_TYPE_P (TREE_TYPE (a->type))
+                 || (TYPE_TYPELESS_STORAGE (a->type)
+                     == TYPE_TYPELESS_STORAGE (b->type))));
 
     case RECORD_TYPE:
     case UNION_TYPE:
@@ -8386,7 +8393,8 @@ build_array_type_1 (tree elt_type, tree index_type, bool typeless_storage,
       hstate.add_object (TYPE_HASH (elt_type));
       if (index_type)
        hstate.add_object (TYPE_HASH (index_type));
-      hstate.add_flag (typeless_storage);
+      if (!AGGREGATE_TYPE_P (elt_type))
+       hstate.add_flag (TYPE_TYPELESS_STORAGE (t));
       t = type_hash_canon (hstate.end (), t);
     }
 
index 4ff19ce6f82d7e4c53f0af2b99dadf0ed872a6aa..6851cd7e0fc0ab4c812c39110e1e344d8e5b7eba 100644 (file)
@@ -2037,10 +2037,16 @@ extern machine_mode element_mode (const_tree t);
 
 /* For an ARRAY_TYPE, a RECORD_TYPE, a UNION_TYPE or a QUAL_UNION_TYPE
    whether the array is typeless storage or the type contains a member
-   with this flag set.  Such types are excempt from type-based alias
-   analysis.  */
+   with this flag set.  Such types are exempt from type-based alias
+   analysis.  For ARRAY_TYPEs with AGGREGATE_TYPE_P element types
+   the flag should be inherited from the element type, can change
+   when type is finalized and because of that should not be used in
+   type hashing.  For ARRAY_TYPEs with non-AGGREGATE_TYPE_P element types
+   the flag should not be changed after the array is created and should
+   be used in type hashing.  */
 #define TYPE_TYPELESS_STORAGE(NODE) \
-  (TREE_CHECK4 (NODE, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE, ARRAY_TYPE)->type_common.typeless_storage)
+  (TREE_CHECK4 (NODE, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE, \
+               ARRAY_TYPE)->type_common.typeless_storage)
 
 /* Indicated that objects of this type should be laid out in as
    compact a way as possible.  */