From 57a6add274e98def9fe937eea126c56a71e65c28 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 21 Dec 2016 14:38:44 -0500 Subject: [PATCH] Fix handling of explicit function template arguments with TTPs. gcc/cp/ * pt.c (coerce_template_parms): Consider variadic_args_p before complaining about too many template arguments. libstdc++-v3/ * testsuite/util/testsuite_tr1.h (test_property): Don't define both variadic and non-variadic overloads. From-SVN: r243869 --- gcc/cp/ChangeLog | 3 +++ gcc/cp/pt.c | 2 +- gcc/testsuite/g++.dg/cpp0x/variadic-ttp3.C | 23 +++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/variadic-ttp3a.C | 20 ++++++++++++++++++ libstdc++-v3/ChangeLog | 5 +++++ libstdc++-v3/testsuite/util/testsuite_tr1.h | 19 +++++++---------- 6 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-ttp3.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-ttp3a.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7faac155e34..05d6dba39c3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2016-12-21 Jason Merrill + * pt.c (coerce_template_parms): Consider variadic_args_p before + complaining about too many template arguments. + * pt.c (process_partial_specialization): Use get_partial_spec_bindings to check that the partial specialization is more specialized than the primary template. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8abbcfb6f43..f839c538487 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7658,7 +7658,7 @@ coerce_template_parms (tree parms, variadic_args_p = pack_expansion_args_count (inner_args); nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0; - if ((nargs > nparms && !variadic_p) + if ((nargs - variadic_args_p > nparms && !variadic_p) || (nargs < nparms - variadic_p && require_all_args && !variadic_args_p diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ttp3.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp3.C new file mode 100644 index 00000000000..b1bd7a4e208 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp3.C @@ -0,0 +1,23 @@ +// Test that passing a non-variadic template to a variadic TTP works +// with explicit template arguments in a function call.. +// { dg-do compile { target c++11 } } + +template class Property, typename Type> +bool test_property(typename Property::value_type value); + +template class Property, + typename Type1, typename... Types> +bool test_property(typename Property::value_type value); + +template +struct X +{ + using type = X; + using value_type = int; + static const value_type value = 42; +}; + +int main() +{ + test_property(42); // { dg-error "ambiguous" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ttp3a.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp3a.C new file mode 100644 index 00000000000..b3599b60235 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp3a.C @@ -0,0 +1,20 @@ +// Test that passing a non-variadic template to a variadic TTP works +// with explicit template arguments in a function call.. +// { dg-do compile { target c++11 } } + +template class Property, + typename Type1, typename... Types> +bool test_property(typename Property::value_type value); + +template +struct X +{ + using type = X; + using value_type = int; + static const value_type value = 42; +}; + +int main() +{ + test_property(42); +} diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 02297e0f2bb..6263652977d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,8 @@ +2016-12-16 Jason Merrill + + * testsuite/util/testsuite_tr1.h (test_property): Don't define both + variadic and non-variadic overloads. + 2016-12-21 Jonathan Wakely PR libstdc++/71444 diff --git a/libstdc++-v3/testsuite/util/testsuite_tr1.h b/libstdc++-v3/testsuite/util/testsuite_tr1.h index c6a4986b983..908a788a93e 100644 --- a/libstdc++-v3/testsuite/util/testsuite_tr1.h +++ b/libstdc++-v3/testsuite/util/testsuite_tr1.h @@ -45,17 +45,6 @@ namespace __gnu_test && Category::type::value == value); } - template class Property, typename Type> -#if __cplusplus >= 201103L - constexpr -#endif - bool - test_property(typename Property::value_type value) - { - return (Property::value == value - && Property::type::value == value); - } - // For testing tr1/type_traits/extent, which has a second template // parameter. template class Property, @@ -79,6 +68,14 @@ namespace __gnu_test return (Property::value == value && Property::type::value == value); } +#else + template class Property, typename Type> + bool + test_property(typename Property::value_type value) + { + return (Property::value == value + && Property::type::value == value); + } #endif template class Relationship, -- 2.30.2