re PR c++/66405 (ICE: in tsubst, at cp/pt.c:11984)
authorJason Merrill <jason@redhat.com>
Fri, 5 Jun 2015 19:14:02 +0000 (15:14 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 5 Jun 2015 19:14:02 +0000 (15:14 -0400)
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.

From-SVN: r224163

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/variadic-alias1.C [new file with mode: 0644]

index e9a78b3ccb6ebfa62e291196a439a9c62adb3371..99988ef4ba823b50e6e17bd495ae615cdd7615c3 100644 (file)
@@ -1,5 +1,10 @@
 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.
index 87b35fa99dee7e388c06b3cafdf55654a0789b62..4a9fff043e9ef7ebeaefdaf01f712acad7461912 100644 (file)
@@ -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 (file)
index 0000000..e931bc5
--- /dev/null
@@ -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(){}