In this testcase, instantiating the return type doesn't work before
we've instantiated the declaration of the operator(). Furthermore,
instantiating the operator() declaration necessarily instantiates the
return type, so we can wait and look it up from there.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 178af5b2e30a6efb8e49638c37dfea7320586c62
Author: Jason Merrill <ja...@redhat.com>
Date: Wed Mar 2 14:53:31 2016 -0500
* pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Get
LAMBDA_EXPR_RETURN_TYPE from the instantiated closure.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c5b9201..e8cd736 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -17103,8 +17103,6 @@ tsubst_copy_and_build (tree t,
else
gcc_unreachable ();
LAMBDA_EXPR_EXTRA_SCOPE (r) = scope;
- LAMBDA_EXPR_RETURN_TYPE (r)
- = tsubst (LAMBDA_EXPR_RETURN_TYPE (t), args, complain, in_decl);
gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (t) == NULL_TREE
&& LAMBDA_EXPR_PENDING_PROXIES (t) == NULL);
@@ -17115,6 +17113,9 @@ tsubst_copy_and_build (tree t,
declaration of the op() for later calls to lambda_function. */
complete_type (type);
+ if (tree fn = lambda_function (type))
+ LAMBDA_EXPR_RETURN_TYPE (r) = TREE_TYPE (TREE_TYPE (fn));
+
LAMBDA_EXPR_THIS_CAPTURE (r) = NULL_TREE;
insert_pending_capture_proxies ();
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-trailing1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-trailing1.C
new file mode 100644
index 0000000..96755b1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-trailing1.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++14 } }
+
+template <class T>
+void f()
+{
+ auto lam = [](auto a)->decltype(++a) { return a; };
+}
+
+int main()
+{
+ f<int>();
+}