commit a6e5d2436bf09049eba9d2f04d12e33621760947
Author: Jason Merrill <jason@redhat.com>
Date: Tue Apr 1 16:22:01 2014 -0400
PR c++/60374
* pt.c (coerce_template_parms): Check that the pack expansion
pattern works with the first matching parameter.
@@ -6933,6 +6933,26 @@ coerce_template_parms (tree parms,
{
if (PACK_EXPANSION_P (arg))
{
+ /* "If every valid specialization of a variadic template
+ requires an empty template parameter pack, the template is
+ ill-formed, no diagnostic required." So check that the
+ pattern works with this parameter. */
+ tree pattern = PACK_EXPANSION_PATTERN (arg);
+ tree conv = convert_template_argument (TREE_VALUE (parm),
+ pattern, new_args,
+ complain, parm_idx,
+ in_decl);
+ if (conv == error_mark_node)
+ {
+ inform (input_location, "so any instantiation with a "
+ "non-empty parameter pack would be ill-formed");
+ ++lost;
+ }
+ else if (TYPE_P (conv) && !TYPE_P (pattern))
+ /* Recover from missing typename. */
+ TREE_VEC_ELT (inner_args, arg_idx)
+ = make_pack_expansion (conv);
+
/* We don't know how many args we have yet, just
use the unconverted ones for now. */
new_inner_args = inner_args;
new file mode 100644
@@ -0,0 +1,8 @@
+// PR c++/60374
+// { dg-do compile { target c++11 } }
+
+template<typename> struct A {};
+
+template<typename...T> struct A<T::T...> {}; // { dg-error "typename|partial|T" }
+
+A<int> a;
new file mode 100644
@@ -0,0 +1,4 @@
+// { dg-do compile { target c++11 } }
+
+template <typename T> struct A {};
+template <int... I> struct B: A<I...> {}; // { dg-error "type" }
commit 522f1b1012384a1d96608690fa79079585038e55
Author: Jason Merrill <jason@redhat.com>
Date: Tue Apr 1 15:31:59 2014 -0400
* pt.c (process_partial_specialization): Say "not deducible"
rather than "not used". Use inform.
@@ -4139,15 +4139,17 @@ process_partial_specialization (tree decl)
for (i = 0; i < ntparms; ++i)
if (tpd.parms[i] == 0)
{
- /* One of the template parms was not used in the
+ /* One of the template parms was not used in a deduced context in the
specialization. */
if (!did_error_intro)
{
- error ("template parameters not used in partial specialization:");
+ error ("template parameters not deducible in "
+ "partial specialization:");
did_error_intro = true;
}
- error (" %qD", TREE_VALUE (TREE_VEC_ELT (inner_parms, i)));
+ inform (input_location, " %qD",
+ TREE_VALUE (TREE_VEC_ELT (inner_parms, i)));
}
if (did_error_intro)
@@ -1,7 +1,7 @@
// { dg-do compile { target c++11 } }
template<typename...> struct A;
-template<char> struct A<> {}; // { dg-error "not used in partial specialization|anonymous|declaration" }
+template<char> struct A<> {}; // { dg-error "not deducible|anonymous|declaration" }
template<typename T, typename... U> struct A<T, U...> : A<U...> {}; // { dg-error "incomplete type" }
@@ -6,7 +6,7 @@ struct foo
};
template<typename ... Args>
-struct foo< typename Args::is_applied... > // { dg-error "not used|Args" }
+struct foo< typename Args::is_applied... > // { dg-error "not deducible|Args" }
{
static bool const value = false;
};
@@ -2,7 +2,7 @@
template<typename> struct A {};
-template<typename> struct A<int> // { dg-error "not used|template\\-parameter" }
+template<typename> struct A<int> // { dg-error "not deducible|template\\-parameter" }
{
template<int> void foo();
};
@@ -2,7 +2,7 @@
template < typename > struct A;
-template < typename > struct A < int > // { dg-error "not used|template\\-parameter|declaration" }
+template < typename > struct A < int > // { dg-error "not deducible|template\\-parameter|declaration" }
{
int i;
int f ();
@@ -4,7 +4,7 @@ template<typename T>
struct X { };
template<typename T>
-struct X<typename T::foo> { }; // { dg-error "not used|T" }
+struct X<typename T::foo> { }; // { dg-error "not deducible|T" }
template<int N>
struct X<int[N]> {}; // okay
@@ -14,7 +14,7 @@ template<typename T, typename T::foo V>
struct Y { };
template<typename T, typename U, U v>
-struct Y<T, v> { }; // { dg-error "not used|U" }
+struct Y<T, v> { }; // { dg-error "not deducible|U" }
template<typename T, T V>