Index: cp/pt.c =================================================================== --- cp/pt.c (revision 212204) +++ cp/pt.c (working copy) @@ -8905,8 +8911,15 @@ instantiate_class_template_1 (tree type) gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL); /* Determine what specialization of the original template to - instantiate. */ - t = most_specialized_class (type, tf_warning_or_error); + instantiate. Note: protect vs too deep instantiation. */ + if (push_tinst_level (type)) + { + t = most_specialized_class (type, tf_warning_or_error); + pop_tinst_level (); + } + else + t = error_mark_node; + if (t == error_mark_node) { TYPE_BEING_DEFINED (type) = 1; Index: testsuite/g++.dg/cpp0x/template-recurse1.C =================================================================== --- testsuite/g++.dg/cpp0x/template-recurse1.C (revision 0) +++ testsuite/g++.dg/cpp0x/template-recurse1.C (working copy) @@ -0,0 +1,25 @@ +// PR c++/58059 +// { dg-do compile { target c++11 } } + +template struct enable_if { typedef T type; }; +template struct enable_if { }; + +// This code is nonsense; it was produced by minimizing the problem repeatedly. +constexpr bool test_func(int value) { + return true; +} +template +struct test_class { + static constexpr int value = 0; +}; +template +struct test_class< + TParm, + // This line ultimately causes the crash. + typename enable_if::value)>::type // { dg-error "depth exceeds" } + > { + static constexpr int value = 1; +}; + +// This instantiation is required in order to crash. +template class test_class<2,void>; Index: testsuite/g++.dg/template/recurse.C =================================================================== --- testsuite/g++.dg/template/recurse.C (revision 212204) +++ testsuite/g++.dg/template/recurse.C (working copy) @@ -5,9 +5,7 @@ template struct F { int operator()() { - F f; // { dg-error "incomplete type" "incomplete" } - // { dg-bogus "exceeds maximum.*exceeds maximum" "exceeds" { xfail *-*-* } 8 } - // { dg-error "exceeds maximum" "exceeds" { xfail *-*-* } 8 } + F f; // { dg-error "depth exceeds|incomplete" } return f()*I; // { dg-message "recursively" "recurse" } } }; Index: testsuite/g++.dg/template/recurse4.C =================================================================== --- testsuite/g++.dg/template/recurse4.C (revision 0) +++ testsuite/g++.dg/template/recurse4.C (working copy) @@ -0,0 +1,5 @@ +// PR c++/51488 + +template struct s; +template struct s::a> {}; +s ca; // { dg-error "depth exceeds|incomplete" }