summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-20 07:21:55 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-20 07:21:55 +0000
commitd119c9240b447d47da4e9e4ef44528cf4017d068 (patch)
tree48ac6841cf0e7f79f7f70ae3e23938490fe096e3
parent756cee388ffcdd4ecab29b1d10475e7438159312 (diff)
downloadgcc-d119c9240b447d47da4e9e4ef44528cf4017d068.tar.gz
Reapply:
PR c++/53137 * pt.c (instantiate_class_template_1): Set LAMBDA_EXPR_THIS_CAPTURE. (instantiate_decl): Don't push_to_top_level for local class methods. (instantiate_class_template_1): Or for local classes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@188810 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c28
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template5.C17
4 files changed, 49 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4ac2cb71f4d..fedbdee2c73 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2012-06-19 Jason Merrill <jason@redhat.com>
+ Reapply:
+ PR c++/53137
+ * pt.c (instantiate_class_template_1): Set LAMBDA_EXPR_THIS_CAPTURE.
+ (instantiate_decl): Don't push_to_top_level for local class methods.
+ (instantiate_class_template_1): Or for local classes.
+
PR c++/53599
* pt.c (lookup_template_class_1): Use ts_global.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 565cd9a0fdb..7f5682da32a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8734,6 +8734,7 @@ instantiate_class_template_1 (tree type)
tree pbinfo;
tree base_list;
unsigned int saved_maximum_field_alignment;
+ tree fn_context;
if (type == error_mark_node)
return error_mark_node;
@@ -8792,7 +8793,9 @@ instantiate_class_template_1 (tree type)
it now. */
push_deferring_access_checks (dk_no_deferred);
- push_to_top_level ();
+ fn_context = decl_function_context (TYPE_MAIN_DECL (type));
+ if (!fn_context)
+ push_to_top_level ();
/* Use #pragma pack from the template context. */
saved_maximum_field_alignment = maximum_field_alignment;
maximum_field_alignment = TYPE_PRECISION (pattern);
@@ -9191,8 +9194,14 @@ instantiate_class_template_1 (tree type)
apply_lambda_return_type (lambda, void_type_node);
LAMBDA_EXPR_RETURN_TYPE (lambda) = NULL_TREE;
}
+
+ LAMBDA_EXPR_THIS_CAPTURE (lambda)
+ = lookup_field_1 (type, get_identifier ("__this"), false);
+
instantiate_decl (decl, false, false);
maybe_add_lambda_conv_op (type);
+
+ LAMBDA_EXPR_THIS_CAPTURE (lambda) = NULL_TREE;
}
else
gcc_assert (errorcount);
@@ -9223,7 +9232,8 @@ instantiate_class_template_1 (tree type)
perform_deferred_access_checks ();
pop_nested_class ();
maximum_field_alignment = saved_maximum_field_alignment;
- pop_from_top_level ();
+ if (!fn_context)
+ pop_from_top_level ();
pop_deferring_access_checks ();
pop_tinst_level ();
@@ -18456,9 +18466,10 @@ instantiate_decl (tree d, int defer_ok,
tree spec;
tree gen_tmpl;
bool pattern_defined;
- int need_push;
location_t saved_loc = input_location;
bool external_p;
+ tree fn_context;
+ bool nested;
/* This function should only be used to instantiate templates for
functions and static member variables. */
@@ -18693,9 +18704,12 @@ instantiate_decl (tree d, int defer_ok,
goto out;
}
- need_push = !cfun || !global_bindings_p ();
- if (need_push)
+ fn_context = decl_function_context (d);
+ nested = (current_function_decl != NULL_TREE);
+ if (!fn_context)
push_to_top_level ();
+ else if (nested)
+ push_function_context ();
/* Mark D as instantiated so that recursive calls to
instantiate_decl do not try to instantiate it again. */
@@ -18808,8 +18822,10 @@ instantiate_decl (tree d, int defer_ok,
/* We're not deferring instantiation any more. */
TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0;
- if (need_push)
+ if (!fn_context)
pop_from_top_level ();
+ else if (nested)
+ pop_function_context ();
out:
input_location = saved_loc;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9a8d5dccb52..98d55ee9a8a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2012-06-19 Jason Merrill <jason@redhat.com>
+ Reapply:
+ PR c++/53137
+ * g++.dg/cpp0x/lambda/lambda-template5.C: New.
+
PR c++/53599
* g++.dg/template/local7.C: New.
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template5.C
new file mode 100644
index 00000000000..b91b89ff36c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template5.C
@@ -0,0 +1,17 @@
+// PR c++/53137
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+ template <typename T> void f();
+
+ template <typename T> void g()
+ {
+ [this]{ f<T>(); }();
+ }
+
+ void h()
+ {
+ g<int>();
+ }
+};