diff options
author | Jason Merrill <jason@redhat.com> | 2018-02-09 16:01:49 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2018-02-09 16:01:49 -0500 |
commit | 83fe399c27e269e48c54bf5d505973b5c03da072 (patch) | |
tree | 735b075cf6fd462d211da21ec9ca17eabb295b92 /gcc | |
parent | c028d589e94a67795a25763bc95b778e1480f106 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/alias-decl-62.C | 22 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist-template2.C | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/crash125.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/pr51488.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/pr55843.C | 11 |
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 "" } |