diff options
author | Jason Merrill <jason@redhat.com> | 2015-04-15 17:17:03 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-04-15 17:17:03 -0400 |
commit | 5ce3039eb1e5771e01ee9513f0b7508a95f544ed (patch) | |
tree | ae9db838d14d43c0821e59dda18494dafae364c5 /gcc | |
parent | cf0ed95b57a87bd943bb093a52d19cc00bdede31 (diff) | |
download | gcc-5ce3039eb1e5771e01ee9513f0b7508a95f544ed.zip gcc-5ce3039eb1e5771e01ee9513f0b7508a95f544ed.tar.gz gcc-5ce3039eb1e5771e01ee9513f0b7508a95f544ed.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/lambda.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-decltype2.C | 25 |
3 files changed, 46 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0302516..3534fdb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index dd1c2d4..174700f 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -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); } diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-decltype2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-decltype2.C new file mode 100644 index 0000000..51bf0ec --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-decltype2.C @@ -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();}}}; |