diff options
author | Jason Merrill <jason@redhat.com> | 2012-12-06 09:37:13 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2012-12-06 09:37:13 -0500 |
commit | 7d9fe08e135b8242e61c87b183c31b7fbb33dc28 (patch) | |
tree | b486c957cc35b0ab2a736727700908949d41fd62 /gcc | |
parent | 5442fe4818ecb877fccbba726ded41f1de3583c6 (diff) | |
download | gcc-7d9fe08e135b8242e61c87b183c31b7fbb33dc28.zip gcc-7d9fe08e135b8242e61c87b183c31b7fbb33dc28.tar.gz gcc-7d9fe08e135b8242e61c87b183c31b7fbb33dc28.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/decl.c | 5 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv6.C | 7 |
4 files changed, 19 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 04a71f2..1a1f459 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index bae48ce..cdda2f4 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 eaf7069..53e849a 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 0000000..bd90437 --- /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(); } |