]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/69842 (Parameter deduction in polymorphic lambdas)
authorJason Merrill <jason@redhat.com>
Wed, 17 Feb 2016 20:45:15 +0000 (15:45 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 17 Feb 2016 20:45:15 +0000 (15:45 -0500)
PR c++/69842
* method.c (forward_parm): Split out from...
(add_one_base_init): ...here.
* lambda.c (maybe_add_lambda_conv_op): Use it.

From-SVN: r233506

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

index b76f85d8f365b5d1e361efdae7ea496737193334..c02ffac463226e95772bdd1e6362abbb16e1aed0 100644 (file)
@@ -1,3 +1,10 @@
+2016-02-17  Jason Merrill  <jason@redhat.com>
+
+       PR c++/69842
+       * method.c (forward_parm): Split out from...
+       (add_one_base_init): ...here.
+       * lambda.c (maybe_add_lambda_conv_op): Use it.
+
 2016-02-16  Jason Merrill  <jason@redhat.com>
 
        PR c++/10200
index 3b91089f50d08645519305b797c6616b767bec79..7800ae8316dfae10f76557e1b0fbcf38c24fbbf9 100644 (file)
@@ -6013,6 +6013,7 @@ extern tree make_thunk                            (tree, bool, tree, tree);
 extern void finish_thunk                       (tree);
 extern void use_thunk                          (tree, bool);
 extern bool trivial_fn_p                       (tree);
+extern tree forward_parm                       (tree);
 extern bool is_trivially_xible                 (enum tree_code, tree, tree);
 extern tree get_defaulted_eh_spec              (tree);
 extern tree unevaluated_noexcept_spec          (void);
index 93b192c46f17249acb9bf5727251a57b5d0f8b49..296c6f7ecf2e2720f914b833bb71e8d384f165f4 100644 (file)
@@ -962,7 +962,9 @@ maybe_add_lambda_conv_op (tree type)
              }
            else
              {
-               tree a = convert_from_reference (tgt);
+               ++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);
index e358ebd1c8c0408b14ae3b0f8bfcb7952be472b5..f455b32e2a02e78f196893e5b34b8afef8800f8e 100644 (file)
@@ -474,6 +474,19 @@ trivial_fn_p (tree fn)
   return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn));
 }
 
+/* PARM is a PARM_DECL for a function which we want to forward to another
+   function without changing its value category, a la std::forward.  */
+
+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);
+  return exp;
+}
+
 /* Subroutine of do_build_copy_constructor: Add a mem-initializer for BINFO
    given the parameter or parameters PARM, possibly inherited constructor
    base INH, or move flag MOVE_P.  */
@@ -494,10 +507,7 @@ add_one_base_init (tree binfo, tree parm, bool move_p, tree inh,
       init = NULL_TREE;
       for (; parm; parm = DECL_CHAIN (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 exp = forward_parm (parm);
          *p = build_tree_list (NULL_TREE, exp);
          p = &TREE_CHAIN (*p);
        }
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-conv1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-conv1.C
new file mode 100644 (file)
index 0000000..6569af4
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/69842
+// { dg-do compile { target c++14 } }
+
+template <class T, class U> struct same;
+template <class T> struct same<T,T> {};
+
+int main()
+{
+  auto g = [](auto && _var) {
+    same<int&&,decltype(_var)>();
+  };
+
+  g(0);
+}