From: Jason Merrill Date: Fri, 22 Feb 2019 06:47:37 +0000 (-0500) Subject: PR c++/87685 - generic lambda 'this' capture error. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9adf74a36e569e555cfe41ba0304b0379e72f9c5;p=gcc.git PR c++/87685 - generic lambda 'this' capture error. The standard says that in a generic lambda we should speculatively capture 'this' if we see a call to an overload set that contains a non-static member function, but it seems wrong to reject the program if we can't capture, since it might not actually be needed. * lambda.c (lambda_expr_this_capture): Change add_capture_p to int. (maybe_generic_this_capture): Pass -1. From-SVN: r269095 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a41044683fe..e7780e7eb12 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2019-02-21 Jason Merrill + PR c++/87685 - generic lambda 'this' capture error. + * lambda.c (lambda_expr_this_capture): Change add_capture_p to int. + (maybe_generic_this_capture): Pass -1. + PR c++/88394 - ICE with VLA init-capture. * lambda.c (is_normal_capture_proxy): Check DECL_CAPTURED_VARIABLE. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 879712f6dbc..91bc82b85e5 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7151,7 +7151,7 @@ extern bool is_capture_proxy (tree); extern bool is_normal_capture_proxy (tree); extern bool is_constant_capture_proxy (tree); extern void register_capture_members (tree); -extern tree lambda_expr_this_capture (tree, bool); +extern tree lambda_expr_this_capture (tree, int); extern void maybe_generic_this_capture (tree, tree); extern tree maybe_resolve_dummy (tree, bool); extern tree current_nonlambda_function (void); diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 7032168fb7b..d178f15a4da 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -730,10 +730,11 @@ add_default_capture (tree lambda_stack, tree id, tree initializer) /* Return the capture pertaining to a use of 'this' in LAMBDA, in the form of an INDIRECT_REF, possibly adding it through default - capturing, if ADD_CAPTURE_P is true. */ + capturing, if ADD_CAPTURE_P is nonzero. If ADD_CAPTURE_P is negative, + try to capture but don't complain if we can't. */ tree -lambda_expr_this_capture (tree lambda, bool add_capture_p) +lambda_expr_this_capture (tree lambda, int add_capture_p) { tree result; @@ -829,7 +830,7 @@ lambda_expr_this_capture (tree lambda, bool add_capture_p) result = this_capture; else if (!this_capture) { - if (add_capture_p) + if (add_capture_p == 1) { error ("% was not captured for this lambda function"); result = error_mark_node; @@ -934,7 +935,7 @@ maybe_generic_this_capture (tree object, tree fns) && DECL_NONSTATIC_MEMBER_FUNCTION_P (*iter)) { /* Found a non-static member. Capture this. */ - lambda_expr_this_capture (lam, true); + lambda_expr_this_capture (lam, /*maybe*/-1); break; } } diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this3.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this3.C new file mode 100644 index 00000000000..2bd287cc368 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this3.C @@ -0,0 +1,13 @@ +// PR c++/87685 +// { dg-do compile { target c++14 } } + +struct A +{ + template static void f(T) {} + void f() {} + + void foo() + { + [] (auto&& v) { A::f(v); }; // OK if parameter type is specified + } +};