Patchwork C++ PATCH for c++/54538 (lambda mangling)

login
register
mail settings
Submitter Jason Merrill
Date Sept. 10, 2012, 11:44 p.m.
Message ID <504E7B75.301@redhat.com>
Download mbox | patch
Permalink /patch/182975/
State New
Headers show

Comments

Jason Merrill - Sept. 10, 2012, 11:44 p.m.
This bug was introduced by the fix for 53783; the change from 
tsubst_copy to tsubst messed up handling of FIELD_DECLs, because tsubst 
of a FIELD_DECL always creates a new one.  Fixed by limiting the 53783 
change to FUNCTION_DECLs.

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

Patch

commit d61bd5ca5d9e57ed3bb2b82cacbcbc110f874349
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Sep 10 15:26:44 2012 -0400

    	PR c++/54538
    	PR c++/53783
    	* pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Go back to using RECUR
    	for LAMBDA_EXPR_EXTRA_SCOPE except for function scope.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index cde83f2..a875528 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -14199,8 +14199,18 @@  tsubst_copy_and_build (tree t,
 	LAMBDA_EXPR_MUTABLE_P (r) = LAMBDA_EXPR_MUTABLE_P (t);
 	LAMBDA_EXPR_DISCRIMINATOR (r)
 	  = (LAMBDA_EXPR_DISCRIMINATOR (t));
-	LAMBDA_EXPR_EXTRA_SCOPE (r)
-	  = tsubst (LAMBDA_EXPR_EXTRA_SCOPE (t), args, complain, in_decl);
+	/* For a function scope, we want to use tsubst so that we don't
+	   complain about referring to an auto function before its return
+	   type has been deduced.  Otherwise, we want to use tsubst_copy so
+	   that we look up the existing field/parameter/variable rather
+	   than build a new one.  */
+	tree scope = LAMBDA_EXPR_EXTRA_SCOPE (t);
+	if (scope && TREE_CODE (scope) == FUNCTION_DECL)
+	  scope = tsubst (LAMBDA_EXPR_EXTRA_SCOPE (t), args,
+			  complain, in_decl);
+	else
+	  scope = RECUR (scope);
+	LAMBDA_EXPR_EXTRA_SCOPE (r) = scope;
 	LAMBDA_EXPR_RETURN_TYPE (r)
 	  = tsubst (LAMBDA_EXPR_RETURN_TYPE (t), args, complain, in_decl);
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle4.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle4.C
new file mode 100644
index 0000000..0d37637
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle4.C
@@ -0,0 +1,13 @@ 
+// PR c++/54538
+// { dg-do compile { target c++11 } }
+
+template <class T>
+struct A
+{
+  // { dg-final { scan-assembler "_ZNK1AIcE1pMUlvE_cvPFvvEEv" } }
+  // { dg-final { scan-assembler "_ZNK1AIiE1pMUlvE_cvPFvvEEv" } }
+  void (*p)() = []{};
+};
+
+A<int> a1;
+A<char> a2;