re PR c++/6749 (infinite loop with inheritance of abstract classes)
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Mon, 16 Aug 2004 14:29:27 +0000 (14:29 +0000)
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>
Mon, 16 Aug 2004 14:29:27 +0000 (14:29 +0000)
PR c++/6749
* pt.c (instantiate_pending_templates): Add int parameter.  Don't
return anything.
* cp-tree.h (instantiate_pending_templates): Adjust prototype.
* decl2.c (finish_file): Adjust call to
instantiate_pending_templates.

* g++.dg/template/vtable2.C: New test.

From-SVN: r86054

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/vtable2.C [new file with mode: 0644]

index 6e4ec4649498d60cf9b6fa7d5f7552d7310e1db4..2946db7567173eee294970b9499d918f695018ea 100644 (file)
@@ -1,3 +1,12 @@
+2004-08-16  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       PR c++/6749
+       * pt.c (instantiate_pending_templates): Add int parameter.  Don't
+       return anything.
+       * cp-tree.h (instantiate_pending_templates): Adjust prototype.
+       * decl2.c (finish_file): Adjust call to
+       instantiate_pending_templates.
+
 2004-08-15  Roger Sayle  <roger@eyesopen.com>
 
        * call.c (build_vfield_ref, build_call, build_conditional_expr,
index e2c94f25ed27d7cc17aec0841c307afed0d5d166..72011f7356fbd8b611b12c8e5ebc6283b1fae9f8 100644 (file)
@@ -3990,7 +3990,7 @@ extern void maybe_process_partial_specialization (tree);
 extern void maybe_check_template_type           (tree);
 extern tree most_specialized_instantiation      (tree);
 extern void print_candidates                    (tree);
-extern int instantiate_pending_templates        (void);
+extern void instantiate_pending_templates       (int);
 extern tree tsubst_default_argument             (tree, tree, tree);
 extern tree tsubst_copy_and_build               (tree, tree, tsubst_flags_t, tree, bool);
 extern tree most_general_template              (tree);
index ab83b9822101c68c864107b0c3394be139689254..efb86b5534a26fc63dca6556ac47418c62feff06 100644 (file)
@@ -2721,6 +2721,7 @@ finish_file (void)
   size_t i;
   location_t locus;
   unsigned ssdf_count = 0;
+  int retries = 0;
 
   locus = input_location;
   at_eof = 1;
@@ -2772,7 +2773,7 @@ finish_file (void)
 
       /* If there are templates that we've put off instantiating, do
         them now.  */
-      instantiate_pending_templates ();
+      instantiate_pending_templates (retries);
       ggc_collect ();
 
       /* Write out virtual tables as required.  Note that writing out
@@ -2780,7 +2781,7 @@ finish_file (void)
         instantiation of members of that class.  If we write out
         vtables then we remove the class from our list so we don't
         have to look at it again.  */
+
       while (keyed_classes != NULL_TREE
             && maybe_emit_vtables (TREE_VALUE (keyed_classes)))
        {
@@ -2806,14 +2807,14 @@ finish_file (void)
              next = TREE_CHAIN (t);
            }
        }
-       
+
       /* Write out needed type info variables.  We have to be careful
         looping through unemitted decls, because emit_tinfo_decl may
         cause other variables to be needed.  We stick new elements
         (and old elements that we may need to reconsider) at the end
         of the array, then shift them back to the beginning once we're
         done.  */
-  
+
       n_old = VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls);
       for (i = 0; i < n_old; ++i)
        {
@@ -2994,6 +2995,8 @@ finish_file (void)
        reconsider = true;
       if (cgraph_varpool_assemble_pending_decls ())
        reconsider = true;
+
+      retries++;
     } 
   while (reconsider);
 
index 4590bd7dee2bfe97e5db62e1c5a105178fd764b7..d3d5267dcefcb06a48c41f5b2447732db09e7ed1 100644 (file)
@@ -11272,17 +11272,30 @@ out:
 }
 
 /* Run through the list of templates that we wish we could
-   instantiate, and instantiate any we can.  */
+   instantiate, and instantiate any we can.  RETRIES is the
+   number of times we retry pending template instantiation.  */
 
-int
-instantiate_pending_templates (void)
+void
+instantiate_pending_templates (int retries)
 {
   tree *t;
   tree last = NULL_TREE;
-  int instantiated_something = 0;
   int reconsider;
   location_t saved_loc = input_location;
-  
+
+  /* Instantiating templates may trigger vtable generation.  This in turn
+     may require further template instantiations.  We place a limit here
+     to avoid infinite loop.  */
+  if (pending_templates && retries >= max_tinst_depth)
+    {
+      cp_error_at ("template instantiation depth exceeds maximum of %d"
+                  " (use -ftemplate-depth-NN to increase the maximum)"
+                  " instantiating `%+D', possibly from virtual table"
+                  " generation",
+                  max_tinst_depth, TREE_VALUE (pending_templates));
+      return;
+    }
+
   do 
     {
       reconsider = 0;
@@ -11309,10 +11322,7 @@ instantiate_pending_templates (void)
                        instantiate_decl (fn, /*defer_ok=*/0,
                                          /*undefined_ok=*/0);
                  if (COMPLETE_TYPE_P (instantiation))
-                   {
-                     instantiated_something = 1;
-                     reconsider = 1;
-                   }
+                   reconsider = 1;
                }
 
              if (COMPLETE_TYPE_P (instantiation))
@@ -11334,10 +11344,7 @@ instantiate_pending_templates (void)
                                                    /*defer_ok=*/0,
                                                    /*undefined_ok=*/0);
                  if (DECL_TEMPLATE_INSTANTIATED (instantiation))
-                   {
-                     instantiated_something = 1;
-                     reconsider = 1;
-                   }
+                   reconsider = 1;
                }
 
              if (DECL_TEMPLATE_SPECIALIZATION (instantiation)
@@ -11359,7 +11366,6 @@ instantiate_pending_templates (void)
   while (reconsider);
 
   input_location = saved_loc;
-  return instantiated_something;
 }
 
 /* Substitute ARGVEC into T, which is a list of initializers for
index 57780d9a45793380586fc382a605a509d450c385..6ef35f7b66e6905a9fdc3cc154220e6ad0e6d281 100644 (file)
@@ -1,3 +1,8 @@
+2004-08-16  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       PR c++/6749
+       * g++.dg/template/vtable2.C: New test.
+
 2004-08-14  Richard Henderson  <rth@redhat.com>
 
        * gcc.dg/torture/builtin-attr-1.c: Fix scalbln prototype.
diff --git a/gcc/testsuite/g++.dg/template/vtable2.C b/gcc/testsuite/g++.dg/template/vtable2.C
new file mode 100644 (file)
index 0000000..9f2bf0b
--- /dev/null
@@ -0,0 +1,18 @@
+// Use a small template instantiation depth to speed up testing 
+// { dg-options "-ftemplate-depth-5" }
+// { dg-do compile }
+
+// Origin: rullo.pat@tiscalinet.it
+//        Nathanael Nerode <neroden@gcc.gnu.org>
+//        Wolfgang Bangerth <bangerth@dealii.org>
+
+// PR c++/6749: Infinite loop generating vtable.
+
+template <class T> struct inner {};
+
+template <class T> struct parent {
+  virtual void f()
+    { parent<inner<T> > p; };          // { dg-error "instantiation depth" }
+};
+
+template struct parent<int>;