From 7d9fe08e135b8242e61c87b183c31b7fbb33dc28 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 6 Dec 2012 09:37:13 -0500 Subject: [PATCH] re PR c++/55015 (Lambda functions not found at link time when declared in an inline function) 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 | 6 ++++++ gcc/cp/decl.c | 5 ++--- gcc/cp/semantics.c | 4 ++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv6.C | 7 +++++++ 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 04a71f23a41..1a1f459f52f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2012-12-06 Jason Merrill + 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. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index bae48cefdf4..cdda2f42765 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index eaf706968e4..53e849afbef 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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 index 00000000000..bd904372367 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv6.C @@ -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(); } -- 2.30.2