re PR c++/6716 (loop and fill ram during compiling)
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Tue, 2 Jul 2002 15:56:01 +0000 (15:56 +0000)
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>
Tue, 2 Jul 2002 15:56:01 +0000 (15:56 +0000)
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.

From-SVN: r55182

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/instantiate1.C [new file with mode: 0644]

index 27ee091..7382cb3 100644 (file)
@@ -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
index 46de8da..68793c7 100644 (file)
@@ -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)
       {
index 2cb4cc3..8700a4f 100644 (file)
@@ -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:
index b7cb0f2..b25b0ef 100644 (file)
@@ -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 (file)
index 0000000..e96bcd2
--- /dev/null
@@ -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" }
+};