aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/class.c9
-rw-r--r--gcc/cp/decl.c9
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/template/inherit8.C4
-rw-r--r--gcc/testsuite/g++.dg/template/using21.C43
-rw-r--r--gcc/testsuite/g++.dg/template/using22.C51
7 files changed, 83 insertions, 40 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 142a866..3325f1a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 3877a27..82c28fa 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 842c2d8..84b78f6 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f4e7ff5..d3bfd48 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/g++.dg/template/inherit8.C b/gcc/testsuite/g++.dg/template/inherit8.C
index a9b2bdb..3176dc0 100644
--- a/gcc/testsuite/g++.dg/template/inherit8.C
+++ b/gcc/testsuite/g++.dg/template/inherit8.C
@@ -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" }
{
};
};
diff --git a/gcc/testsuite/g++.dg/template/using21.C b/gcc/testsuite/g++.dg/template/using21.C
index 7f61f85..65313aa 100644
--- a/gcc/testsuite/g++.dg/template/using21.C
+++ b/gcc/testsuite/g++.dg/template/using21.C
@@ -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;
};
diff --git a/gcc/testsuite/g++.dg/template/using22.C b/gcc/testsuite/g++.dg/template/using22.C
index b456e62..9ea3d8a 100644
--- a/gcc/testsuite/g++.dg/template/using22.C
+++ b/gcc/testsuite/g++.dg/template/using22.C
@@ -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;
};