diff options
author | Jason Merrill <jason@redhat.com> | 2013-02-14 20:26:44 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2013-02-14 20:26:44 -0500 |
commit | 622aac0b88ed111d033a950b0737317d8c85bbcb (patch) | |
tree | 76ab66221ec193a48645ec9dfa45c26964b7f963 /gcc | |
parent | ff9b4073cc6f8da73fd9affa494192e91c852e64 (diff) | |
download | gcc-622aac0b88ed111d033a950b0737317d8c85bbcb.zip gcc-622aac0b88ed111d033a950b0737317d8c85bbcb.tar.gz gcc-622aac0b88ed111d033a950b0737317d8c85bbcb.tar.bz2 |
re PR c++/55223 ([C++11] Default lambda expression of a templated class member)
PR c++/55223
gcc/cp/
* pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Fix handling of
default argument scope.
* mangle.c (write_name): Likewise.
libiberty/
* cp-demangle.c (d_dump): Handle DEMANGLE_COMPONENT_DEFAULT_ARG.
(d_print_comp): Likewise.
From-SVN: r196065
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/common.opt | 3 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 5 | ||||
-rw-r--r-- | gcc/cp/pt.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg3.C | 18 |
5 files changed, 43 insertions, 4 deletions
diff --git a/gcc/common.opt b/gcc/common.opt index b6592e0..3c7b415 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -785,7 +785,8 @@ Driver Undocumented ; argument. ; First selectable in G++ 4.7. ; -; 7: The version of the ABI that treats nullptr_t as a builtin type. +; 7: The version of the ABI that treats nullptr_t as a builtin type and +; corrects the mangling of lambdas in default argument scope. ; First selectable in G++ 4.8. ; Additional positive integers will be assigned as new versions of ; the ABI become the default version of the ABI. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4784a3c..de03a7a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2013-02-14 Jason Merrill <jason@redhat.com> + PR c++/55223 + * pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Fix handling of + default argument scope. + * mangle.c (write_name): Likewise. + PR c++/55232 * error.c (find_typenames_r): Don't walk into a pack expansion. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index f6b3443..a48d4768 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -802,7 +802,10 @@ write_name (tree decl, const int ignore_local_scope) if (context == NULL || context == global_namespace || DECL_NAMESPACE_STD_P (context) - || (ignore_local_scope && TREE_CODE (context) == FUNCTION_DECL)) + || (ignore_local_scope + && (TREE_CODE (context) == FUNCTION_DECL + || (abi_version_at_least (7) + && TREE_CODE (context) == PARM_DECL)))) { tree template_info; /* Is this a template instance? */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index bd44fde..aa868a4 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14444,8 +14444,20 @@ tsubst_copy_and_build (tree t, 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); + scope = tsubst (scope, args, complain, in_decl); + else if (scope && TREE_CODE (scope) == PARM_DECL) + { + /* Look up the parameter we want directly, as tsubst_copy + doesn't do what we need. */ + tree fn = tsubst (DECL_CONTEXT (scope), args, complain, in_decl); + tree parm = FUNCTION_FIRST_USER_PARM (fn); + while (DECL_PARM_INDEX (parm) != DECL_PARM_INDEX (scope)) + parm = DECL_CHAIN (parm); + scope = parm; + /* FIXME Work around the parm not having DECL_CONTEXT set. */ + if (DECL_CONTEXT (scope) == NULL_TREE) + DECL_CONTEXT (scope) = fn; + } else scope = RECUR (scope); LAMBDA_EXPR_EXTRA_SCOPE (r) = scope; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg3.C new file mode 100644 index 0000000..f02fb29 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg3.C @@ -0,0 +1,18 @@ +// PR c++/55223 +// { dg-options "-std=c++11 -fabi-version=0" } +// { dg-final { scan-assembler "_ZN8functionC1IZN1CIiE4testES_Ed_UliE_EET_" } } + +struct function +{ + template <class U> function(U u) { } +}; + +template<typename T> struct C +{ + static T test(function f = [](int i){return i;}) { } +}; + +int main() +{ + C<int>::test(); +} |