From 157420b4bd936f18b64d8143a6b3f32f89689412 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 16 Jun 2017 22:27:52 -0400 Subject: [PATCH] PR c++/80174 - ICE with partial specialization of member template. PR c++/71747 * pt.c (get_partial_spec_bindings): Only coerce innermost args. From-SVN: r249319 --- gcc/cp/ChangeLog | 4 +++ gcc/cp/pt.c | 8 ++++-- .../g++.dg/template/partial-specialization6.C | 28 +++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/partial-specialization6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 48a9cf698fe..330f0f205a0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2017-06-16 Jason Merrill + PR c++/80174 - ICE with partial specialization of member template. + PR c++/71747 + * pt.c (get_partial_spec_bindings): Only coerce innermost args. + PR c++/80831 - ICE with -fsyntax-only. * decl2.c (c_parse_final_cleanups): Use cgraph_node::get_create. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3dad0fc6741..0a581630347 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -21672,9 +21672,11 @@ get_partial_spec_bindings (tree tmpl, tree spec_tmpl, tree args) `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); - spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl), - spec_args, tmpl, - tf_none, false, false); + + if (spec_args != error_mark_node) + spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl), + INNERMOST_TEMPLATE_ARGS (spec_args), + tmpl, tf_none, false, false); pop_tinst_level (); diff --git a/gcc/testsuite/g++.dg/template/partial-specialization6.C b/gcc/testsuite/g++.dg/template/partial-specialization6.C new file mode 100644 index 00000000000..51a15905839 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial-specialization6.C @@ -0,0 +1,28 @@ +// PR c++/80174 + +typedef unsigned char uint8_t; + +template +struct HighestMaxFieldIdx { + static const uint8_t maxFieldIdx = T::fieldIdx; +}; + +template +struct Outer { + + template + struct Varint {}; + + + template + struct Varint<_fieldIdx, uint8_t, field> { + static const uint8_t fieldIdx = _fieldIdx; + }; +}; + +struct Msg { + uint8_t a; + + static const uint8_t t + = HighestMaxFieldIdx::Varint<1, uint8_t, &Msg::a> >::maxFieldIdx; +}; -- 2.30.2