diff mbox

[C++] PR 51448, 53618, 58059 (Take 2)

Message ID 53B51891.6050207@oracle.com
State New
Headers show

Commit Message

Paolo Carlini July 3, 2014, 8:47 a.m. UTC
Hi again,

this is IMHO more spot-on, because I figured out where exactly things go 
wrong as part of the most_specialized_class call. In complete analogy 
with the get_bindings case for functions, the problem happens in 
get_class_bindings, thus I added a simple push_tinst_level check around 
the tsubst there, which works fine for the testcases we have in this area.

Tested x86_64-linux.

Thanks,
Paolo.

/////////////////////
/cp
2014-07-03  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/51488
	PR c++/53618
	PR c++/58059
	* pt.c (get_class_bindings): Call push_tinst_level/pop_tinst_level
	around tsubst.

/testsuite
2014-07-03  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/51488
	PR c++/53618
	PR c++/58059
	* g++.dg/cpp0x/template-recurse1.C: New.
	* g++.dg/template/recurse4.C: Likewise.
	* g++.dg/template/recurse.C: Adjust.
diff mbox

Patch

Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 212223)
+++ cp/pt.c	(working copy)
@@ -18826,6 +18826,13 @@  get_class_bindings (tree tmpl, tree tparms, tree s
     if (! TREE_VEC_ELT (innermost_deduced_args, i))
       return NULL_TREE;
 
+  tree tinst = build_tree_list (tmpl, args);
+  if (! push_tinst_level (tinst))
+    {
+      ggc_free (tinst);
+      return NULL_TREE;
+    }
+
   /* Verify that nondeduced template arguments agree with the type
      obtained from argument deduction.
 
@@ -18839,6 +18846,9 @@  get_class_bindings (tree tmpl, tree tparms, tree s
      `T' is `A' but unify () does not check whether `typename T::X'
      is `int'.  */
   spec_args = tsubst (spec_args, deduced_args, tf_none, NULL_TREE);
+
+  pop_tinst_level ();
+
   spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
 				     spec_args, tmpl,
 				     tf_none, false, false);
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<bool, typename T = void> struct enable_if { typedef T type; };
+template<typename T> struct enable_if<false, T> { };
+
+// This code is nonsense; it was produced by minimizing the problem repeatedly.
+constexpr bool test_func(int value) {
+  return true;
+}
+template <int TParm, class Enable=void>
+struct test_class {
+  static constexpr int value = 0;
+};
+template <int TParm>
+struct test_class<
+    TParm,
+    // This line ultimately causes the crash.
+    typename enable_if<test_func(test_class<TParm-1>::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 212222)
+++ testsuite/g++.dg/template/recurse.C	(working copy)
@@ -5,9 +5,7 @@  template <int I> struct F
 {
   int operator()()
     {
-      F<I+1> f;			// { dg-error "incomplete type" "incomplete" }
-				// { dg-bogus "exceeds maximum.*exceeds maximum" "exceeds" { xfail *-*-* } 8 }
-                                // { dg-error "exceeds maximum" "exceeds" { xfail *-*-* } 8 }
+      F<I+1> 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<class T,class U=void> struct s;
+template<class T> struct s<T,typename s<T>::a> {};
+s<int> ca;  // { dg-error "depth exceeds|incomplete" }