In coerce_template_parms, inner_args is the set of args we're actually
working on, whereas "args" also includes any args of the enclosing
scope. Treating the latter as the former leads to problems when there
actually are multiple levels.
Tested x86_64-pc-linux-gnu, applying to trunk and 4.7.
commit 4e0709c10d6b3d9139eba31f6d162ae8b81915e2
Author: Jason Merrill <ja...@redhat.com>
Date: Sun Apr 15 20:28:33 2012 -0400
PR c++/52292
PR c++/52380
* pt.c (coerce_template_parms): Even if we aren't converting we
want to expand argument packs.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 07a2cc0..42dc0a7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6882,7 +6882,7 @@ coerce_template_parms (tree parms,
{
/* We don't know how many args we have yet, just
use the unconverted ones for now. */
- new_inner_args = args;
+ new_inner_args = inner_args;
break;
}
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic124.C b/gcc/testsuite/g++.dg/cpp0x/variadic124.C
new file mode 100644
index 0000000..8ddc810
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic124.C
@@ -0,0 +1,29 @@
+// PR c++/52292
+// { dg-options -std=c++11 }
+
+template <template <typename...> class T>
+struct foo {
+ template <typename... U>
+ foo(T<U...> x) { }
+};
+
+template <typename T>
+struct bar {
+ bar(T x) : value(x) { }
+
+ T value;
+};
+
+struct generic : private foo<bar> {
+ template <typename T>
+ generic(bar<T> x) : foo(x)
+ {
+ }
+
+};
+
+int main()
+{
+ bar<int> x(32);
+ generic y(x); // FAILS
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic125.C b/gcc/testsuite/g++.dg/cpp0x/variadic125.C
new file mode 100644
index 0000000..89fd6b0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic125.C
@@ -0,0 +1,25 @@
+// PR c++/52380
+// { dg-do compile { target c++11 } }
+
+template<typename T>
+struct S
+{
+ template<typename U>
+ struct Unary // Line 5
+ {};
+
+ template<unsigned, typename... Args>
+ struct Dispatch // Line 9
+ : public Unary<Args...>
+ {};
+
+ template<typename... Args>
+ struct Variadic
+ : public Dispatch<sizeof...(Args), Args...>
+ {};
+};
+
+int main()
+{
+ S<void>::Variadic<void> z;
+}