]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/55015 (Lambda functions not found at link time when declared in an inline...
authorJason Merrill <jason@redhat.com>
Thu, 6 Dec 2012 14:37:13 +0000 (09:37 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 6 Dec 2012 14:37:13 +0000 (09:37 -0500)
PR c++/55015
PR c++/53821
* semantics.c (maybe_add_lambda_conv_op): Revert earlier change.
* decl.c (start_preparsed_function): Make local class methods comdat
in templates, too.

From-SVN: r194251

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/semantics.c
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv6.C [new file with mode: 0644]

index 04a71f23a411790598dfa8ea394369d9e6edcccc..1a1f459f52f8bc783aadaa32b7a36725e6fc7f6e 100644 (file)
@@ -1,5 +1,11 @@
 2012-12-06  Jason Merrill  <jason@redhat.com>
 
+       PR c++/55015
+       PR c++/53821
+       * semantics.c (maybe_add_lambda_conv_op): Revert earlier change.
+       * decl.c (start_preparsed_function): Make local class methods comdat
+       in templates, too.
+
        PR c++/54653
        * parser.c (cp_parser_class_head): A partial specialization scope
        counts as a template.
index bae48cefdf483bb8e98690de1a9aaddfc9e2f6f1..cdda2f427654cf014e47a30a3d684c82a1975b41 100644 (file)
@@ -13199,10 +13199,9 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       if (DECL_NOT_REALLY_EXTERN (decl1))
        DECL_EXTERNAL (decl1) = 0;
 
-      if (ctx != NULL_TREE && DECL_DECLARED_INLINE_P (ctx)
-         && TREE_PUBLIC (ctx))
+      if (ctx != NULL_TREE && vague_linkage_p (ctx))
        /* This is a function in a local class in an extern inline
-          function.  */
+          or template function.  */
        comdat_linkage (decl1);
     }
   /* If this function belongs to an interface, it is public.
index eaf706968e4b2ff005207c4c92b90aa2356ba593..53e849afbef1ed27af1184579ee53255efa8aadd 100644 (file)
@@ -9419,6 +9419,8 @@ 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);
 
@@ -9449,6 +9451,8 @@ 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-conv6.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv6.C
new file mode 100644 (file)
index 0000000..bd90437
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/55015
+// { dg-do link }
+// { dg-options -std=c++11 }
+
+typedef void (*VoidFunc)();
+inline VoidFunc GetFunc() { return [](){}; }
+int main() { VoidFunc func = GetFunc(); }