re PR c++/63405 (ICE in cp_perform_integral_promotions, at cp/typeck.c:2084)
authorJason Merrill <jason@redhat.com>
Wed, 8 Oct 2014 21:05:50 +0000 (17:05 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 8 Oct 2014 21:05:50 +0000 (17:05 -0400)
PR c++/63405
* pt.c (tsubst_pack_expansion): Limit simple expansion to type packs.

From-SVN: r216013

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

index 975193d6a127a4fd215db44894117327f362a525..1f9f4121cd1d5b88c0e12779a1f232e2478965b0 100644 (file)
@@ -1,5 +1,8 @@
 2014-10-08  Jason Merrill  <jason@redhat.com>
 
+       PR c++/63405
+       * pt.c (tsubst_pack_expansion): Limit simple expansion to type packs.
+
        PR c++/63485
        * tree.c (build_cplus_array_type): Look for a type with no
        typedef-name or attributes.
index d1dddff3ac2e0bca23dcec6e7ff4b779ef93a955..7d380e54b4ac1c005da6b311937baf262bcbd248 100644 (file)
@@ -9929,7 +9929,13 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
   /* If the expansion is just T..., return the matching argument pack.  */
   if (!unsubstituted_packs
       && TREE_PURPOSE (packs) == pattern)
-    return ARGUMENT_PACK_ARGS (TREE_VALUE (packs));
+    {
+      tree args = ARGUMENT_PACK_ARGS (TREE_VALUE (packs));
+      if (TREE_CODE (t) == TYPE_PACK_EXPANSION
+         || pack_expansion_args_count (args))
+       return args;
+      /* Otherwise use the normal path so we get convert_from_reference.  */
+    }
 
   /* We cannot expand this expansion expression, because we don't have
      all of the argument packs we need.  */
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic162.C b/gcc/testsuite/g++.dg/cpp0x/variadic162.C
new file mode 100644 (file)
index 0000000..9e5386d
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/63405
+// { dg-do compile { target c++11 } }
+
+template <typename _Tp> _Tp forward(_Tp);
+template <typename Args> struct Format { Format(int, Args); };
+template <typename... Args> auto format(Args &&... args) -> Format<Args...> {
+  return {0, args...};
+}
+
+template <typename... Args> void msg(Args... args) {
+  format(forward(args)...);
+}
+
+void some_function() { msg('x'); }