]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/79900 - ICE in strip_typedefs
authormpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Mar 2017 08:35:37 +0000 (08:35 +0000)
committermpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Mar 2017 08:35:37 +0000 (08:35 +0000)
* tree.c (strip_typedefs): Skip the attribute handling if T is
a variant type which hasn't been updated yet.

* g++.dg/warn/Wpadded-1.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@245988 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wpadded-1.C [new file with mode: 0644]

index 5bd83227ff7b91bdfa2027332a08075396730738..caf0322972ff64a56c6ea079304c2508675e5bcb 100644 (file)
@@ -1,3 +1,9 @@
+2017-03-09  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/79900 - ICE in strip_typedefs
+       * tree.c (strip_typedefs): Skip the attribute handling if T is
+       a variant type which hasn't been updated yet.
+
 2017-03-08  Jason Merrill  <jason@redhat.com>
 
        PR c++/79797 - ICE with self-reference in array DMI.
index d3c63b82cb347e9baadf8f4f76aefee4e04e5a75..2757af6691d5baee0bfc69d3be025ed1f8e8afed 100644 (file)
@@ -1548,29 +1548,40 @@ strip_typedefs (tree t, bool *remove_attributes)
        result = TYPE_MAIN_VARIANT (t);
     }
   gcc_assert (!typedef_variant_p (result));
-  if (TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (result)
-      || TYPE_ALIGN (t) != TYPE_ALIGN (result))
+
+  if (COMPLETE_TYPE_P (result) && !COMPLETE_TYPE_P (t))
+  /* If RESULT is complete and T isn't, it's likely the case that T
+     is a variant of RESULT which hasn't been updated yet.  Skip the
+     attribute handling.  */;
+  else
     {
-      gcc_assert (TYPE_USER_ALIGN (t));
-      if (remove_attributes)
-       *remove_attributes = true;
-      else
+      if (TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (result)
+         || TYPE_ALIGN (t) != TYPE_ALIGN (result))
        {
-         if (TYPE_ALIGN (t) == TYPE_ALIGN (result))
-           result = build_variant_type_copy (result);
+         gcc_assert (TYPE_USER_ALIGN (t));
+         if (remove_attributes)
+           *remove_attributes = true;
          else
-           result = build_aligned_type (result, TYPE_ALIGN (t));
-         TYPE_USER_ALIGN (result) = true;
+           {
+             if (TYPE_ALIGN (t) == TYPE_ALIGN (result))
+               result = build_variant_type_copy (result);
+             else
+               result = build_aligned_type (result, TYPE_ALIGN (t));
+             TYPE_USER_ALIGN (result) = true;
+           }
+       }
+
+      if (TYPE_ATTRIBUTES (t))
+       {
+         if (remove_attributes)
+           result = apply_identity_attributes (result, TYPE_ATTRIBUTES (t),
+                                               remove_attributes);
+         else
+           result = cp_build_type_attribute_variant (result,
+                                                     TYPE_ATTRIBUTES (t));
        }
     }
-  if (TYPE_ATTRIBUTES (t))
-    {
-      if (remove_attributes)
-       result = apply_identity_attributes (result, TYPE_ATTRIBUTES (t),
-                                           remove_attributes);
-      else
-       result = cp_build_type_attribute_variant (result, TYPE_ATTRIBUTES (t));
-    }
+
   return cp_build_qualified_type (result, cp_type_quals (t));
 }
 
index 396ab3ad1218c104b1efa1b6ace29c91d35bfa59..6c8ab1d87fb5767618e327d96b79edfae7bc0b79 100644 (file)
@@ -1,3 +1,8 @@
+2017-03-09  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/79900 - ICE in strip_typedefs
+       * g++.dg/warn/Wpadded-1.C: New test.
+
 2017-03-08  Marek Polacek  <polacek@redhat.com>
 
        * g++.dg/Walloca1.C: Adjust dg-warning.
diff --git a/gcc/testsuite/g++.dg/warn/Wpadded-1.C b/gcc/testsuite/g++.dg/warn/Wpadded-1.C
new file mode 100644 (file)
index 0000000..b3f0581
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/79900 - ICE in strip_typedefs
+// { dg-do compile }
+// { dg-options "-Wpadded" }
+
+template <class> struct A;
+template <typename> struct B { // { dg-warning "padding struct size to alignment boundary" }
+  long _M_off;
+  int _M_state;
+};
+template <> struct A<char> { typedef B<int> pos_type; };
+enum _Ios_Openmode {};
+struct C {
+  typedef _Ios_Openmode openmode;
+};
+template <typename, typename _Traits> struct D {
+  typedef typename _Traits::pos_type pos_type;
+  pos_type m_fn1(pos_type, C::openmode);
+};
+template class D<char, A<char> >;
+template <typename _CharT, typename _Traits>
+typename D<_CharT, _Traits>::pos_type D<_CharT, _Traits>::m_fn1(pos_type x,
+                                                                C::openmode) { return x; }