commit 22ef026b9bac683273c17d80170be4721241b706
Author: Jason Merrill <jason@redhat.com>
Date: Tue Jul 17 06:15:20 2012 -0400
* decl.c (xref_basetypes): Complain about incomplete template base.
* class.c (finish_struct): Adjust variants in templates, too.
@@ -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);
@@ -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);
@@ -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" }
{
};
};
@@ -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;
+};
+
+template <class T>
+struct A<T>::D : A<T>
+{
+ using A<T>::foo;
+};
- struct E : A
- {
- using A<T>::foo;
- };
+template <class T>
+struct A<T>::E : A
+{
+ using A<T>::foo;
};
@@ -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;
+};
+
+template <class T>
+struct A<T>::B : A<T>
+{
+ using A::nonexist; // { dg-error "no members matching" }
+};
- struct C : A
- {
- using A::nonexist; // { dg-error "no members matching" }
- };
+template <class T>
+struct A<T>::C : A
+{
+ 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>::D : A<T>
+{
+ using A<T>::nonexist; // { dg-error "no members matching" }
+};
- struct E : A
- {
- using A<T>::nonexist; // { dg-error "no members matching" }
- };
+template <class T>
+struct A<T>::E : A
+{
+ using A<T>::nonexist; // { dg-error "no members matching" }
+};
- struct F : Z<T>
- {
- using Z<T>::nonexist;
- };
+template <class T>
+struct A<T>::F : Z<T>
+{
+ using Z<T>::nonexist;
};