Commit 4b16f9c8 by Jason Merrill Committed by Jason Merrill

re PR c++/56464 ([C++11] Crashes when using implicit this in a lambda capture in…

re PR c++/56464 ([C++11] Crashes when using implicit this in a lambda capture in member initializer)

	PR c++/56464
	PR c++/54383
	* semantics.c (lambda_expr_this_capture): Handle NSDMI
	and non-class scopes.

From-SVN: r196437
parent 0388c913
2013-03-04 Jason Merrill <jason@redhat.com>
PR c++/56464
PR c++/54383
* semantics.c (lambda_expr_this_capture): Handle NSDMI
and non-class scopes.
2013-03-01 Paolo Carlini <paolo.carlini@oracle.com> 2013-03-01 Paolo Carlini <paolo.carlini@oracle.com>
* decl.c (grokdeclarator): Remove dead code. * decl.c (grokdeclarator): Remove dead code.
......
...@@ -9442,41 +9442,62 @@ lambda_expr_this_capture (tree lambda) ...@@ -9442,41 +9442,62 @@ lambda_expr_this_capture (tree lambda)
if (!this_capture if (!this_capture
&& LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE) && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE)
{ {
tree containing_function = TYPE_CONTEXT (LAMBDA_EXPR_CLOSURE (lambda)); tree lambda_stack = NULL_TREE;
tree lambda_stack = tree_cons (NULL_TREE, lambda, NULL_TREE);
tree init = NULL_TREE; tree init = NULL_TREE;
/* If we are in a lambda function, we can move out until we hit: /* If we are in a lambda function, we can move out until we hit:
1. a non-lambda function, 1. a non-lambda function or NSDMI,
2. a lambda function capturing 'this', or 2. a lambda function capturing 'this', or
3. a non-default capturing lambda function. */ 3. a non-default capturing lambda function. */
while (LAMBDA_FUNCTION_P (containing_function)) for (tree tlambda = lambda; ;)
{ {
tree lambda lambda_stack = tree_cons (NULL_TREE,
= CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (containing_function)); tlambda,
lambda_stack);
if (LAMBDA_EXPR_THIS_CAPTURE (lambda)) if (LAMBDA_EXPR_EXTRA_SCOPE (tlambda)
&& TREE_CODE (LAMBDA_EXPR_EXTRA_SCOPE (tlambda)) == FIELD_DECL)
{ {
/* An outer lambda has already captured 'this'. */ /* In an NSDMI, we don't have a function to look up the decl in,
init = LAMBDA_EXPR_THIS_CAPTURE (lambda); but the fake 'this' pointer that we're using for parsing is
in scope_chain. */
init = scope_chain->x_current_class_ptr;
gcc_checking_assert
(init && (TREE_TYPE (TREE_TYPE (init))
== current_nonlambda_class_type ()));
break; break;
} }
if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) == CPLD_NONE) tree closure_decl = TYPE_NAME (LAMBDA_EXPR_CLOSURE (tlambda));
/* An outer lambda won't let us capture 'this'. */ tree containing_function = decl_function_context (closure_decl);
if (containing_function == NULL_TREE)
/* We ran out of scopes; there's no 'this' to capture. */
break; break;
lambda_stack = tree_cons (NULL_TREE, if (!LAMBDA_FUNCTION_P (containing_function))
lambda, {
lambda_stack); /* We found a non-lambda function. */
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (containing_function))
/* First parameter is 'this'. */
init = DECL_ARGUMENTS (containing_function);
break;
}
containing_function = decl_function_context (containing_function); tlambda
} = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (containing_function));
if (!init && DECL_NONSTATIC_MEMBER_FUNCTION_P (containing_function) if (LAMBDA_EXPR_THIS_CAPTURE (tlambda))
&& !LAMBDA_FUNCTION_P (containing_function)) {
/* First parameter is 'this'. */ /* An outer lambda has already captured 'this'. */
init = DECL_ARGUMENTS (containing_function); init = LAMBDA_EXPR_THIS_CAPTURE (tlambda);
break;
}
if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (tlambda) == CPLD_NONE)
/* An outer lambda won't let us capture 'this'. */
break;
}
if (init) if (init)
this_capture = add_default_capture (lambda_stack, this_capture = add_default_capture (lambda_stack,
......
// PR c++/56464
// { dg-do run { target c++11 } }
struct bug { bug*a = [&]{ return [=]{return this;}(); }(); };
int main()
{
bug b;
if (b.a != &b)
__builtin_abort ();
}
// PR c++/54383
// { dg-do compile { target c++11 } }
auto foo = [&](int a) { return a > this->b; }; // { dg-error "this" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment