aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2012-11-29 15:12:58 -0500
committerJason Merrill <jason@gcc.gnu.org>2012-11-29 15:12:58 -0500
commitbc7d0e9006266cf3e0963e7311cf3ba9db56e3d5 (patch)
tree05084cfe0755772b905267bbc58f2fb915f992d8 /gcc
parentb4b5e1f715b8e60cc6bd05742e92fb6c85409b84 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/cp/cp-tree.h5
-rw-r--r--gcc/cp/pt.c13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this6.C32
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);
+}