Commit 5ce3039e by Jason Merrill Committed by Jason Merrill

re PR c++/65727 (Segfault With Decltype In Lambda Expression Used To Initialize…

re PR c++/65727 (Segfault With Decltype In Lambda Expression Used To Initialize Static Class Member)

	PR c++/65727
	* lambda.c (lambda_expr_this_capture): In unevaluated context go
	through the normal loop, just don't capture.
	(maybe_resolve_dummy): Handle null return.

Co-Authored-By: Marek Polacek <polacek@redhat.com>

From-SVN: r222132
parent cf0ed95b
2015-04-15 Jason Merrill <jason@redhat.com>
Marek Polacek <polacek@redhat.com>
PR c++/65727
* lambda.c (lambda_expr_this_capture): In unevaluated context go
through the normal loop, just don't capture.
(maybe_resolve_dummy): Handle null return.
2015-04-15 Paolo Carlini <paolo.carlini@oracle.com> 2015-04-15 Paolo Carlini <paolo.carlini@oracle.com>
* call.c (enforce_access): Emit error + inform. * call.c (enforce_access): Emit error + inform.
......
...@@ -646,7 +646,7 @@ add_default_capture (tree lambda_stack, tree id, tree initializer) ...@@ -646,7 +646,7 @@ add_default_capture (tree lambda_stack, tree id, tree initializer)
/* Return the capture pertaining to a use of 'this' in LAMBDA, in the /* Return the capture pertaining to a use of 'this' in LAMBDA, in the
form of an INDIRECT_REF, possibly adding it through default form of an INDIRECT_REF, possibly adding it through default
capturing, if ADD_CAPTURE_P is false. */ capturing, if ADD_CAPTURE_P is true. */
tree tree
lambda_expr_this_capture (tree lambda, bool add_capture_p) lambda_expr_this_capture (tree lambda, bool add_capture_p)
...@@ -655,17 +655,9 @@ lambda_expr_this_capture (tree lambda, bool add_capture_p) ...@@ -655,17 +655,9 @@ lambda_expr_this_capture (tree lambda, bool add_capture_p)
tree this_capture = LAMBDA_EXPR_THIS_CAPTURE (lambda); tree this_capture = LAMBDA_EXPR_THIS_CAPTURE (lambda);
/* In unevaluated context this isn't an odr-use, so just return the /* In unevaluated context this isn't an odr-use, so don't capture. */
nearest 'this'. */
if (cp_unevaluated_operand) if (cp_unevaluated_operand)
{ add_capture_p = false;
/* In an NSDMI the fake 'this' pointer that we're using for
parsing is in scope_chain. */
if (LAMBDA_EXPR_EXTRA_SCOPE (lambda)
&& TREE_CODE (LAMBDA_EXPR_EXTRA_SCOPE (lambda)) == FIELD_DECL)
return scope_chain->x_current_class_ptr;
return lookup_name (this_identifier);
}
/* Try to default capture 'this' if we can. */ /* Try to default capture 'this' if we can. */
if (!this_capture if (!this_capture
...@@ -740,11 +732,17 @@ lambda_expr_this_capture (tree lambda, bool add_capture_p) ...@@ -740,11 +732,17 @@ lambda_expr_this_capture (tree lambda, bool add_capture_p)
} }
} }
if (!this_capture) if (cp_unevaluated_operand)
result = this_capture;
else if (!this_capture)
{ {
if (add_capture_p) if (add_capture_p)
error ("%<this%> was not captured for this lambda function"); {
result = error_mark_node; error ("%<this%> was not captured for this lambda function");
result = error_mark_node;
}
else
result = NULL_TREE;
} }
else else
{ {
...@@ -787,7 +785,7 @@ maybe_resolve_dummy (tree object, bool add_capture_p) ...@@ -787,7 +785,7 @@ maybe_resolve_dummy (tree object, bool add_capture_p)
/* In a lambda, need to go through 'this' capture. */ /* In a lambda, need to go through 'this' capture. */
tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type); tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type);
tree cap = lambda_expr_this_capture (lam, add_capture_p); tree cap = lambda_expr_this_capture (lam, add_capture_p);
if (cap != error_mark_node) if (cap && cap != error_mark_node)
object = build_x_indirect_ref (EXPR_LOCATION (object), cap, object = build_x_indirect_ref (EXPR_LOCATION (object), cap,
RO_NULL, tf_warning_or_error); RO_NULL, tf_warning_or_error);
} }
......
// PR c++/65727
// { dg-do compile { target c++11 } }
struct type_a { void(*cb)(); };
struct type_b
{
type_b(type_a p);
void dummy();
};
template<class T>
constexpr T function_c(T**t) {return **t;}
class type_d {
public:
static void dummy();
};
class type_e {
public:
static type_b b;
type_d *d[1];
};
type_b type_e::b = {{[](){decltype(function_c(type_e::d))::dummy();}}};
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