diff mbox

Fix PR c++/60033

Message ID 1393963121-22097-1-git-send-email-adam@jessamine.co.uk
State New
Headers show

Commit Message

Adam Butcher March 4, 2014, 7:58 p.m. UTC
PR c++/60033
	* pt.c (retrieve_specialization): When retrieving a capture pack from a
	generic lambda, remove the lambda's own template argument list prior to
	fetching the specialization.

	PR c++/60033
	* g++.dg/cpp1y/pr60033.C: New testcase.
---
 gcc/cp/pt.c                          | 11 +++++++++++
 gcc/testsuite/g++.dg/cpp1y/pr60033.C | 20 ++++++++++++++++++++
 2 files changed, 31 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/pr60033.C

Comments

Jason Merrill March 7, 2014, 8:26 p.m. UTC | #1
On 03/04/2014 02:58 PM, Adam Butcher wrote:
> 	PR c++/60033
> 	* pt.c (retrieve_specialization): When retrieving a capture pack from a
> 	generic lambda, remove the lambda's own template argument list prior to
> 	fetching the specialization.

I think I'd prefer to handle this at the call site in tsubst_copy.

Jason
diff mbox

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8126905..0d0b1dc 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1031,6 +1031,17 @@  retrieve_specialization (tree tmpl, tree args, hashval_t hash)
   gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL
 	      || TREE_CODE (tmpl) == FIELD_DECL);
 
+  /* When retrieving a capture pack from a generic lambda, remove the lambda
+     call op's own template argument list from ARGS.  Only the template
+     arguments active for the closure type should be used to retrieve the pack
+     specialization.
+     XXX: It may be that this situation can be avoided by manipulating the field
+     XXX: type earlier.  */
+  if (TREE_CODE (tmpl) == FIELD_DECL
+      && LAMBDA_FUNCTION_P (current_function_decl)
+      && template_class_depth (DECL_CONTEXT (tmpl)) != TMPL_ARGS_DEPTH (args))
+    args = strip_innermost_template_args (args, 1);
+
   /* There should be as many levels of arguments as there are
      levels of parameters.  */
   gcc_assert (TMPL_ARGS_DEPTH (args)
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60033.C b/gcc/testsuite/g++.dg/cpp1y/pr60033.C
new file mode 100644
index 0000000..8194bec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr60033.C
@@ -0,0 +1,20 @@ 
+// PR c++/60033
+// { dg-options -std=c++1y }
+
+template <typename... T>
+auto f(T&&... ts)
+{
+   return sizeof...(ts);
+}
+
+template <typename... T>
+auto g(T&&... ts) {
+  return [&] (auto v) {
+    return f(ts...);
+  };
+}
+
+int main()
+{
+   return g(1,2,3,4)(5) == 4 ? 0 : 1;
+}