* decl.c (xref_basetypes): Complain about incomplete template base.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Jul 2012 18:09:10 +0000 (18:09 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Jul 2012 18:09:10 +0000 (18:09 +0000)
* class.c (finish_struct): Adjust variants in templates, too.

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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/inherit8.C
gcc/testsuite/g++.dg/template/using21.C
gcc/testsuite/g++.dg/template/using22.C

index 142a866..3325f1a 100644 (file)
@@ -1,5 +1,8 @@
 2012-07-17  Jason Merrill  <jason@redhat.com>
 
+       * decl.c (xref_basetypes): Complain about incomplete template base.
+       * class.c (finish_struct): Adjust variants in templates, too.
+
        PR c++/53549
        * parser.c (cp_parser_class_head): Call xref_basetypes here.
        (cp_parser_class_specifier_1): Not here.
index 3877a27..82c28fa 100644 (file)
@@ -6325,6 +6325,15 @@ finish_struct (tree t, tree attributes)
 
       /* Remember current #pragma pack value.  */
       TYPE_PRECISION (t) = maximum_field_alignment;
+
+      /* Fix up any variants we've already built.  */
+      for (x = TYPE_NEXT_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
+       {
+         TYPE_SIZE (x) = TYPE_SIZE (t);
+         TYPE_SIZE_UNIT (x) = TYPE_SIZE_UNIT (t);
+         TYPE_FIELDS (x) = TYPE_FIELDS (t);
+         TYPE_METHODS (x) = TYPE_METHODS (t);
+       }
     }
   else
     finish_struct_1 (t);
index 842c2d8..84b78f6 100644 (file)
@@ -11843,7 +11843,14 @@ xref_basetypes (tree ref, tree base_list)
     {
       tree basetype = TREE_VALUE (*basep);
 
-      if (!(processing_template_decl && uses_template_parms (basetype))
+      /* The dependent_type_p call below should really be dependent_scope_p
+        so that we give a hard error about using an incomplete type as a
+        base, but we allow it with a pedwarn for backward
+        compatibility.  */
+      if (processing_template_decl
+         && CLASS_TYPE_P (basetype) && TYPE_BEING_DEFINED (basetype))
+       cxx_incomplete_type_diagnostic (NULL_TREE, basetype, DK_PEDWARN);
+      if (!dependent_type_p (basetype)
          && !complete_type_or_else (basetype, NULL))
        /* An incomplete type.  Remove it from the list.  */
        *basep = TREE_CHAIN (*basep);
index f4e7ff5..d3bfd48 100644 (file)
@@ -1,5 +1,9 @@
 2012-07-17  Jason Merrill  <jason@redhat.com>
 
+       * g++.dg/template/inherit8.C: Adjust.
+       * g++.dg/template/using21.C: Adjust.
+       * g++.dg/template/using22.C: Adjust.
+
        PR c++/53549
        * g++.dg/template/current-inst1.C: New.
        * g++.dg/parse/crash35.C: Adjust.
index a9b2bdb..3176dc0 100644 (file)
@@ -4,9 +4,9 @@ template <typename T>
 struct A
 {
   template <typename U>
-  struct B : public A <B<U> >
+  struct B : public A <B<U> >  // { dg-error "declaration" }
   {
-    struct C : public B<U>
+    struct C : public B<U>     // { dg-error "incomplete" }
     {
     };
   };
index 7f61f85..65313aa 100644 (file)
@@ -4,25 +4,34 @@
 template<typename T>
 struct A
 {
-    int foo;
+  int foo;
 
-    struct B : A<T>
-    {
-        using A::foo;
-    };
+  struct B;
+  struct C;
+  struct D;
+  struct E;
+};
 
-    struct C : A
-    {
-        using A::foo;
-    };
+template <class T>
+struct A<T>::B : A<T>
+{
+  using A::foo;
+};
 
-    struct D : A<T>
-    {
-       using A<T>::foo;
-    };
+template <class T>
+struct A<T>::C : A
+{
+  using A::foo;
+};
 
-    struct E : A
-    {
-       using A<T>::foo;
-    };
+template <class T>
+struct A<T>::D : A<T>
+{
+  using A<T>::foo;
+};
+
+template <class T>
+struct A<T>::E : A
+{
+  using A<T>::foo;
 };
index b456e62..9ea3d8a 100644 (file)
@@ -6,28 +6,39 @@ template <class T> struct Z {};
 template<typename T>
 struct A
 {
-    struct B : A<T>
-    {
-        using A::nonexist; // { dg-error "no members matching" }
-    };
+  struct B;
+  struct C;
+  struct D;
+  struct E;
+  struct F;
+};
 
-    struct C : A
-    {
-        using A::nonexist; // { dg-error "no members matching" }
-    };
+template <class T>
+struct A<T>::B : A<T>
+{
+  using A::nonexist; // { dg-error "no members matching" }
+};
 
-    struct D : A<T>
-    {
-       using A<T>::nonexist; // { dg-error "no members matching" }
-    };
+template <class T>
+struct A<T>::C : A
+{
+  using A::nonexist; // { dg-error "no members matching" }
+};
 
-    struct E : A
-    {
-       using A<T>::nonexist; // { dg-error "no members matching" }
-    };
+template <class T>
+struct A<T>::D : A<T>
+{
+  using A<T>::nonexist; // { dg-error "no members matching" }
+};
 
-    struct F : Z<T>
-    {
-       using Z<T>::nonexist;
-    };
+template <class T>
+struct A<T>::E : A
+{
+  using A<T>::nonexist; // { dg-error "no members matching" }
+};
+
+template <class T>
+struct A<T>::F : Z<T>
+{
+  using Z<T>::nonexist;
 };