aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-02-09 16:01:49 -0500
committerJason Merrill <jason@gcc.gnu.org>2018-02-09 16:01:49 -0500
commit83fe399c27e269e48c54bf5d505973b5c03da072 (patch)
tree735b075cf6fd462d211da21ec9ca17eabb295b92 /gcc
parentc028d589e94a67795a25763bc95b778e1480f106 (diff)
downloadgcc-83fe399c27e269e48c54bf5d505973b5c03da072.zip
gcc-83fe399c27e269e48c54bf5d505973b5c03da072.tar.gz
gcc-83fe399c27e269e48c54bf5d505973b5c03da072.tar.bz2
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. From-SVN: r257542
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-62.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist-template2.C7
-rw-r--r--gcc/testsuite/g++.dg/template/crash125.C4
-rw-r--r--gcc/testsuite/g++.dg/template/pr51488.C4
-rw-r--r--gcc/testsuite/g++.dg/template/pr55843.C11
7 files changed, 44 insertions, 28 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cea51ff..9df4c29 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 9c57709..2816045 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
index 0000000..6f1fa45
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-62.C
@@ -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;
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-template2.C b/gcc/testsuite/g++.dg/cpp0x/initlist-template2.C
index 40e3075..0df0d4e 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist-template2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-template2.C
@@ -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 "" }
diff --git a/gcc/testsuite/g++.dg/template/crash125.C b/gcc/testsuite/g++.dg/template/crash125.C
index 448f746..de41b99 100644
--- a/gcc/testsuite/g++.dg/template/crash125.C
+++ b/gcc/testsuite/g++.dg/template/crash125.C
@@ -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 "" }
diff --git a/gcc/testsuite/g++.dg/template/pr51488.C b/gcc/testsuite/g++.dg/template/pr51488.C
index 4979a22..794a6cf 100644
--- a/gcc/testsuite/g++.dg/template/pr51488.C
+++ b/gcc/testsuite/g++.dg/template/pr51488.C
@@ -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 "" }
diff --git a/gcc/testsuite/g++.dg/template/pr55843.C b/gcc/testsuite/g++.dg/template/pr55843.C
index 467dd82..04079ed 100644
--- a/gcc/testsuite/g++.dg/template/pr55843.C
+++ b/gcc/testsuite/g++.dg/template/pr55843.C
@@ -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 "" }