aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-02-14 20:26:44 -0500
committerJason Merrill <jason@gcc.gnu.org>2013-02-14 20:26:44 -0500
commit622aac0b88ed111d033a950b0737317d8c85bbcb (patch)
tree76ab66221ec193a48645ec9dfa45c26964b7f963 /gcc
parentff9b4073cc6f8da73fd9affa494192e91c852e64 (diff)
downloadgcc-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.opt3
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/mangle.c5
-rw-r--r--gcc/cp/pt.c16
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg3.C18
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();
+}