From 83fe399c27e269e48c54bf5d505973b5c03da072 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 9 Feb 2018 16:01:49 -0500 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 6 +++++ gcc/cp/pt.c | 18 +++++++-------- gcc/testsuite/g++.dg/cpp0x/alias-decl-62.C | 22 +++++++++++++++++++ .../g++.dg/cpp0x/initlist-template2.C | 7 ++---- gcc/testsuite/g++.dg/template/crash125.C | 4 +--- gcc/testsuite/g++.dg/template/pr51488.C | 4 +--- gcc/testsuite/g++.dg/template/pr55843.C | 11 +++------- 7 files changed, 44 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-62.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cea51ff39a8..9df4c2948af 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-02-09 Jason Merrill + + 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 PR c/84293 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9c57709e7a7..281604594ad 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 00000000000..6f1fa4584ac --- /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 using a = void; +template struct b +{ + typedef int c; +}; +template class b>; +template ::c> class f; +template class g { }; +template class h +{ + class i; + typedef g> j; + class i + { + j k; // { dg-error "incomplete" } + }; +}; +h H; + diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-template2.C b/gcc/testsuite/g++.dg/cpp0x/initlist-template2.C index 40e3075c162..0df0d4e89c3 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 448f74682d4..de41b99a927 100644 --- a/gcc/testsuite/g++.dg/template/crash125.C +++ b/gcc/testsuite/g++.dg/template/crash125.C @@ -13,6 +13,4 @@ struct TraitCheckImpl > { typedef void Complete; }; -Swappable s; // { dg-error "depth" } - -// { dg-prune-output "compilation terminated" } +Swappable s; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/pr51488.C b/gcc/testsuite/g++.dg/template/pr51488.C index 4979a22787c..794a6cfe067 100644 --- a/gcc/testsuite/g++.dg/template/pr51488.C +++ b/gcc/testsuite/g++.dg/template/pr51488.C @@ -2,6 +2,4 @@ template struct s; template struct s::a> {}; -s ca; // { dg-error "depth" } - -// { dg-prune-output "compilation terminated" } +s ca; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/pr55843.C b/gcc/testsuite/g++.dg/template/pr55843.C index 467dd827218..04079ed1175 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 struct if_c { }; template< typename T > struct has_type { struct gcc_3_2_wknd { - template< typename U > static yes_tag test( type_wrapper const volatile* // { dg-message "required" } + template< typename U > static yes_tag test( type_wrapper const volatile* // { dg-message "" } , type_wrapper* = 0 ); }; typedef type_wrapper t_; - static const bool value = sizeof(gcc_3_2_wknd::test(static_cast(0))) == // { dg-message "required" } + static const bool value = sizeof(gcc_3_2_wknd::test(static_cast(0))) == // { dg-message "" } sizeof(yes_tag); }; template struct Get_type { @@ -22,7 +20,4 @@ template struct Get_type >::value >::type> { }; // { dg-message "required" } template struct Get_type >::value >::type> { }; // { dg-message "required" } -typedef Get_type::type P; - -// { dg-prune-output "-ftemplate-depth" } -// { dg-prune-output "compilation terminated" } +typedef Get_type::type P; // { dg-message "" } -- 2.30.2