diff options
author | Jason Merrill <jason@redhat.com> | 2012-11-29 15:12:58 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2012-11-29 15:12:58 -0500 |
commit | bc7d0e9006266cf3e0963e7311cf3ba9db56e3d5 (patch) | |
tree | 05084cfe0755772b905267bbc58f2fb915f992d8 /gcc | |
parent | b4b5e1f715b8e60cc6bd05742e92fb6c85409b84 (diff) | |
download | gcc-bc7d0e9006266cf3e0963e7311cf3ba9db56e3d5.zip gcc-bc7d0e9006266cf3e0963e7311cf3ba9db56e3d5.tar.gz gcc-bc7d0e9006266cf3e0963e7311cf3ba9db56e3d5.tar.bz2 |
re PR c++/53137 (g++ segfault)
PR c++/53137
* pt.c (tsubst_expr) [DECL_EXPR]: Set LAMBDA_EXPR_THIS_CAPTURE here.
(tsubst_copy_and_build) [LAMBDA_EXPR]: And clear it here.
(instantiate_class_template_1): Not here.
From-SVN: r193954
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 5 | ||||
-rw-r--r-- | gcc/cp/pt.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this6.C | 32 |
4 files changed, 49 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d8d958a..60211d8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2012-11-29 Jason Merrill <jason@redhat.com> + + PR c++/53137 + * pt.c (tsubst_expr) [DECL_EXPR]: Set LAMBDA_EXPR_THIS_CAPTURE here. + (tsubst_copy_and_build) [LAMBDA_EXPR]: And clear it here. + (instantiate_class_template_1): Not here. + 2012-11-29 Marc Glisse <marc.glisse@inria.fr> PR c++/53094 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 85c8e7c..ceac093 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -659,8 +659,9 @@ enum cp_lambda_default_capture_mode_type { #define LAMBDA_EXPR_CAPTURE_LIST(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->capture_list) -/* During parsing of the lambda, the node in the capture-list that holds - the 'this' capture. */ +/* During parsing of the lambda-introducer, the node in the capture-list + that holds the 'this' capture. During parsing of the body, the + capture proxy for that node. */ #define LAMBDA_EXPR_THIS_CAPTURE(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->this_capture) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ecb013e..3bc0d64 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8956,14 +8956,8 @@ instantiate_class_template_1 (tree type) tree decl = lambda_function (type); if (decl) { - tree lam = CLASSTYPE_LAMBDA_EXPR (type); - LAMBDA_EXPR_THIS_CAPTURE (lam) - = lookup_field_1 (type, get_identifier ("__this"), false); - instantiate_decl (decl, false, false); maybe_add_lambda_conv_op (type); - - LAMBDA_EXPR_THIS_CAPTURE (lam) = NULL_TREE; } else gcc_assert (errorcount); @@ -12728,6 +12722,12 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, else if (is_capture_proxy (DECL_EXPR_DECL (t))) { DECL_CONTEXT (decl) = current_function_decl; + if (DECL_NAME (decl) == this_identifier) + { + tree lam = DECL_CONTEXT (current_function_decl); + lam = CLASSTYPE_LAMBDA_EXPR (lam); + LAMBDA_EXPR_THIS_CAPTURE (lam) = decl; + } insert_capture_proxy (decl); } else if (DECL_IMPLICIT_TYPEDEF_P (t)) @@ -14313,6 +14313,7 @@ tsubst_copy_and_build (tree t, wait until after we finish instantiating the type. */ LAMBDA_EXPR_CAPTURE_LIST (r) = RECUR (LAMBDA_EXPR_CAPTURE_LIST (t)); + LAMBDA_EXPR_THIS_CAPTURE (r) = NULL_TREE; RETURN (build_lambda_object (r)); } diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this6.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this6.C new file mode 100644 index 0000000..acf4eaa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this6.C @@ -0,0 +1,32 @@ +// PR c++/53137 +// { dg-options -std=c++11 } + +template <typename STORE> +void getParent(STORE& tStore) +{ +} + +struct Store +{ + template <typename CheckParentFunc> + void updateChildCommon(CheckParentFunc c) + { + c(); + } + + template <typename T> + int& getStore(); + + template <typename T> + void updateChild(const T& obj) + { + updateChildCommon([this] () { getParent(getStore<T>()); }); + } + + void update(int obj); +}; + +void Store::update(int obj) +{ + updateChild(obj); +} |