]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/69842 (Parameter deduction in polymorphic lambdas)
authorJason Merrill <jason@redhat.com>
Thu, 25 Feb 2016 15:23:47 +0000 (10:23 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 25 Feb 2016 15:23:47 +0000 (10:23 -0500)
PR c++/69842
* method.c (forward_parm): Handle parameter packs.
* lambda.c (maybe_add_lambda_conv_op): Use it for them.

From-SVN: r233719

gcc/cp/ChangeLog
gcc/cp/lambda.c
gcc/cp/method.c
gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic4.C [new file with mode: 0644]

index 97296e4d2224f118bf90ae3a6b221a1a13437a95..ea4389d475a7bdf383f335913225b60b159f3801 100644 (file)
@@ -1,5 +1,9 @@
 2016-02-25  Jason Merrill  <jason@redhat.com>
 
+       PR c++/69842
+       * method.c (forward_parm): Handle parameter packs.
+       * lambda.c (maybe_add_lambda_conv_op): Use it for them.
+
        PR c++/67364
        * constexpr.c (cxx_eval_component_reference): Don't complain about
        unevaluated empty classes.
index 296c6f7ecf2e2720f914b833bb71e8d384f165f4..cdc11febcffa4038ddaccd37b53c2880cd8a2c58 100644 (file)
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cgraph.h"
 #include "tree-iterator.h"
 #include "toplev.h"
+#include "gimplify.h"
 
 /* Constructor for a lambda expression.  */
 
@@ -952,23 +953,18 @@ maybe_add_lambda_conv_op (tree type)
 
        if (generic_lambda_p)
          {
-           if (DECL_PACK_P (tgt))
-             {
-               tree a = make_pack_expansion (tgt);
-               if (decltype_call)
-                 CALL_EXPR_ARG (decltype_call, ix) = copy_node (a);
-               PACK_EXPANSION_LOCAL_P (a) = true;
-               CALL_EXPR_ARG (call, ix) = a;
-             }
-           else
-             {
-               ++processing_template_decl;
-               tree a = forward_parm (tgt);
-               --processing_template_decl;
-               CALL_EXPR_ARG (call, ix) = a;
-               if (decltype_call)
-                 CALL_EXPR_ARG (decltype_call, ix) = copy_node (a);
-             }
+           ++processing_template_decl;
+           tree a = forward_parm (tgt);
+           --processing_template_decl;
+
+           CALL_EXPR_ARG (call, ix) = a;
+           if (decltype_call)
+             CALL_EXPR_ARG (decltype_call, ix) = unshare_expr (a);
+
+           if (PACK_EXPANSION_P (a))
+             /* Set this after unsharing so it's not in decltype_call.  */
+             PACK_EXPANSION_LOCAL_P (a) = true;
+
            ++ix;
          }
        else
index f455b32e2a02e78f196893e5b34b8afef8800f8e..0235e6a9c22ea3ee6feed57ac882222a4e1f4fb3 100644 (file)
@@ -481,9 +481,12 @@ tree
 forward_parm (tree parm)
 {
   tree exp = convert_from_reference (parm);
-  if (TREE_CODE (TREE_TYPE (parm)) != REFERENCE_TYPE
-      || TYPE_REF_IS_RVALUE (TREE_TYPE (parm)))
-    exp = move (exp);
+  tree type = TREE_TYPE (parm);
+  if (DECL_PACK_P (parm))
+    type = PACK_EXPANSION_PATTERN (type);
+  exp = build_static_cast (type, exp, tf_warning_or_error);
+  if (DECL_PACK_P (parm))
+    exp = make_pack_expansion (exp);
   return exp;
 }
 
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic4.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic4.C
new file mode 100644 (file)
index 0000000..0b65f56
--- /dev/null
@@ -0,0 +1,20 @@
+// PR c++/69842
+// { dg-do compile { target c++14 } }
+
+template <class T, class U> struct assert_same;
+template <class T> struct assert_same<T,T> {};
+
+template<typename T>
+void sink(T &&)
+{
+  assert_same<int,T> a;
+}
+
+int main()
+{
+  auto const g([](auto &&...  _var) {
+      sink(static_cast<decltype(_var)>(_var)...);
+    });
+
+  g(0);
+}