Commit 947296ca by Jason Merrill Committed by Jason Merrill

decl.c (xref_basetypes): Complain about incomplete template base.

	* decl.c (xref_basetypes): Complain about incomplete template base.
	* class.c (finish_struct): Adjust variants in templates, too.

From-SVN: r189583
parent ec44e463
2012-07-17 Jason Merrill <jason@redhat.com> 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 PR c++/53549
* parser.c (cp_parser_class_head): Call xref_basetypes here. * parser.c (cp_parser_class_head): Call xref_basetypes here.
(cp_parser_class_specifier_1): Not here. (cp_parser_class_specifier_1): Not here.
......
...@@ -6325,6 +6325,15 @@ finish_struct (tree t, tree attributes) ...@@ -6325,6 +6325,15 @@ finish_struct (tree t, tree attributes)
/* Remember current #pragma pack value. */ /* Remember current #pragma pack value. */
TYPE_PRECISION (t) = maximum_field_alignment; 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 else
finish_struct_1 (t); finish_struct_1 (t);
......
...@@ -11843,7 +11843,14 @@ xref_basetypes (tree ref, tree base_list) ...@@ -11843,7 +11843,14 @@ xref_basetypes (tree ref, tree base_list)
{ {
tree basetype = TREE_VALUE (*basep); 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)) && !complete_type_or_else (basetype, NULL))
/* An incomplete type. Remove it from the list. */ /* An incomplete type. Remove it from the list. */
*basep = TREE_CHAIN (*basep); *basep = TREE_CHAIN (*basep);
......
2012-07-17 Jason Merrill <jason@redhat.com> 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 PR c++/53549
* g++.dg/template/current-inst1.C: New. * g++.dg/template/current-inst1.C: New.
* g++.dg/parse/crash35.C: Adjust. * g++.dg/parse/crash35.C: Adjust.
......
...@@ -4,9 +4,9 @@ template <typename T> ...@@ -4,9 +4,9 @@ template <typename T>
struct A struct A
{ {
template <typename U> 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 @@ ...@@ -4,25 +4,34 @@
template<typename T> template<typename T>
struct A struct A
{ {
int foo; int foo;
struct B : A<T> struct B;
{ struct C;
using A::foo; struct D;
}; struct E;
};
struct C : A template <class T>
{ struct A<T>::B : A<T>
using A::foo; {
}; using A::foo;
};
struct D : A<T> template <class T>
{ struct A<T>::C : A
using A<T>::foo; {
}; using A::foo;
};
struct E : A template <class T>
{ struct A<T>::D : A<T>
using A<T>::foo; {
}; 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 {}; ...@@ -6,28 +6,39 @@ template <class T> struct Z {};
template<typename T> template<typename T>
struct A struct A
{ {
struct B : A<T> struct B;
{ struct C;
using A::nonexist; // { dg-error "no members matching" } struct D;
}; struct E;
struct F;
};
struct C : A template <class T>
{ struct A<T>::B : A<T>
using A::nonexist; // { dg-error "no members matching" } {
}; using A::nonexist; // { dg-error "no members matching" }
};
struct D : A<T> template <class T>
{ struct A<T>::C : A
using A<T>::nonexist; // { dg-error "no members matching" } {
}; using A::nonexist; // { dg-error "no members matching" }
};
struct E : A template <class T>
{ struct A<T>::D : A<T>
using A<T>::nonexist; // { dg-error "no members matching" } {
}; using A<T>::nonexist; // { dg-error "no members matching" }
};
struct F : Z<T> template <class T>
{ struct A<T>::E : A
using Z<T>::nonexist; {
}; using A<T>::nonexist; // { dg-error "no members matching" }
};
template <class T>
struct A<T>::F : Z<T>
{
using Z<T>::nonexist;
}; };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment