From: jason Date: Tue, 17 Apr 2012 02:29:51 +0000 (+0000) Subject: PR c++/38543 X-Git-Tag: upstream/4.9.2~13232 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bc38e4e11df22f8cbd889412a996ced7e065cbc9;p=platform%2Fupstream%2Flinaro-gcc.git PR c++/38543 * pt.c (determine_specialization): Instead of comparing the number of parms, check that tsubst gives the right answer. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186522 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1b7f4be..8746c64 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2012-04-16 Jason Merrill + PR c++/38543 + * pt.c (determine_specialization): Instead of comparing the number + of parms, check that tsubst gives the right answer. + PR c++/52008 * pt.c (process_partial_specialization): Complain about a partial specialization with fewer args than primary template parms. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d6144d5..0ca6993 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1839,6 +1839,7 @@ determine_specialization (tree template_id, { tree decl_arg_types; tree fn_arg_types; + tree insttype; /* In case of explicit specialization, we need to check if the number of template headers appearing in the specialization @@ -1900,15 +1901,6 @@ determine_specialization (tree template_id, fn_arg_types = skip_artificial_parms_for (fn, fn_arg_types); - /* Check that the number of function parameters matches. - For example, - template void f(int i = 0); - template <> void f(); - The specialization f is invalid but is not caught - by get_bindings below. */ - if (list_length (fn_arg_types) != list_length (decl_arg_types)) - continue; - /* Function templates cannot be specializations; there are no partial specializations of functions. Therefore, if the type of DECL does not match FN, there is no @@ -1929,6 +1921,15 @@ determine_specialization (tree template_id, specialize TMPL will produce DECL. */ continue; + /* Make sure that the deduced arguments actually work. */ + insttype = tsubst (TREE_TYPE (fn), targs, tf_none, NULL_TREE); + if (insttype == error_mark_node) + continue; + fn_arg_types + = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (insttype)); + if (!compparms (fn_arg_types, decl_arg_types)) + continue; + /* Save this template, and the arguments deduced. */ templates = tree_cons (targs, fn, templates); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2acdffe..0b6fcf5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2012-04-16 Jason Merrill + PR c++/38543 + * g++.dg/cpp0x/variadic131.C: New. + PR c++/52008 * g++.dg/cpp0x/variadic130.C: New. diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic131.C b/gcc/testsuite/g++.dg/cpp0x/variadic131.C new file mode 100644 index 0000000..3006f87 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic131.C @@ -0,0 +1,11 @@ +// PR c++/38543 +// { dg-do compile { target c++11 } } + +template< typename ... T > void foo( T ... args ); +template<> void foo( ){} +template<> void foo(int,double){} +int main() +{ + foo( 0, 0.0 ); + return 55; +}