From a9410b4fe946b3f82ff2254b46ef53573897d68e Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 21 Dec 2016 14:38:35 -0500 Subject: [PATCH] Check that a partial specialization is more specialized. * pt.c (process_partial_specialization): Use get_partial_spec_bindings to check that the partial specialization is more specialized than the primary template. From-SVN: r243868 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/pt.c | 11 +++++++++++ gcc/testsuite/g++.dg/cpp0x/constexpr-data2.C | 2 +- gcc/testsuite/g++.dg/cpp0x/variadic82.C | 4 ++-- gcc/testsuite/g++.dg/cpp0x/variadic83.C | 4 ++-- gcc/testsuite/g++.dg/template/partial5.C | 2 +- 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4c68b1e4e3e..7faac155e34 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2016-12-21 Jason Merrill + * pt.c (process_partial_specialization): Use + get_partial_spec_bindings to check that the partial specialization + is more specialized than the primary template. + * pt.c (convert_template_argument): Pass args to do_auto_deduction. (mark_template_parm): Handle deducibility from type of non-type argument here. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9d9c35e47e6..8abbcfb6f43 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4606,9 +4606,20 @@ process_partial_specialization (tree decl) "primary template because it replaces multiple parameters " "with a pack expansion"); inform (DECL_SOURCE_LOCATION (maintmpl), "primary template here"); + /* Avoid crash in process_partial_specialization. */ return decl; } + /* If we aren't in a dependent class, we can actually try deduction. */ + else if (tpd.level == 1 + && !get_partial_spec_bindings (maintmpl, maintmpl, specargs)) + { + if (permerror (input_location, "partial specialization %qD is not " + "more specialized than", decl)) + inform (DECL_SOURCE_LOCATION (maintmpl), "primary template %qD", + maintmpl); + } + /* [temp.class.spec] A partially specialized non-type argument expression shall not diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-data2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-data2.C index 312760a3767..898102167de 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-data2.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-data2.C @@ -12,7 +12,7 @@ template }; // Partial specialization. -template +template struct A3<_Tp*, v> { typedef _Tp* value_type; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic82.C b/gcc/testsuite/g++.dg/cpp0x/variadic82.C index f9bbc353268..9ac59cd5f41 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic82.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic82.C @@ -3,9 +3,9 @@ template struct A; -template struct A // { dg-bogus "cannot expand" "" } +template struct A // { dg-error "" } { struct B; }; -A a; // { dg-bogus "incomplete type" "" } +A a; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic83.C b/gcc/testsuite/g++.dg/cpp0x/variadic83.C index 507fc7e4c6c..c751e7327ca 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic83.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic83.C @@ -3,6 +3,6 @@ template struct A; -template struct A { }; // { dg-bogus "cannot expand" "" } +template struct A { }; // { dg-error "" } -A a; // { dg-bogus "incomplete type" "" } +A a; diff --git a/gcc/testsuite/g++.dg/template/partial5.C b/gcc/testsuite/g++.dg/template/partial5.C index 2f400f7d44c..1b56fb39fa1 100644 --- a/gcc/testsuite/g++.dg/template/partial5.C +++ b/gcc/testsuite/g++.dg/template/partial5.C @@ -14,7 +14,7 @@ template struct Y { }; template -struct Y { }; // { dg-error "not deducible|U" "" { target { ! c++1z } } } +struct Y { }; // { dg-error "" } template -- 2.30.2