Patchwork C++ PATCH for c++/53821 (multiply defined lambda member functions)

login
register
mail settings
Submitter Jason Merrill
Date July 2, 2012, 7:09 p.m.
Message ID <4FF1F1D7.50100@redhat.com>
Download mbox | patch
Permalink /patch/168632/
State New
Headers show

Comments

Jason Merrill - July 2, 2012, 7:09 p.m.
It seems that since my change to avoid push_to_top_level for 
instantiating lambdas, the code in maybe_add_lambda_conv_op for handling 
function context activates and does the wrong thing.  I don't remember 
why I added the code that sets DECL_INTERFACE_KNOWN, but it doesn't seem 
to be needed.

This patch restores the old behavior for the testcase.  While looking at 
it I notice that the op() itself is incorrectly emitted as a local 
function rather than COMDAT, but that will wait for another patch.

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

Patch

commit 45299163c2e02cde76e8b5bb8c2ecf11bda0b616
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Jul 2 13:53:05 2012 -0400

    	PR c++/53821
    	* semantics.c (maybe_add_lambda_conv_op): Don't set
    	DECL_INTERFACE_KNOWN.

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index f1a94c1..8e37ebb 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -9336,8 +9336,6 @@  maybe_add_lambda_conv_op (tree type)
   DECL_NOT_REALLY_EXTERN (fn) = 1;
   DECL_DECLARED_INLINE_P (fn) = 1;
   DECL_ARGUMENTS (fn) = build_this_parm (fntype, TYPE_QUAL_CONST);
-  if (nested)
-    DECL_INTERFACE_KNOWN (fn) = 1;
 
   add_method (type, fn, NULL_TREE);
 
@@ -9368,8 +9366,6 @@  maybe_add_lambda_conv_op (tree type)
   DECL_ARGUMENTS (fn) = copy_list (DECL_CHAIN (DECL_ARGUMENTS (callop)));
   for (arg = DECL_ARGUMENTS (fn); arg; arg = DECL_CHAIN (arg))
     DECL_CONTEXT (arg) = fn;
-  if (nested)
-    DECL_INTERFACE_KNOWN (fn) = 1;
 
   add_method (type, fn, NULL_TREE);
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template6.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template6.C
new file mode 100644
index 0000000..5e85619
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template6.C
@@ -0,0 +1,14 @@ 
+// PR c++/53821
+// { dg-final { scan-assembler-not "_ZZ1fIvEvvENKUlvE_cvPFvvEEv" } }
+// { dg-do compile { target c++11 } }
+
+template <class T> void f()
+{
+  auto g = []{};
+  g();
+}
+
+int main()
+{
+  f<void>();
+}