Commit 35046a54 by Kriang Lerdsuwanakij Committed by Kriang Lerdsuwanakij

re PR c++/6749 (infinite loop with inheritance of abstract classes)

	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
parent a20f4d83
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> 2004-08-15 Roger Sayle <roger@eyesopen.com>
* call.c (build_vfield_ref, build_call, build_conditional_expr, * call.c (build_vfield_ref, build_call, build_conditional_expr,
......
...@@ -3990,7 +3990,7 @@ extern void maybe_process_partial_specialization (tree); ...@@ -3990,7 +3990,7 @@ extern void maybe_process_partial_specialization (tree);
extern void maybe_check_template_type (tree); extern void maybe_check_template_type (tree);
extern tree most_specialized_instantiation (tree); extern tree most_specialized_instantiation (tree);
extern void print_candidates (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_default_argument (tree, tree, tree);
extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t, tree, bool); extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t, tree, bool);
extern tree most_general_template (tree); extern tree most_general_template (tree);
......
...@@ -2721,6 +2721,7 @@ finish_file (void) ...@@ -2721,6 +2721,7 @@ finish_file (void)
size_t i; size_t i;
location_t locus; location_t locus;
unsigned ssdf_count = 0; unsigned ssdf_count = 0;
int retries = 0;
locus = input_location; locus = input_location;
at_eof = 1; at_eof = 1;
...@@ -2772,7 +2773,7 @@ finish_file (void) ...@@ -2772,7 +2773,7 @@ finish_file (void)
/* If there are templates that we've put off instantiating, do /* If there are templates that we've put off instantiating, do
them now. */ them now. */
instantiate_pending_templates (); instantiate_pending_templates (retries);
ggc_collect (); ggc_collect ();
/* Write out virtual tables as required. Note that writing out /* Write out virtual tables as required. Note that writing out
...@@ -2780,7 +2781,7 @@ finish_file (void) ...@@ -2780,7 +2781,7 @@ finish_file (void)
instantiation of members of that class. If we write out instantiation of members of that class. If we write out
vtables then we remove the class from our list so we don't vtables then we remove the class from our list so we don't
have to look at it again. */ have to look at it again. */
while (keyed_classes != NULL_TREE while (keyed_classes != NULL_TREE
&& maybe_emit_vtables (TREE_VALUE (keyed_classes))) && maybe_emit_vtables (TREE_VALUE (keyed_classes)))
{ {
...@@ -2806,14 +2807,14 @@ finish_file (void) ...@@ -2806,14 +2807,14 @@ finish_file (void)
next = TREE_CHAIN (t); next = TREE_CHAIN (t);
} }
} }
/* Write out needed type info variables. We have to be careful /* Write out needed type info variables. We have to be careful
looping through unemitted decls, because emit_tinfo_decl may looping through unemitted decls, because emit_tinfo_decl may
cause other variables to be needed. We stick new elements cause other variables to be needed. We stick new elements
(and old elements that we may need to reconsider) at the end (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 of the array, then shift them back to the beginning once we're
done. */ done. */
n_old = VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls); n_old = VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls);
for (i = 0; i < n_old; ++i) for (i = 0; i < n_old; ++i)
{ {
...@@ -2994,6 +2995,8 @@ finish_file (void) ...@@ -2994,6 +2995,8 @@ finish_file (void)
reconsider = true; reconsider = true;
if (cgraph_varpool_assemble_pending_decls ()) if (cgraph_varpool_assemble_pending_decls ())
reconsider = true; reconsider = true;
retries++;
} }
while (reconsider); while (reconsider);
......
...@@ -11272,17 +11272,30 @@ out: ...@@ -11272,17 +11272,30 @@ out:
} }
/* Run through the list of templates that we wish we could /* 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 void
instantiate_pending_templates (void) instantiate_pending_templates (int retries)
{ {
tree *t; tree *t;
tree last = NULL_TREE; tree last = NULL_TREE;
int instantiated_something = 0;
int reconsider; int reconsider;
location_t saved_loc = input_location; 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 do
{ {
reconsider = 0; reconsider = 0;
...@@ -11309,10 +11322,7 @@ instantiate_pending_templates (void) ...@@ -11309,10 +11322,7 @@ instantiate_pending_templates (void)
instantiate_decl (fn, /*defer_ok=*/0, instantiate_decl (fn, /*defer_ok=*/0,
/*undefined_ok=*/0); /*undefined_ok=*/0);
if (COMPLETE_TYPE_P (instantiation)) if (COMPLETE_TYPE_P (instantiation))
{ reconsider = 1;
instantiated_something = 1;
reconsider = 1;
}
} }
if (COMPLETE_TYPE_P (instantiation)) if (COMPLETE_TYPE_P (instantiation))
...@@ -11334,10 +11344,7 @@ instantiate_pending_templates (void) ...@@ -11334,10 +11344,7 @@ instantiate_pending_templates (void)
/*defer_ok=*/0, /*defer_ok=*/0,
/*undefined_ok=*/0); /*undefined_ok=*/0);
if (DECL_TEMPLATE_INSTANTIATED (instantiation)) if (DECL_TEMPLATE_INSTANTIATED (instantiation))
{ reconsider = 1;
instantiated_something = 1;
reconsider = 1;
}
} }
if (DECL_TEMPLATE_SPECIALIZATION (instantiation) if (DECL_TEMPLATE_SPECIALIZATION (instantiation)
...@@ -11359,7 +11366,6 @@ instantiate_pending_templates (void) ...@@ -11359,7 +11366,6 @@ instantiate_pending_templates (void)
while (reconsider); while (reconsider);
input_location = saved_loc; input_location = saved_loc;
return instantiated_something;
} }
/* Substitute ARGVEC into T, which is a list of initializers for /* Substitute ARGVEC into T, which is a list of initializers for
......
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> 2004-08-14 Richard Henderson <rth@redhat.com>
* gcc.dg/torture/builtin-attr-1.c: Fix scalbln prototype. * gcc.dg/torture/builtin-attr-1.c: Fix scalbln prototype.
......
// 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>;
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