On 2/7/19 2:24 AM, Alexandre Oliva wrote:
From: Alexandre Oliva <aol...@redhat.com>
A lambda capture variable initialized with a lambda expr taking more
than one parameter got us confused.
The first problem was that the parameter list was cut short during
tsubsting because we tsubsted it with cp_unevaluated_operand. We
reset it right after, to tsubst the function body, so I've moved the
reset up so that it's in effect while processing the parameters as
well.
The second problem was that the lambda expr appeared twice, once in a
decltype that gave the capture variable its type, and once in its
initializer. This caused us to instantiate two separate lambda exprs
and closure types, and then to flag that the lambda expr in the
initializer could not be converted to the unrelated closure type
determined for the capture variable. Recording the tsubsted expr in
the local specialization map, and retrieving it for reuse fixed it.
Regstrapped on x86_64- and i686-linux-gnu. Ok to install?
for gcc/cp/ChangeLog
PR c++/87322
* pt.c (tsubst_lambda_expr): Avoid duplicate tsubsting.
Move cp_evaluated resetting before signature tsubsting.
for gcc/testsuite/ChangeLog
PR c++/87322
* g++.dg/cpp1y/pr87322.C: New.
---
gcc/cp/pt.c | 18 ++++++++++++++----
gcc/testsuite/g++.dg/cpp1y/pr87322.C | 23 +++++++++++++++++++++++
2 files changed, 37 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp1y/pr87322.C
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b8fbf4046f07..3dffa8d2de88 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -17912,8 +17912,17 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t
complain, tree in_decl)
tree oldfn = lambda_function (t);
in_decl = oldfn;
+ /* If we have already specialized this lambda expr, reuse it. See
+ PR c++/86322. */
Wrong PR number.
+ if (local_specializations)
+ if (tree r = retrieve_local_specialization (t))
+ return r;
Hmm, I would expect this to do the wrong thing for pack expansion of a
lambda, giving us only one rather than one per element of the expansion.
For instance, in lambda-variadic5.C we should get three instantiations
of the "print" function template; can you add that check to the test?
The cp_evaluated change is OK.
Jason