From 3c3f480eb1c70f05275cdf3cb45f7bce9780ad8d Mon Sep 17 00:00:00 2001 From: jason Date: Thu, 29 Nov 2012 20:12:58 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193954 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 7 ++++++ gcc/cp/cp-tree.h | 5 ++-- gcc/cp/pt.c | 13 +++++----- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this6.C | 32 ++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d8d958a579c..60211d8add0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2012-11-29 Jason Merrill + + 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 PR c++/53094 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 85c8e7c702c..ceac093385d 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 ecb013ecaee..3bc0d64d6ba 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 00000000000..acf4eaa7fcb --- /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 +void getParent(STORE& tStore) +{ +} + +struct Store +{ + template + void updateChildCommon(CheckParentFunc c) + { + c(); + } + + template + int& getStore(); + + template + void updateChild(const T& obj) + { + updateChildCommon([this] () { getParent(getStore()); }); + } + + void update(int obj); +}; + +void Store::update(int obj) +{ + updateChild(obj); +} -- 2.11.4.GIT