summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorlerdsuwa <lerdsuwa@138bc75d-0d04-0410-961f-82ee72b054a4>2002-07-02 15:56:01 +0000
committerlerdsuwa <lerdsuwa@138bc75d-0d04-0410-961f-82ee72b054a4>2002-07-02 15:56:01 +0000
commite1c962d0cda100019cfd97d9e11404bd5915a5f6 (patch)
treec34661bfb02384e9fbdc00eb55f921dfd879ef8a /gcc
parent913fb3d9e3cb0bbcc1cd2e8f9c1922cf55c488a0 (diff)
downloadgcc-e1c962d0cda100019cfd97d9e11404bd5915a5f6.tar.gz
PR c++/6716
* pt.c (can_complete_type_without_circularity): New function. (instantiate_class_template): Use it. * typeck2.c (incomplete_type_error): Improve error message due to incomplete fields. * g++.dg/template/instantiate1.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@55182 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/pt.c37
-rw-r--r--gcc/cp/typeck2.c8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/instantiate1.C21
5 files changed, 76 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 27ee0911d79..7382cb3dda0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2002-07-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6716
+ * pt.c (can_complete_type_without_circularity): New function.
+ (instantiate_class_template): Use it.
+ * typeck2.c (incomplete_type_error): Improve error message
+ due to incomplete fields.
+
2002-07-01 Mark Mitchell <mark@codesourcery.com>
PR c++/7112
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 46de8dac6f4..68793c78427 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -135,6 +135,7 @@ static int mark_template_parm PARAMS ((tree, void *));
static int template_parm_this_level_p PARAMS ((tree, void *));
static tree tsubst_friend_function PARAMS ((tree, tree));
static tree tsubst_friend_class PARAMS ((tree, tree));
+static int can_complete_type_without_circularity PARAMS ((tree));
static tree get_bindings_real PARAMS ((tree, tree, tree, int, int, int));
static int template_decl_level PARAMS ((tree));
static tree maybe_get_template_decl_from_type_decl PARAMS ((tree));
@@ -4908,6 +4909,25 @@ tsubst_friend_class (friend_tmpl, args)
return friend_type;
}
+/* Returns zero if TYPE cannot be completed later due to circularity.
+ Otherwise returns one. */
+
+int
+can_complete_type_without_circularity (type)
+ tree type;
+{
+ if (type == NULL_TREE || type == error_mark_node)
+ return 0;
+ else if (COMPLETE_TYPE_P (type))
+ return 1;
+ else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
+ return can_complete_type_without_circularity (TREE_TYPE (type));
+ else if (CLASS_TYPE_P (type) && TYPE_BEING_DEFINED (TYPE_MAIN_VARIANT (type)))
+ return 0;
+ else
+ return 1;
+}
+
tree
instantiate_class_template (type)
tree type;
@@ -5222,7 +5242,20 @@ instantiate_class_template (type)
if (DECL_INITIALIZED_IN_CLASS_P (r))
check_static_variable_definition (r, TREE_TYPE (r));
}
-
+ else if (TREE_CODE (r) == FIELD_DECL)
+ {
+ /* Determine whether R has a valid type and can be
+ completed later. If R is invalid, then it is replaced
+ by error_mark_node so that it will not be added to
+ TYPE_FIELDS. */
+ tree rtype = TREE_TYPE (r);
+ if (!can_complete_type_without_circularity (rtype))
+ {
+ incomplete_type_error (r, rtype);
+ r = error_mark_node;
+ }
+ }
+
/* R will have a TREE_CHAIN if and only if it has already been
processed by finish_member_declaration. This can happen
if, for example, it is a TYPE_DECL for a class-scoped
@@ -5303,6 +5336,8 @@ instantiate_class_template (type)
--processing_template_decl;
}
+ /* Now that TYPE_FIELDS and TYPE_METHODS are set up. We can
+ instantiate templates used by this class. */
for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
if (TREE_CODE (t) == FIELD_DECL)
{
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 2cb4cc3b01e..8700a4fe287 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -211,7 +211,8 @@ cxx_incomplete_type_diagnostic (value, type, warn_only)
return;
if (value != 0 && (TREE_CODE (value) == VAR_DECL
- || TREE_CODE (value) == PARM_DECL))
+ || TREE_CODE (value) == PARM_DECL
+ || TREE_CODE (value) == FIELD_DECL))
{
(*p_msg_at) ("`%D' has incomplete type", value);
decl = 1;
@@ -226,7 +227,10 @@ retry:
case ENUMERAL_TYPE:
if (!decl)
(*p_msg) ("invalid use of undefined type `%#T'", type);
- (*p_msg_at) ("forward declaration of `%#T'", type);
+ if (!TYPE_TEMPLATE_INFO (type))
+ (*p_msg_at) ("forward declaration of `%#T'", type);
+ else
+ (*p_msg_at) ("forward declaration of `%#T'", type);
break;
case VOID_TYPE:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b7cb0f28e8b..b25b0ef318d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2002-07-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6716
+ * g++.dg/template/instantiate1.C: New test.
+
2002-07-01 Mark Mitchell <mark@codesourcery.com>
PR c++/7112
diff --git a/gcc/testsuite/g++.dg/template/instantiate1.C b/gcc/testsuite/g++.dg/template/instantiate1.C
new file mode 100644
index 00000000000..e96bcd283fd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/instantiate1.C
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// Origin:
+
+// PR c++/6716
+// ICE in complex class structure when components are incomplete
+
+template <class T> struct X {
+ T t; // { dg-error "incomplete" }
+};
+
+template <class T> struct Y { // { dg-error "instantiated" }
+ X<T> x;
+};
+
+template <class T> struct Z { // { dg-error "instantiated|declaration" }
+ Y<Z<T> > y;
+};
+
+struct ZZ : Z<int>
+{ // { dg-error "instantiated" }
+};