mirror of git://gcc.gnu.org/git/gcc.git
re PR c++/77585 (g++ incorrectly decides that member function is called without object in generic lambda)
PR c++/77585 * pt.c (instantiate_decl): Push to class scope lambda resides within when instantiating a generic lambda function. PR c++/77585 * g++.dg/cpp1y/pr77585.C: New. From-SVN: r243723
This commit is contained in:
parent
a3998c2fb1
commit
2a810dedce
|
|
@ -1,3 +1,9 @@
|
|||
2016-12-15 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
PR c++/77585
|
||||
* pt.c (instantiate_decl): Push to class scope lambda resides
|
||||
within when instantiating a generic lambda function.
|
||||
|
||||
2016-12-14 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/78774
|
||||
|
|
|
|||
21
gcc/cp/pt.c
21
gcc/cp/pt.c
|
|
@ -22484,6 +22484,7 @@ instantiate_decl (tree d, int defer_ok,
|
|||
tree tmpl_parm;
|
||||
tree spec_parm;
|
||||
tree block = NULL_TREE;
|
||||
tree lambda_ctx = NULL_TREE;
|
||||
|
||||
/* Save away the current list, in case we are instantiating one
|
||||
template from within the body of another. */
|
||||
|
|
@ -22497,7 +22498,23 @@ instantiate_decl (tree d, int defer_ok,
|
|||
&& TREE_CODE (DECL_CONTEXT (code_pattern)) == FUNCTION_DECL)
|
||||
block = push_stmt_list ();
|
||||
else
|
||||
start_preparsed_function (d, NULL_TREE, SF_PRE_PARSED);
|
||||
{
|
||||
if (LAMBDA_FUNCTION_P (d))
|
||||
{
|
||||
/* When instantiating a lambda's templated function
|
||||
operator, we need to push the non-lambda class scope
|
||||
of the lambda itself so that the nested function
|
||||
stack is sufficiently correct to deal with this
|
||||
capture. */
|
||||
lambda_ctx = DECL_CONTEXT (d);
|
||||
do
|
||||
lambda_ctx = decl_type_context (TYPE_NAME (lambda_ctx));
|
||||
while (lambda_ctx && LAMBDA_TYPE_P (lambda_ctx));
|
||||
if (lambda_ctx)
|
||||
push_nested_class (lambda_ctx);
|
||||
}
|
||||
start_preparsed_function (d, NULL_TREE, SF_PRE_PARSED);
|
||||
}
|
||||
|
||||
/* Some typedefs referenced from within the template code need to be
|
||||
access checked at template instantiation time, i.e now. These
|
||||
|
|
@ -22565,6 +22582,8 @@ instantiate_decl (tree d, int defer_ok,
|
|||
d = finish_function (0);
|
||||
expand_or_defer_fn (d);
|
||||
}
|
||||
if (lambda_ctx)
|
||||
pop_nested_class ();
|
||||
|
||||
if (DECL_OMP_DECLARE_REDUCTION_P (code_pattern))
|
||||
cp_check_omp_declare_reduction (d);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
2016-12-15 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
PR c++/77585
|
||||
* g++.dg/cpp1y/pr77585.C: New.
|
||||
|
||||
2016-12-15 David Edelsohn <dje.gcc@gmail.com>
|
||||
|
||||
* gcc.dg/tree-ssa/ssa-fre-55.c: Add -Wno-psabi.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
// PR c++/77585
|
||||
// { dg-do run { target c++14 } }
|
||||
|
||||
// Confusion about this capture when instantiating generic lambda's
|
||||
// function operator
|
||||
|
||||
template <typename F> int Eat (F &&f) { return f (1); }
|
||||
|
||||
struct Foo {
|
||||
int x = 1;
|
||||
int Share () { return x++; }
|
||||
int Frob (int);
|
||||
};
|
||||
|
||||
int Foo::Frob (int r)
|
||||
{
|
||||
auto lam = [&](auto) { return Share (); };
|
||||
r += Eat (lam);
|
||||
|
||||
auto lam0 = [&](auto) {
|
||||
auto lam1 = [&](auto) { return Share (); };
|
||||
return Eat (lam1); };
|
||||
r += Eat (lam0);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int Frob (int r)
|
||||
{
|
||||
auto lam = [&](auto) { return 1; };
|
||||
r += Eat (lam);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int main ()
|
||||
{
|
||||
Foo f;
|
||||
|
||||
return Frob (f.Frob (0)) == 4 ? 0 : 1;
|
||||
}
|
||||
Loading…
Reference in New Issue