Patchwork Fix PR c++/60033

login
register
mail settings
Submitter Adam Butcher
Date March 7, 2014, 11:07 p.m.
Message ID <1394233645-23716-1-git-send-email-adam@jessamine.co.uk>
Download mbox | patch
Permalink /patch/328116/
State New
Headers show

Comments

Adam Butcher - March 7, 2014, 11:07 p.m.
PR c++/60033
	* pt.c (tsubst_copy): 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                          | 10 ++++++++++
 gcc/testsuite/g++.dg/cpp1y/pr60033.C | 20 ++++++++++++++++++++
 2 files changed, 30 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/pr60033.C
Jason Merrill - March 8, 2014, 4 a.m.
On 03/07/2014 06:07 PM, Adam Butcher wrote:
> +	  /* 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.  */
> +	  if (TREE_CODE (t) == FIELD_DECL
> +	      && LAMBDA_FUNCTION_P (current_function_decl)
> +	      && (template_class_depth (DECL_CONTEXT (t))
> +		  != TMPL_ARGS_DEPTH (args)))
> +	    args = strip_innermost_template_args (args, 1);

You don't need to check for FIELD_DECL here; at this point we know t is 
a FIELD_DECL.  OK with that change.

Jason

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8126905..9d7063b 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -12572,6 +12572,16 @@  tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	      return r;
 	    }
 
+	  /* 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.  */
+	  if (TREE_CODE (t) == FIELD_DECL
+	      && LAMBDA_FUNCTION_P (current_function_decl)
+	      && (template_class_depth (DECL_CONTEXT (t))
+		  != TMPL_ARGS_DEPTH (args)))
+	    args = strip_innermost_template_args (args, 1);
+
 	  /* Otherwise return the full NONTYPE_ARGUMENT_PACK that
 	     tsubst_decl put in the hash table.  */
 	  return retrieve_specialization (t, args, 0);
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;
+}