aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/pt.c23
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic-alias1.C13
3 files changed, 35 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e9a78b3..99988ef 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,6 +1,11 @@
2015-06-05 Jason Merrill <jason@redhat.com>
PR c++/66405
+ * pt.c (argument_pack_element_is_expansion_p): Return 2 if
+ the expansion has extra args.
+ (use_pack_expansion_extra_args_p): Return true in that case.
+
+ PR c++/66405
* pt.c (type_dependent_expression_p): EXPR_PACK_EXPANSION is
dependent even if it has a type.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 87b35fa..4a9fff0 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -9740,16 +9740,22 @@ make_fnparm_pack (tree spec_parm)
return extract_fnparm_pack (NULL_TREE, &spec_parm);
}
-/* Return true iff the Ith element of the argument pack ARG_PACK is a
- pack expansion. */
+/* Return 1 if the Ith element of the argument pack ARG_PACK is a
+ pack expansion with no extra args, 2 if it has extra args, or 0
+ if it is not a pack expansion. */
-static bool
+static int
argument_pack_element_is_expansion_p (tree arg_pack, int i)
{
tree vec = ARGUMENT_PACK_ARGS (arg_pack);
if (i >= TREE_VEC_LENGTH (vec))
- return false;
- return PACK_EXPANSION_P (TREE_VEC_ELT (vec, i));
+ return 0;
+ tree elt = TREE_VEC_ELT (vec, i);
+ if (!PACK_EXPANSION_P (elt))
+ return 0;
+ if (PACK_EXPANSION_EXTRA_ARGS (elt))
+ return 2;
+ return 1;
}
@@ -9799,7 +9805,12 @@ use_pack_expansion_extra_args_p (tree parm_packs,
{
tree arg = TREE_VALUE (parm_pack);
- if (argument_pack_element_is_expansion_p (arg, i))
+ int exp = argument_pack_element_is_expansion_p (arg, i);
+ if (exp == 2)
+ /* We can't substitute a pack expansion with extra args into
+ our pattern. */
+ return true;
+ else if (exp)
has_expansion_arg = true;
else
has_non_expansion_arg = true;
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-alias1.C b/gcc/testsuite/g++.dg/cpp0x/variadic-alias1.C
new file mode 100644
index 0000000..e931bc5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-alias1.C
@@ -0,0 +1,13 @@
+// PR c++/66405
+// { dg-do compile { target c++11 } }
+
+template <typename T, T...> struct B;
+template <bool... Bools> using and_c = B<bool, +Bools...>;
+template <typename T, typename U> using Constructible = int;
+template <typename... Ts> struct common_tuple {
+ template <typename... Us,
+ typename = and_c<Constructible<Ts, Us>{}...> >
+ common_tuple();
+ void foo();
+};
+template <> void common_tuple<>::foo(){}