PR c++/81917 - ICE with void_t and partial specialization.
authorJason Merrill <jason@redhat.com>
Fri, 9 Feb 2018 21:01:49 +0000 (16:01 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 9 Feb 2018 21:01:49 +0000 (16:01 -0500)
* pt.c (instantiate_class_template_1): Set TYPE_BEING_DEFINED before
calling most_specialized_partial_spec.

From-SVN: r257542

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/alias-decl-62.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/initlist-template2.C
gcc/testsuite/g++.dg/template/crash125.C
gcc/testsuite/g++.dg/template/pr51488.C
gcc/testsuite/g++.dg/template/pr55843.C

index cea51ff..9df4c29 100644 (file)
@@ -1,3 +1,9 @@
+2018-02-09  Jason Merrill  <jason@redhat.com>
+
+       PR c++/81917 - ICE with void_t and partial specialization.
+       * pt.c (instantiate_class_template_1): Set TYPE_BEING_DEFINED before
+       calling most_specialized_partial_spec.
+
 2018-02-09  Nathan Sidwell  <nathan@acm.org>
 
        PR c/84293
index 9c57709..2816045 100644 (file)
@@ -10347,14 +10347,14 @@ instantiate_class_template_1 (tree type)
   templ = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
   gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL);
 
+  /* Mark the type as in the process of being defined.  */
+  TYPE_BEING_DEFINED (type) = 1;
+
   /* Determine what specialization of the original template to
      instantiate.  */
   t = most_specialized_partial_spec (type, tf_warning_or_error);
   if (t == error_mark_node)
-    {
-      TYPE_BEING_DEFINED (type) = 1;
-      return error_mark_node;
-    }
+    return error_mark_node;
   else if (t)
     {
       /* This TYPE is actually an instantiation of a partial
@@ -10379,16 +10379,16 @@ instantiate_class_template_1 (tree type)
   /* If the template we're instantiating is incomplete, then clearly
      there's nothing we can do.  */
   if (!COMPLETE_TYPE_P (pattern))
-    return type;
+    {
+      /* We can try again later.  */
+      TYPE_BEING_DEFINED (type) = 0;
+      return type;
+    }
 
   /* If we've recursively instantiated too many templates, stop.  */
   if (! push_tinst_level (type))
     return type;
 
-  /* Now we're really doing the instantiation.  Mark the type as in
-     the process of being defined.  */
-  TYPE_BEING_DEFINED (type) = 1;
-
   /* We may be in the middle of deferred access check.  Disable
      it now.  */
   push_deferring_access_checks (dk_no_deferred);
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-62.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-62.C
new file mode 100644 (file)
index 0000000..6f1fa45
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/81917
+// { dg-do compile { target c++11 } }
+
+template <typename> using a = void;
+template <typename, typename = void> struct b
+{
+  typedef int c;
+};
+template <typename d> class b<d, a<typename d::e>>;
+template <typename d, typename = typename b<d>::c> class f;
+template <typename> class g { };
+template <typename, typename> class h
+{
+  class i;
+  typedef g<f<i>> j;
+  class i
+  {
+    j k;                       // { dg-error "incomplete" }
+  };
+};
+h<int, int> H;
+
index 40e3075..0df0d4e 100644 (file)
@@ -1,6 +1,5 @@
 // PR c++/71747
 // { dg-do compile { target c++11 } }
-// { dg-options -ftemplate-depth=20 }
 
 template < bool > struct A
 {
@@ -14,10 +13,8 @@ template < bool > struct A
 template < bool, typename = int > struct F; 
 template < bool X > 
 // should be: struct F < X, typename A < A < X > {} () >::type > 
-struct F < X, typename A < F < X > {} () >::type > // { dg-error "" }
+struct F < X, typename A < F < X > {} () >::type >
 {
 };
 
-F < true > f;
-
-// { dg-prune-output "compilation terminated" }
+F < true > f;                  // { dg-error "" }
index 448f746..de41b99 100644 (file)
@@ -13,6 +13,4 @@ struct TraitCheckImpl<Swappable<T> > {
     typedef void Complete;
 };
 
-Swappable<int> s;  // { dg-error "depth" }
-
-// { dg-prune-output "compilation terminated" }
+Swappable<int> s;  // { dg-error "" }
index 4979a22..794a6cf 100644 (file)
@@ -2,6 +2,4 @@
 
 template<class T,class U=void> struct s;
 template<class T> struct s<T,typename s<T>::a> {};
-s<int> ca;  // { dg-error "depth" }
-
-// { dg-prune-output "compilation terminated" }
+s<int> ca;  // { dg-error "" }
index 467dd82..04079ed 100644 (file)
@@ -1,5 +1,3 @@
-// { dg-options "-ftemplate-depth-8" }
-
 template< typename T > struct type_wrapper {
 };
 typedef char (&yes_tag)[2];
@@ -7,11 +5,11 @@ template<bool b> struct if_c {
 };
 template< typename T > struct has_type {
   struct gcc_3_2_wknd {
-    template< typename U > static yes_tag test( type_wrapper<U> const volatile* // { dg-message "required" }
+    template< typename U > static yes_tag test( type_wrapper<U> const volatile* // { dg-message "" }
 , type_wrapper<typename U::type>* = 0 );
   };
   typedef type_wrapper<T> t_;
-  static const bool value = sizeof(gcc_3_2_wknd::test(static_cast<t_*>(0))) == // { dg-message "required" }
+  static const bool value = sizeof(gcc_3_2_wknd::test(static_cast<t_*>(0))) == // { dg-message "" }
 sizeof(yes_tag);
 };
 template <class K, class T, class=void> struct Get_type {
@@ -22,7 +20,4 @@ template <class K> struct Get_type<K, RT_tag, typename if_c<
 !has_type<Get_type<K, FT_tag> >::value >::type> { }; // { dg-message "required" }
 template <class K> struct Get_type<K, FT_tag, typename if_c<
 !has_type<Get_type<K, RT_tag> >::value >::type> { };  // { dg-message "required" }
-typedef Get_type<int, FT_tag>::type P;
-
-// { dg-prune-output "-ftemplate-depth" }
-// { dg-prune-output "compilation terminated" }
+typedef Get_type<int, FT_tag>::type P;               // { dg-message "" }