mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-20 19:01:12 +08:00
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
This commit is contained in:
parent
cf0ed95b57
commit
5ce3039eb1
@ -1,3 +1,11 @@
|
||||
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>
|
||||
|
||||
* call.c (enforce_access): Emit error + inform.
|
||||
|
@ -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
|
||||
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
|
||||
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);
|
||||
|
||||
/* In unevaluated context this isn't an odr-use, so just return the
|
||||
nearest 'this'. */
|
||||
/* In unevaluated context this isn't an odr-use, so don't capture. */
|
||||
if (cp_unevaluated_operand)
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
add_capture_p = false;
|
||||
|
||||
/* Try to default capture 'this' if we can. */
|
||||
if (!this_capture
|
||||
@ -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)
|
||||
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
|
||||
{
|
||||
@ -787,7 +785,7 @@ maybe_resolve_dummy (tree object, bool add_capture_p)
|
||||
/* In a lambda, need to go through 'this' capture. */
|
||||
tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type);
|
||||
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,
|
||||
RO_NULL, tf_warning_or_error);
|
||||
}
|
||||
|
25
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-decltype2.C
Normal file
25
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-decltype2.C
Normal file
@ -0,0 +1,25 @@
|
||||
// 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();}}};
|
Loading…
x
Reference in New Issue
Block a user