diff mbox

C++ PATCH for c++/58761 (lambda 'this' capture in NSDMI)

Message ID 537A502E.5030308@redhat.com
State New
Headers show

Commit Message

Jason Merrill May 19, 2014, 6:40 p.m. UTC
The problem in this testcase was that when we go to instantiate the 
lambda in the NSDMI, since it wasn't defined in a function we 
push_to_top_level and thereby clobber the current_class_ptr we set up.

Tested x86_64-pc-linux-gnu, applying to trunk.
diff mbox

Patch

commit e9fdfb3ea5ea6672a2dd72d3ed717686fe060cef
Author: Jason Merrill <jason@redhat.com>
Date:   Thu May 15 15:02:39 2014 -0400

    	PR c++/58761
    	* pt.c (tsubst_copy): Don't check at_function_scope_p.
    	(instantiate_class_template_1): Don't push_to_top_level in an nsdmi.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c9eddb8..d712583 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8942,6 +8942,9 @@  instantiate_class_template_1 (tree type)
   push_deferring_access_checks (dk_no_deferred);
 
   fn_context = decl_function_context (TYPE_MAIN_DECL (type));
+  /* Also avoid push_to_top_level for a lambda in an NSDMI.  */
+  if (!fn_context && LAMBDA_TYPE_P (type) && TYPE_CLASS_SCOPE_P (type))
+    fn_context = error_mark_node;
   if (!fn_context)
     push_to_top_level ();
   /* Use #pragma pack from the template context.  */
@@ -12531,7 +12534,7 @@  tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	{
 	  /* We get here for a use of 'this' in an NSDMI.  */
 	  if (DECL_NAME (t) == this_identifier
-	      && at_function_scope_p ()
+	      && current_function_decl
 	      && DECL_CONSTRUCTOR_P (current_function_decl))
 	    return current_class_ptr;
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi6.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi6.C
new file mode 100644
index 0000000..98cdbce
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi6.C
@@ -0,0 +1,23 @@ 
+// PR c++/58761
+// { dg-do compile { target c++11 } }
+
+template <class T>
+struct X
+{
+  int x = 42;
+  int y = [this](){return this->x;}();
+};
+
+template <class T>
+struct Y
+{
+  int x = 42;
+  int y = [this](){return this->x;}();
+  Y(int) {}
+};
+
+int main()
+{
+  X<int> x;
+  Y<int> y(42);
+}